00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_TOPO_ALGEBRAIC_FACE_HH
00028 # define MLN_TOPO_ALGEBRAIC_FACE_HH
00029
00033
00034 #include <mln/topo/face.hh>
00035 #include <mln/topo/algebraic_n_face.hh>
00036
00037
00038 namespace mln
00039 {
00040
00041 namespace topo
00042 {
00043
00044
00045 template <unsigned D> class complex;
00046 template <unsigned N, unsigned D> class n_face;
00047 template <unsigned N, unsigned D> class face_data;
00048
00049
00050
00051
00052
00053
00059 template <unsigned D>
00060 class algebraic_face : public face<D>
00061 {
00062 typedef face<D> super_;
00063
00064 public:
00065
00066 typedef complex<D> complex_type;
00067
00069 algebraic_face();
00071 algebraic_face(complex<D>& complex, unsigned n, unsigned face_id,
00072 bool sign);
00074 algebraic_face(const face<D>& f, bool sign);
00075
00077 template <unsigned N>
00078 algebraic_face(const algebraic_n_face<N, D>& f);
00079
00083 bool sign() const;
00085 void set_sign(bool sign);
00087
00088 private:
00090 bool sign_;
00091 };
00092
00093
00095 template <unsigned D>
00096 algebraic_face<D>
00097 make_algebraic_face(const face<D>& f, bool sign);
00098
00099
00102 template <unsigned D>
00103 algebraic_face<D>
00104 operator-(const face<D>& f);
00105
00106 template <unsigned D>
00107 algebraic_face<D>
00108 operator-(const algebraic_face<D>& f);
00110
00111
00114
00119 template <unsigned D>
00120 bool operator==(const algebraic_face<D>& lhs,
00121 const algebraic_face<D>& rhs);
00122
00127 template <unsigned D>
00128 bool operator!=(const algebraic_face<D>& lhs,
00129 const algebraic_face<D>& rhs);
00130
00139 template <unsigned D>
00140 bool operator< (const algebraic_face<D>& lhs,
00141 const algebraic_face<D>& rhs);
00142
00144
00145
00147 template <unsigned D>
00148 std::ostream&
00149 operator<<(std::ostream& ostr, const algebraic_face<D>& f);
00150
00151
00152
00153 # ifndef MLN_INCLUDE_ONLY
00154
00155 template <unsigned D>
00156 inline
00157 algebraic_face<D>::algebraic_face()
00158 : super_(), sign_(true)
00159 {
00160 }
00161
00162 template <unsigned D>
00163 inline
00164 algebraic_face<D>::algebraic_face(complex<D>& c, unsigned n,
00165 unsigned face_id, bool sign)
00166 : super_(c, n, face_id), sign_(sign)
00167 {
00168
00169 mln_precondition(n <= D);
00170 }
00171
00172 template <unsigned D>
00173 inline
00174 algebraic_face<D>::algebraic_face(const face<D>& f, bool sign)
00175 : super_(f), sign_(sign)
00176 {
00177
00178 mln_precondition(f.n() <= D);
00179 }
00180
00181 template <unsigned D>
00182 template <unsigned N>
00183 inline
00184 algebraic_face<D>::algebraic_face(const algebraic_n_face<N, D>& f)
00185 : super_(f), sign_(f.sign())
00186 {
00187
00188 metal::bool_< N <= D >::check();
00189 }
00190
00191
00192 template <unsigned D>
00193 inline
00194 bool
00195 algebraic_face<D>::sign() const
00196 {
00197 return sign_;
00198 }
00199
00200 template <unsigned D>
00201 inline
00202 void
00203 algebraic_face<D>::set_sign(bool sign)
00204 {
00205 sign_ = sign;
00206 }
00207
00208
00209 template <unsigned D>
00210 algebraic_face<D>
00211 make_algebraic_face(const face<D>& f, bool sign)
00212 {
00213 return algebraic_face<D>(f, sign);
00214 }
00215
00216
00217 template <unsigned D>
00218 algebraic_face<D>
00219 operator-(const face<D>& f)
00220 {
00221 return algebraic_face<D>(f, false);
00222 }
00223
00224 template <unsigned D>
00225 algebraic_face<D>
00226 operator-(const algebraic_face<D>& f)
00227 {
00228 algebraic_face<D> f2(f);
00229 f2.set_sign(!f.sign());
00230 return f2;
00231 }
00232
00233
00234 template <unsigned D>
00235 inline
00236 bool
00237 operator==(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00238 {
00239
00240 mln_precondition(lhs.cplx() == rhs.cplx());
00241 return
00242 lhs.n() == rhs.n() &&
00243 lhs.face_id() == rhs.face_id() &&
00244 lhs.sign() == rhs.sign();
00245 }
00246
00247 template <unsigned D>
00248 inline
00249 bool
00250 operator!=(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00251 {
00252
00253 mln_precondition(lhs.cplx() == rhs.cplx());
00254 return !(lhs == rhs);
00255 }
00256
00257 template <unsigned D>
00258 inline
00259 bool
00260 operator< (const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00261 {
00262
00263 mln_precondition(lhs.cplx() == rhs.cplx());
00264
00265 mln_precondition(lhs.n() == rhs.n());
00266 return lhs.face_id() < rhs.face_id();
00267 }
00268
00269
00270 template <unsigned D>
00271 inline
00272 std::ostream&
00273 operator<<(std::ostream& ostr, const algebraic_face<D>& f)
00274 {
00275 return
00276 ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
00277 << ", id = " << f.face_id() << ", sign = " << f.sign()<< ')';
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 namespace internal
00291 {
00292
00293 template <unsigned N, unsigned D>
00294 std::vector< algebraic_face<D> >
00295 lower_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00296 {
00297 metal::bool_< (N <= D) >::check();
00298 metal::bool_< (N > 1) >::check();
00299
00300 if (face.n() == N)
00301 {
00302 face_data<N, D>& data = face.template data<N>();
00303 std::vector< algebraic_n_face<N - 1, D> > lower_dim_faces =
00304 data.lower_dim_faces_;
00305 std::vector< topo::algebraic_face<D> > result;
00306 for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator f =
00307 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00308 result.push_back(*f);
00309 return result;
00310 }
00311 else
00312 return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00313 }
00314
00315 template <unsigned D>
00316 std::vector< algebraic_face<D> >
00317 lower_dim_adj_faces_if_dim_matches_<1, D>::operator()(const face<D>& face)
00318 {
00321 mln_precondition(face.n() == 1);
00322 face_data<1, D>& data = face.template data<1>();
00323 std::vector< algebraic_n_face<0, D> > lower_dim_faces =
00324 data.lower_dim_faces_;
00325 std::vector< topo::algebraic_face<D> > result;
00326 for (typename std::vector< algebraic_n_face<0, D> >::const_iterator f =
00327 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00328 result.push_back(*f);
00329 return result;
00330 }
00331
00332 template <unsigned N, unsigned D>
00333 std::vector< algebraic_face<D> >
00334 higher_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00335 {
00336 metal::bool_< (N < D) >::check();
00337
00338 if (face.n() == N)
00339 {
00340 face_data<N, D>& data = face.template data<N>();
00341 std::vector< algebraic_n_face<N + 1, D> > higher_dim_faces =
00342 data.higher_dim_faces_;
00343 std::vector< topo::algebraic_face<D> > result;
00344 for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator f =
00345 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00346 result.push_back(*f);
00347 return result;
00348 }
00349 else
00350 return
00351 internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00352 }
00353
00354 template <unsigned D>
00355 std::vector< algebraic_face<D> >
00356 higher_dim_adj_faces_if_dim_matches_<0, D>::operator()(const face<D>& face)
00357 {
00360 mln_precondition(face.n() == 0);
00361 face_data<0, D>& data = face.template data<0>();
00362 std::vector< algebraic_n_face<1, D> > higher_dim_faces =
00363 data.higher_dim_faces_;
00364 std::vector< topo::algebraic_face<D> > result;
00365 for (typename std::vector< algebraic_n_face<1, D> >::const_iterator f =
00366 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00367 result.push_back(*f);
00368 return result;
00369 }
00370
00371 }
00372
00373
00374 # endif // ! MLN_INCLUDE_ONLY
00375
00376 }
00377
00378 }
00379
00380 #endif // ! MLN_TOPO_ALGEBRAIC_FACE_HH