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