
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add more services to complexes and faces. * mln/core/complex.hh (mln::complex<D>::nfaces<N>): New. Use it... (mln::complex<D>::add_face): ...here. * mln/core/face.hh (mln::face_handle<N, D>::c, mln::face_handle<N, D>::c_): Rename as... (mln::face_handle<N, D>::cplx, mln::face_handle<N, D>::cplx_): ...these. Adjust users. (operator==(const face_handle<N, D>&, const face_handle<N, D>&)) (operator< (const face_handle<N, D>&, const face_handle<N, D>&)): New. complex.hh | 18 ++++++++++++++- face.hh | 69 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 72 insertions(+), 15 deletions(-) Index: mln/core/complex.hh --- mln/core/complex.hh (revision 2119) +++ mln/core/complex.hh (working copy) @@ -36,6 +36,8 @@ /// /// FIXME: More. +# include <cstddef> + # include <iosfwd> # include <mln/metal/bool.hh> @@ -77,6 +79,10 @@ face_handle<N + 1, D> add_face(const faces_set<N, D>& adjacent_faces); /// \} + /// \brief Return the number of \p N-faces. + template <unsigned N> + std::size_t nfaces() const; + /// Pretty-printing. /// \{ /// Print the complex. @@ -234,7 +240,7 @@ /* FIXME: This is not thread-proof (these two lines should form an atomic section). */ internal::faces_set_mixin<0u, D>::faces_.push_back(face<0u, D>()); - unsigned id = internal::faces_set_mixin<0u, D>::faces_.size() - 1; + unsigned id = nfaces<0u>() - 1; return face_handle<0u, D>(*this, id); } @@ -250,7 +256,7 @@ /* FIXME: This is not thread-proof (these two lines should form an atomic section). */ internal::faces_set_mixin<N + 1, D>::faces_.push_back(f); - unsigned id = internal::faces_set_mixin<N + 1, D>::faces_.size() - 1; + unsigned id = nfaces<N + 1>() - 1; face_handle<N + 1, D> fh(*this, id); // Connect F and its ADJACENT_FACES. @@ -265,6 +271,14 @@ template <unsigned D> template <unsigned N> + std::size_t + complex<D>::nfaces() const + { + return internal::faces_set_mixin<N, D>::faces_.size(); + } + + template <unsigned D> + template <unsigned N> face<N, D>& complex<D>::face_(unsigned face_id) { Index: mln/core/face.hh --- mln/core/face.hh (revision 2119) +++ mln/core/face.hh (working copy) @@ -58,6 +58,8 @@ } + // FIXME: Rename `face' as `face_data' and `face_handle' as face. + /*-------. | Face. | `-------*/ @@ -66,7 +68,7 @@ template <unsigned N, unsigned D> class face; - // Specialization for the faces of highest dimension (D). + // Specialization for the faces of highest dimension (\p D). template <unsigned D> class face<D, D> : public internal::lower_dim_faces_mixin<D, D> { @@ -148,7 +150,8 @@ /// Accessors. /// \{ /// Return the complex the face belongs to. - complex<D>& c() const; + // FIXME: Rename to complex()? + complex<D>& cplx() const; /// Return the id of the face. unsigned face_id() const; @@ -160,16 +163,40 @@ /// \brief The complex the face belongs to. /// /// A const face_handle can be used to modify a complex. - mutable complex<D>* c_; + mutable complex<D>* cplx_; /// \brief The id of the face. unsigned face_id_; }; + + /// Create a handle for \p N-face of a \p D-complex. template <unsigned N, unsigned D> face_handle<N, D> make_face_handle(const complex<D>& c, unsigned face_id); + /// Comparison of two instances of mln::face_handle. + /// \{ + /// \brief Is \a lhs equal to \a rhs? + /// + /// \pre Arguments \a lhs and \a rhs must belong to the same + /// mln::complex. + template <unsigned N, unsigned D> + bool + operator==(const face_handle<N, D>& lhs, const face_handle<N, D>& rhs); + + /// \brief Is \a lhs ``less'' than \a rhs? + /// + /// This comparison is required by algorithms sorting face handles. + /// + /// \pre Arguments \a lhs and \a rhs must belong to the same + /// mln::complex. + template <unsigned N, unsigned D> + bool + operator< (const face_handle<N, D>& lhs, const face_handle<N, D>& rhs); + /// \} + + /*----------------------. | Set of face handles. | `----------------------*/ @@ -240,19 +267,19 @@ template <unsigned N, unsigned D> face_handle<N, D>::face_handle() - : c_(0), face_id_(UINT_MAX) + : cplx_(0), face_id_(UINT_MAX) { } template <unsigned N, unsigned D> face_handle<N, D>::face_handle(complex<D>& c, unsigned face_id) - : c_(&c), face_id_(face_id) + : cplx_(&c), face_id_(face_id) { } template <unsigned N, unsigned D> face_handle<N, D>::face_handle(const face_handle<N, D>& rhs) - : c_(rhs.c_), face_id_(rhs.face_id_) + : cplx_(rhs.cplx_), face_id_(rhs.face_id_) { } @@ -262,7 +289,7 @@ { if (&rhs != this) { - c_ = rhs.c_; + cplx_ = rhs.cplx_; face_id_ = rhs.face_id_; } return *this; @@ -272,15 +299,15 @@ bool face_handle<N, D>::is_valid() const { - return c_ != 0 && face_id_ != UINT_MAX; + return cplx_ != 0 && face_id_ < cplx_->template nfaces<N>(); } template <unsigned N, unsigned D> complex<D>& - face_handle<N, D>::c() const + face_handle<N, D>::cplx() const { - mln_assertion(c_); - return *c_; + mln_assertion(cplx_); + return *cplx_; } template <unsigned N, unsigned D> @@ -295,7 +322,7 @@ face_handle<N, D>::to_face() const { mln_assertion(is_valid()); - return c_->template face_<N>(face_id_); + return cplx_->template face_<N>(face_id_); } @@ -306,6 +333,22 @@ return face_handle<N, D>(&c, face_id); } + template <unsigned N, unsigned D> + bool + operator==(const face_handle<N, D>& lhs, const face_handle<N, D>& rhs) + { + mln_assertion(&lhs.face.cplx() == &rhs.face.cplx()); + return lhs.face().id() == rhs.face().id(); + } + + template <unsigned N, unsigned D> + bool + operator< (const face_handle<N, D>& lhs, const face_handle<N, D>& rhs) + { + mln_assertion(&lhs.face.cplx() == &rhs.face.cplx()); + return lhs.face().id() < rhs.face().id(); + } + /*---------------. | Set of faces. | @@ -317,7 +360,7 @@ { // Check consistency. if (!faces_.empty()) - mln_assertion(&faces_.front().c() == &f.c()); + mln_assertion(&faces_.front().cplx() == &f.cplx()); faces_.push_back (f); }