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 #ifndef MLN_TOPO_FACE_HH
00027 # define MLN_TOPO_FACE_HH
00028
00032
00033 # include <iostream>
00034 # include <vector>
00035
00036 # include <mln/value/internal/limits.hh>
00037 # include <mln/core/contract.hh>
00038 # include <mln/metal/bool.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044 namespace topo
00045 {
00046
00047
00048 template <unsigned D> class complex;
00049 template <unsigned N, unsigned D> class n_face;
00050 template <unsigned N, unsigned D> class face_data;
00051 template <unsigned N> class algebraic_face;
00052
00053
00054
00055
00056
00057
00062 template <unsigned D>
00063 struct face
00064 {
00065 public:
00066
00067 typedef complex<D> complex_type;
00068
00070 face();
00072 face(complex<D>& complex, unsigned n, unsigned face_id);
00073
00075 template <unsigned N>
00076 face(const n_face<N, D>& f);
00077
00079 bool is_valid() const;
00081 void invalidate();
00082
00086 complex<D> cplx() const;
00088
00089 unsigned n() const;
00091
00092 unsigned face_id() const;
00093
00095 void set_cplx(const complex<D>& cplx);
00096
00098 void set_n(unsigned n);
00100 void inc_n();
00102 void dec_n();
00103
00105 void set_face_id(unsigned face_id);
00107 void inc_face_id();
00109 void dec_face_id();
00110
00112 template <unsigned N>
00113 face_data<N, D>& data() const;
00114
00115
00117 std::vector< algebraic_face<D> > lower_dim_adj_faces() const;
00119 std::vector< algebraic_face<D> > higher_dim_adj_faces() const;
00121
00122 private:
00126 mutable complex<D> cplx_;
00128
00129 unsigned n_;
00131
00132 unsigned face_id_;
00133 };
00134
00135
00138
00143 template <unsigned D>
00144 bool operator==(const face<D>& lhs, const face<D>& rhs);
00145
00150 template <unsigned D>
00151 bool operator!=(const face<D>& lhs, const face<D>& rhs);
00152
00160 template <unsigned D>
00161 bool operator< (const face<D>& lhs, const face<D>& rhs);
00162
00164
00165
00167 template <unsigned D>
00168 std::ostream&
00169 operator<<(std::ostream& ostr, const face<D>& f);
00170
00171
00172
00173 # ifndef MLN_INCLUDE_ONLY
00174
00175 template <unsigned D>
00176 inline
00177 face<D>::face()
00178 : cplx_(),
00179 n_(value::internal::limits<unsigned>::max()),
00180 face_id_(value::internal::limits<unsigned>::max())
00181 {
00182 }
00183
00184 template <unsigned D>
00185 inline
00186 face<D>::face(complex<D>& c, unsigned n, unsigned face_id)
00187 : cplx_(c), n_(n), face_id_(face_id)
00188 {
00189
00190 mln_precondition(n <= D);
00191 }
00192
00193 template <unsigned D>
00194 template <unsigned N>
00195 inline
00196 face<D>::face(const n_face<N, D>& f)
00197 : cplx_(f.cplx()), n_(N), face_id_(f.face_id())
00198 {
00199
00200 metal::bool_< N <= D >::check();
00201 }
00202
00203 template <unsigned D>
00204 inline
00205 bool
00206 face<D>::is_valid() const
00207 {
00208 return n_ <= D && face_id_ < cplx_.nfaces_of_dim(n_);
00209 }
00210
00211 template <unsigned D>
00212 inline
00213 void
00214 face<D>::invalidate()
00215 {
00216 set_n(value::internal::limits<unsigned>::max());
00217 set_face_id(value::internal::limits<unsigned>::max());
00218 }
00219
00220 template <unsigned D>
00221 inline
00222 complex<D>
00223 face<D>::cplx() const
00224 {
00225 return cplx_;
00226 }
00227
00228 template <unsigned D>
00229 inline
00230 unsigned
00231 face<D>::n() const
00232 {
00233 return n_;
00234 }
00235
00236 template <unsigned D>
00237 inline
00238 unsigned
00239 face<D>::face_id() const
00240 {
00241 return face_id_;
00242 }
00243
00244 template <unsigned D>
00245 inline
00246 void
00247 face<D>::set_cplx(const complex<D>& cplx)
00248 {
00249 cplx_ = cplx;
00250 }
00251
00252 template <unsigned D>
00253 inline
00254 void
00255 face<D>::set_n(unsigned n)
00256 {
00257 n_ = n;
00258 }
00259
00260 template <unsigned D>
00261 inline
00262 void
00263 face<D>::inc_n()
00264 {
00265 ++n_;
00266 }
00267
00268 template <unsigned D>
00269 inline
00270 void
00271 face<D>::dec_n()
00272 {
00273 --n_;
00274 }
00275
00276 template <unsigned D>
00277 inline
00278 void
00279 face<D>::set_face_id(unsigned face_id)
00280 {
00281 face_id_ = face_id;
00282 }
00283
00284 template <unsigned D>
00285 inline
00286 void
00287 face<D>::inc_face_id()
00288 {
00289 ++face_id_;
00290 }
00291
00292 template <unsigned D>
00293 inline
00294 void
00295 face<D>::dec_face_id()
00296 {
00297 --face_id_;
00298 }
00299
00300 template <unsigned D>
00301 template <unsigned N>
00302 inline
00303 face_data<N, D>&
00304 face<D>::data() const
00305 {
00306 mln_precondition(n_ == N);
00307 mln_precondition(is_valid());
00308 return cplx_.template face_data_<N>(face_id_);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 namespace internal
00324 {
00325
00326 template <unsigned N, unsigned D>
00327 struct lower_dim_adj_faces_if_dim_matches_
00328 {
00329 std::vector< algebraic_face<D> > operator()(const face<D>& face);
00330 };
00331
00332 template <unsigned D>
00333 struct lower_dim_adj_faces_if_dim_matches_<1, D>
00334 {
00335 std::vector< algebraic_face<D> > operator()(const face<D>& face);
00336 };
00337
00338 template <unsigned N, unsigned D>
00339 struct higher_dim_adj_faces_if_dim_matches_
00340 {
00341 std::vector< algebraic_face<D> > operator()(const face<D>& face);
00342 };
00343
00344 template <unsigned D>
00345 struct higher_dim_adj_faces_if_dim_matches_<0, D>
00346 {
00347 std::vector< algebraic_face<D> > operator()(const face<D>& face);
00348 };
00349
00350 }
00351
00352
00353 template <unsigned D>
00354 inline
00355 std::vector< algebraic_face<D> >
00356 face<D>::lower_dim_adj_faces() const
00357 {
00358
00359 metal::bool_<( D != 0 )>::check();
00360
00361 return n_ > 0 ?
00362 internal::lower_dim_adj_faces_if_dim_matches_<D, D>()(*this) :
00363 std::vector< algebraic_face<D> >();
00364 }
00365
00366 template <unsigned D>
00367 inline
00368 std::vector< algebraic_face<D> >
00369 face<D>::higher_dim_adj_faces() const
00370 {
00371
00372 metal::bool_<( D != 0 )>::check();
00373
00374 return n_ < D ?
00375 internal::higher_dim_adj_faces_if_dim_matches_<D - 1, D>()(*this) :
00376 std::vector< algebraic_face<D> >();
00377 }
00378
00379
00380 template <unsigned D>
00381 inline
00382 bool
00383 operator==(const face<D>& lhs, const face<D>& rhs)
00384 {
00385
00386 mln_precondition(lhs.cplx() == rhs.cplx());
00387 return lhs.n() == rhs.n() && lhs.face_id() == rhs.face_id();
00388 }
00389
00390 template <unsigned D>
00391 inline
00392 bool
00393 operator!=(const face<D>& lhs, const face<D>& rhs)
00394 {
00395
00396 mln_precondition(lhs.cplx() == rhs.cplx());
00397 return !(lhs == rhs);
00398 }
00399
00400 template <unsigned D>
00401 inline
00402 bool
00403 operator< (const face<D>& lhs, const face<D>& rhs)
00404 {
00405
00406 mln_precondition(lhs.cplx() == rhs.cplx());
00407 return lhs.n() < rhs.n() ||
00408 (lhs.n() == rhs.n() && lhs.face_id() < rhs.face_id());
00409 }
00410
00411
00412 template <unsigned D>
00413 inline
00414 std::ostream&
00415 operator<<(std::ostream& ostr, const face<D>& f)
00416 {
00417 return ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
00418 << ", id = " << f.face_id() << ')';
00419 }
00420
00421 # endif // ! MLN_INCLUDE_ONLY
00422
00423 }
00424
00425 }
00426
00427 #endif // ! MLN_TOPO_FACE_HH