2416: Split mln/topo/face.hh.

* milena/mln/topo/face.hh (mln::topo::face_data<N, D>) (mln::topo::n_face<N, D>) (mln::topo::n_faces_set<N, D>): Move... * milena/mln/topo/face_data.hh, * milena/mln/topo/n_face.hh, * milena/mln/topo/n_faces_set.hh: ...here (new files). * milena/mln/topo/complex.hh, * milena/mln/topo/complex_faces_iter.hh, * milena/mln/topo/complex_iter.hh, * milena/mln/topo/faces_iter.hh: Adjust. * milena/tests/topo/complex.cc: Update documentation. --- milena/ChangeLog | 20 ++ milena/mln/topo/complex.hh | 16 +- milena/mln/topo/complex_faces_iter.hh | 1 + milena/mln/topo/complex_iter.hh | 1 + milena/mln/topo/face.hh | 442 +-------------------------------- milena/mln/topo/face_data.hh | 158 ++++++++++++ milena/mln/topo/faces_iter.hh | 1 + milena/mln/topo/n_face.hh | 285 +++++++++++++++++++++ milena/mln/topo/n_faces_set.hh | 138 ++++++++++ milena/tests/topo/complex.cc | 17 +- 10 files changed, 629 insertions(+), 450 deletions(-) create mode 100644 milena/mln/topo/face_data.hh create mode 100644 milena/mln/topo/n_face.hh create mode 100644 milena/mln/topo/n_faces_set.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 5a41910..9bd58d5 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,25 @@ 2008-09-26 Roland Levillain <roland@lrde.epita.fr> + Split mln/topo/face.hh. + + * milena/mln/topo/face.hh + (mln::topo::face_data<N, D>) + (mln::topo::n_face<N, D>) + (mln::topo::n_faces_set<N, D>): + Move... + * milena/mln/topo/face_data.hh, + * milena/mln/topo/n_face.hh, + * milena/mln/topo/n_faces_set.hh: + ...here (new files). + * milena/mln/topo/complex.hh, + * milena/mln/topo/complex_faces_iter.hh, + * milena/mln/topo/complex_iter.hh, + * milena/mln/topo/faces_iter.hh: + Adjust. + * milena/tests/topo/complex.cc: Update documentation. + +2008-09-26 Roland Levillain <roland@lrde.epita.fr> + Rename mln::topo::faces_set as mln::topo::n_faces_set. * mln/topo/face.hh (mln::topo::faces_set<N, D>): Rename as... diff --git a/milena/mln/topo/complex.hh b/milena/mln/topo/complex.hh index 3ed8923..bef3ca9 100644 --- a/milena/mln/topo/complex.hh +++ b/milena/mln/topo/complex.hh @@ -43,7 +43,10 @@ # include <mln/util/tracked_ptr.hh> +# include <mln/topo/face_data.hh> # include <mln/topo/face.hh> +# include <mln/topo/n_face.hh> +# include <mln/topo/n_faces_set.hh> # include <mln/topo/complex_iter.hh> # include <mln/topo/faces_iter.hh> @@ -56,7 +59,14 @@ namespace mln namespace topo { - // Forward declarations. + // Forward declarations (external). + template <unsigned N, unsigned D> class n_faces_set; + template <unsigned D> class complex_fwd_iter_; + template <unsigned D> class complex_bkd_iter_; + template <unsigned N, unsigned D> class faces_fwd_iter_; + template <unsigned N, unsigned D> class faces_bkd_iter_; + + // Forward declarations (internal). namespace internal { template <unsigned D> @@ -65,10 +75,6 @@ namespace mln template <unsigned N, unsigned D> struct faces_set_mixin; } - template <unsigned D> class complex_fwd_iter_; - template <unsigned D> class complex_bkd_iter_; - template <unsigned N, unsigned D> class faces_fwd_iter_; - template <unsigned N, unsigned D> class faces_bkd_iter_; /*----------. diff --git a/milena/mln/topo/complex_faces_iter.hh b/milena/mln/topo/complex_faces_iter.hh index 990d8d4..95d7901 100644 --- a/milena/mln/topo/complex_faces_iter.hh +++ b/milena/mln/topo/complex_faces_iter.hh @@ -33,6 +33,7 @@ /// of a complex. # include <mln/topo/internal/complex_iter_base.hh> +# include <mln/topo/face.hh> /* FIXME: Should we drop N from the signature of these iterators? I.e., have N be dynamic? Or better: provide other iterators where diff --git a/milena/mln/topo/complex_iter.hh b/milena/mln/topo/complex_iter.hh index a752892..32bbb1f 100644 --- a/milena/mln/topo/complex_iter.hh +++ b/milena/mln/topo/complex_iter.hh @@ -32,6 +32,7 @@ /// \brief Definition of forward and backward iterators on complexes. # include <mln/topo/internal/complex_iter_base.hh> +# include <mln/topo/face.hh> // FIXME: Factor a bit more? (Using complex_iter_base_.) diff --git a/milena/mln/topo/face.hh b/milena/mln/topo/face.hh index e15c66a..136271c 100644 --- a/milena/mln/topo/face.hh +++ b/milena/mln/topo/face.hh @@ -33,236 +33,19 @@ #include <limits> -#include <vector> - #include <mln/core/contract.hh> -/* FIXME: Suggestions: - - Split `face', `face_handle' and `any_face_handle' code into several - files. - - `face_data' is somehow an implementation detail: it should be - hidden, either by moving it to mln/topo/complex.cc or into its own - file in mln/topo/internal. - - And what about `n_faces_set'? Should we move it to its own file as - well? */ - namespace mln { namespace topo { - // Forward declarations (external). + // Forward declarations. template <unsigned D> class complex; - namespace internal - { - template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin; - template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin; - } - - // Forward declarations (internal). template <unsigned N, unsigned D> class n_face; - namespace internal - { - template <unsigned N, unsigned D> class lower_dim_faces_data_mixin; - template <unsigned N, unsigned D> class higher_dim_faces_data_mixin; - } - - - /*------------. - | Face data. | - `------------*/ - - /// Data (adjacent faces) associated to a \p N-face of a \p D-complex. template <unsigned N, unsigned D> class face_data; - - - // Specialization for the faces of highest dimension (\p D). - template <unsigned D> - class face_data<D, D> : public internal::lower_dim_faces_data_mixin<D, D> - { - }; - - // Specialization for the faces of intermediate dimension (greater - // than 0, lower than \p D). - template <unsigned N, unsigned D> - class face_data : public internal::lower_dim_faces_data_mixin<N, D>, - public internal::higher_dim_faces_data_mixin<N, D> - { - }; - - // Specialization for the faces of lowest dimension (0). - template <unsigned D> - class face_data<0u, D> : public internal::higher_dim_faces_data_mixin<0u, D> - { - }; - - // Specialization for the case of a 0-complex. - template <> - class face_data<0u, 0u> - { - }; - - - namespace internal - { - - /// Factored implementation of faces. - /// \{ - template <unsigned N, unsigned D> - class lower_dim_faces_data_mixin - { - public: - void connect_lower_dim_face (const n_face<N - 1, D>& f); - private: - friend class mln::topo::internal::lower_dim_faces_set_mixin<N, D>; - std::vector< n_face<N - 1, D> > lower_dim_faces_; - }; - - template <unsigned N, unsigned D> - class higher_dim_faces_data_mixin - { - public: - void connect_higher_dim_face(const n_face<N + 1, D>& f); - private: - friend class mln::topo::internal::higher_dim_faces_set_mixin<N, D>; - std::vector< n_face<N + 1, D> > higher_dim_faces_; - }; - /// \} - - } // end of namespace mln::topo::internal - - - - /*---------. - | n-Face. | - `---------*/ - - /// \brief \p N-face handle in a complex. - /// - /// Contrary to an mln::topo::face, the dimension of an - /// mln::topo::n_face is fixed. - template <unsigned N, unsigned D> - struct n_face - { - // The type of the complex this handle points to. - typedef complex<D> complex_type; - - /// Build a non-initialized face handle. - n_face(); - /// Build a face handle from \a complex and \a face_id. - n_face(complex<D>& complex, unsigned face_id); - - /// Copy and assignment. - /// \{ - n_face(const n_face<N, D>& rhs); - n_face<N, D>& operator=(const n_face<N, D>& rhs); - /// \} - - /// Is this handle valid? - bool is_valid() const; - /// Invalidate this handle. - void invalidate(); - - /// Accessors. - /// \{ - /// Return the complex the face belongs to. - complex<D>& cplx() const; - /// Return the id of the face. - // FIXME: Rename as `id'? - unsigned face_id() const; - - /// Set the complex the face belongs to. - void set_cplx(complex<D>& cplx); - /// Return the dimension of the face. - // FIXME: Rename as `dim'? - unsigned n() const; - /// Set the id of the face. - void set_face_id(unsigned face_id); - - /// Return the mln::topo::face_data pointed by this handle. - face_data<N, D>& face_data() const; - /// \} - - private: - /// \brief The complex the face belongs to. - /// - /// A const mln::topo::n_face can be used to modify a complex. - mutable complex<D>* cplx_; - /// \brief The id of the face. - // FIXME: Rename as `id_'? - unsigned face_id_; - }; - - - /// Create a handle for \p N-face of a \p D-complex. - template <unsigned N, unsigned D> - n_face<N, D> - make_n_face(const complex<D>& c, unsigned face_id); - - - /// Comparison of two instances of mln::topo::n_face. - /// \{ - /// \brief Is \a lhs equal to \a rhs? - /// - /// \pre Arguments \a lhs and \a rhs must belong to the same - /// mln::topo::complex. - template <unsigned N, unsigned D> - bool - operator==(const n_face<N, D>& lhs, const n_face<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::topo::complex. - template <unsigned N, unsigned D> - bool - operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs); - /// \} - - - /*----------------------. - | Set of face handles. | - `----------------------*/ - - /// \brief Set of face handles of dimension \p N. - template <unsigned N, unsigned D> - class n_faces_set - { - public: - void add(const n_face<N, D>& f); - - /// \brief Accessors. - /// - /// Return the set of handles. - /// \{ - const std::vector< n_face<N, D> >& faces() const; - /// \} - - private: - friend class complex<D>; - - // FIXME: Rename this as `handles_'? - std::vector< n_face<N, D> > faces_; - }; - - - /// Construction helpers for mln::topo::n_faces_set. - /// \{ - template <unsigned N, unsigned D> - n_faces_set<N, D> - operator+(const n_face<N, D>& f1, const n_face<N, D>& f2); - - template <unsigned N, unsigned D> - n_faces_set<N, D> - operator+(const n_faces_set<N, D>& fs, const n_face<N, D>& f); - /// \} - + /*-------. | Face. | @@ -287,6 +70,7 @@ namespace mln template <unsigned N> face(const n_face<N, D>& f); + // FIXME: Probably useless. /// Copy and assignment. /// \{ face(const face<D>& rhs); @@ -361,222 +145,6 @@ namespace mln # ifndef MLN_INCLUDE_ONLY - /*--------. - | Faces. | - `--------*/ - - namespace internal - { - template <unsigned N, unsigned D> - inline - void - lower_dim_faces_data_mixin<N, D>::connect_lower_dim_face(const n_face<N - 1, D>& f) - { - lower_dim_faces_.push_back(f); - } - - template <unsigned N, unsigned D> - inline - void - higher_dim_faces_data_mixin<N, D>::connect_higher_dim_face(const n_face<N + 1, D>& f) - { - higher_dim_faces_.push_back(f); - } - - } // end of namespace mln::topo::internal - - - /*--------------. - | Face handle. | - `--------------*/ - - template <unsigned N, unsigned D> - inline - n_face<N, D>::n_face() - : cplx_(0), face_id_(std::numeric_limits<unsigned>::max()) - { - // Ensure N is compatible with D. - metal::bool_< N <= D >::check(); - } - - template <unsigned N, unsigned D> - inline - n_face<N, D>::n_face(complex<D>& c, unsigned face_id) - : cplx_(&c), face_id_(face_id) - { - // Ensure N is compatible with D. - metal::bool_< N <= D >::check(); - } - - template <unsigned N, unsigned D> - inline - n_face<N, D>::n_face(const n_face<N, D>& rhs) - : cplx_(rhs.cplx_), face_id_(rhs.face_id_) - { - // Ensure N is compatible with D. - metal::bool_< N <= D >::check(); - } - - template <unsigned N, unsigned D> - inline - n_face<N, D>& - n_face<N, D>::operator=(const n_face<N, D>& rhs) - { - if (&rhs != this) - { - cplx_ = rhs.cplx_; - face_id_ = rhs.face_id_; - } - return *this; - } - - template <unsigned N, unsigned D> - inline - bool - n_face<N, D>::is_valid() const - { - return cplx_ != 0 && face_id_ < cplx_->template nfaces<N>(); - } - - template <unsigned N, unsigned D> - inline - void - n_face<N, D>::invalidate() - { - set_face_id(std::numeric_limits<unsigned>::max()); - } - - template <unsigned N, unsigned D> - inline - complex<D>& - n_face<N, D>::cplx() const - { - mln_precondition(cplx_); - return *cplx_; - } - - template <unsigned N, unsigned D> - inline - unsigned - n_face<N, D>::n() const - { - return N; - } - - template <unsigned N, unsigned D> - inline - unsigned - n_face<N, D>::face_id() const - { - return face_id_; - } - - template <unsigned N, unsigned D> - inline - void - n_face<N, D>::set_cplx(complex<D>& cplx) - { - cplx_ = &cplx; - } - - template <unsigned N, unsigned D> - inline - void - n_face<N, D>::set_face_id(unsigned face_id) - { - face_id_ = face_id; - } - - template <unsigned N, unsigned D> - inline - face_data<N, D>& - n_face<N, D>::face_data() const - { - mln_precondition(is_valid()); - return cplx_->template face_data_<N>(face_id_); - } - - - template <unsigned N, unsigned D> - inline - n_face<N, D> - make_n_face(const complex<D>& c, unsigned face_id) - { - return n_face<N, D>(&c, face_id); - } - - - template <unsigned N, unsigned D> - inline - bool - operator==(const n_face<N, D>& lhs, const n_face<N, D>& rhs) - { - // Ensure LHS and RHS belong to the same complex. - mln_precondition(&lhs.face.cplx() == &rhs.face.cplx()); - return lhs.face().id() == rhs.face().id(); - } - - template <unsigned N, unsigned D> - inline - bool - operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs) - { - // Ensure LHS and RHS belong to the same complex. - mln_precondition(&lhs.face.cplx() == &rhs.face.cplx()); - return lhs.face().id() < rhs.face().id(); - } - - - /*---------------. - | Set of faces. | - `---------------*/ - - template <unsigned N, unsigned D> - inline - void - n_faces_set<N, D>::add(const n_face<N, D>& f) - { - // Check consistency. - if (!faces_.empty()) - mln_precondition(&faces_.front().cplx() == &f.cplx()); - faces_.push_back(f); - } - - template <unsigned N, unsigned D> - inline - const std::vector< n_face<N, D> >& - n_faces_set<N, D>::faces() const - { - return faces_; - } - - - template <unsigned N, unsigned D> - inline - n_faces_set<N, D> - operator+(const n_face<N, D>& f1, const n_face<N, D>& f2) - { - n_faces_set<N, D> fs; - fs.add(f1); - fs.add(f2); - return fs; - } - - template <unsigned N, unsigned D> - inline - n_faces_set<N, D> - operator+(const n_faces_set<N, D>& fs, const n_face<N, D>& f) - { - n_faces_set<N, D> fs2(fs); - fs2.add(f); - return fs2; - } - - - /*----------------------. - | ``Any-face'' handle. | - `----------------------*/ - template <unsigned D> inline face<D>::face() @@ -588,8 +156,7 @@ namespace mln template <unsigned D> inline - face<D>::face(complex<D>& c, unsigned n, - unsigned face_id) + face<D>::face(complex<D>& c, unsigned n, unsigned face_id) : cplx_(&c), n_(n), face_id_(face_id) { // Ensure N is compatible with D. @@ -718,7 +285,6 @@ namespace mln lhs.face().id() == rhs.face().id(); } - template <unsigned D> inline bool diff --git a/milena/mln/topo/face_data.hh b/milena/mln/topo/face_data.hh new file mode 100644 index 0000000..7c94ddd --- /dev/null +++ b/milena/mln/topo/face_data.hh @@ -0,0 +1,158 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_TOPO_FACE_DATA_HH +# define MLN_TOPO_FACE_DATA_HH + +/// \file mln/topo/face_data.hh +/// \brief Data associated to the faces of a complex. +/// +/// These data are actually lists of adjacent faces (of lower and +/// higher dimensions). + +# include <vector> + +# include <mln/topo/n_face.hh> + + +namespace mln +{ + + namespace topo + { + + // Forward declarations (external). + template <unsigned D> class complex; + namespace internal + { + template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin; + template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin; + } + + // Forward declarations (internal). + template <unsigned N, unsigned D> class n_face; + namespace internal + { + template <unsigned N, unsigned D> class lower_dim_faces_data_mixin; + template <unsigned N, unsigned D> class higher_dim_faces_data_mixin; + } + + + /*------------. + | Face data. | + `------------*/ + + /// Data (adjacent faces) associated to a \p N-face of a \p D-complex. + template <unsigned N, unsigned D> class face_data; + + + // Specialization for the faces of highest dimension (\p D). + template <unsigned D> + class face_data<D, D> : public internal::lower_dim_faces_data_mixin<D, D> + { + }; + + // Specialization for the faces of intermediate dimension (greater + // than 0, lower than \p D). + template <unsigned N, unsigned D> + class face_data : public internal::lower_dim_faces_data_mixin<N, D>, + public internal::higher_dim_faces_data_mixin<N, D> + { + }; + + // Specialization for the faces of lowest dimension (0). + template <unsigned D> + class face_data<0u, D> : public internal::higher_dim_faces_data_mixin<0u, D> + { + }; + + // Specialization for the case of a 0-complex. + template <> + class face_data<0u, 0u> + { + }; + + + namespace internal + { + + /// Factored implementation of faces. + /// \{ + template <unsigned N, unsigned D> + class lower_dim_faces_data_mixin + { + public: + void connect_lower_dim_face (const n_face<N - 1, D>& f); + private: + friend class mln::topo::internal::lower_dim_faces_set_mixin<N, D>; + std::vector< n_face<N - 1, D> > lower_dim_faces_; + }; + + template <unsigned N, unsigned D> + class higher_dim_faces_data_mixin + { + public: + void connect_higher_dim_face(const n_face<N + 1, D>& f); + private: + friend class mln::topo::internal::higher_dim_faces_set_mixin<N, D>; + std::vector< n_face<N + 1, D> > higher_dim_faces_; + }; + /// \} + + } // end of namespace mln::topo::internal + + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + template <unsigned N, unsigned D> + inline + void + lower_dim_faces_data_mixin<N, D>::connect_lower_dim_face(const n_face<N - 1, D>& f) + { + lower_dim_faces_.push_back(f); + } + + template <unsigned N, unsigned D> + inline + void + higher_dim_faces_data_mixin<N, D>::connect_higher_dim_face(const n_face<N + 1, D>& f) + { + higher_dim_faces_.push_back(f); + } + + } // end of namespace mln::topo::internal + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::topo + +} // end of namespace mln + +#endif // ! MLN_TOPO_FACE_DATA_HH diff --git a/milena/mln/topo/faces_iter.hh b/milena/mln/topo/faces_iter.hh index 1ad756b..509ed9c 100644 --- a/milena/mln/topo/faces_iter.hh +++ b/milena/mln/topo/faces_iter.hh @@ -33,6 +33,7 @@ /// of a complex. # include <mln/topo/internal/complex_iter_base.hh> +# include <mln/topo/n_face.hh> namespace mln { diff --git a/milena/mln/topo/n_face.hh b/milena/mln/topo/n_face.hh new file mode 100644 index 0000000..afeb4ab --- /dev/null +++ b/milena/mln/topo/n_face.hh @@ -0,0 +1,285 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_TOPO_N_FACE_HH +# define MLN_TOPO_N_FACE_HH + +/// \file mln/topo/n_face.hh +/// \brief n-face of a complex. + +#include <limits> + +#include <mln/core/contract.hh> + + +namespace mln +{ + + namespace topo + { + + // Forward declaration. + template <unsigned D> class complex; + template <unsigned N, unsigned D> class face_data; + + + /*---------. + | n-Face. | + `---------*/ + + /// \brief \p N-face handle in a complex. + /// + /// Contrary to an mln::topo::face, the dimension of an + /// mln::topo::n_face is fixed. + template <unsigned N, unsigned D> + struct n_face + { + // The type of the complex this handle points to. + typedef complex<D> complex_type; + + /// Build a non-initialized face handle. + n_face(); + /// Build a face handle from \a complex and \a face_id. + n_face(complex<D>& complex, unsigned face_id); + + // FIXME: Probably useless. + /// Copy and assignment. + /// \{ + n_face(const n_face<N, D>& rhs); + n_face<N, D>& operator=(const n_face<N, D>& rhs); + /// \} + + /// Is this handle valid? + bool is_valid() const; + /// Invalidate this handle. + void invalidate(); + + /// Accessors. + /// \{ + /// Return the complex the face belongs to. + complex<D>& cplx() const; + /// Return the id of the face. + // FIXME: Rename as `id'? + unsigned face_id() const; + + /// Set the complex the face belongs to. + void set_cplx(complex<D>& cplx); + /// Return the dimension of the face. + // FIXME: Rename as `dim'? + unsigned n() const; + /// Set the id of the face. + void set_face_id(unsigned face_id); + + /// Return the mln::topo::face_data pointed by this handle. + face_data<N, D>& face_data() const; + /// \} + + private: + /// \brief The complex the face belongs to. + /// + /// A const mln::topo::n_face can be used to modify a complex. + mutable complex<D>* cplx_; + /// \brief The id of the face. + // FIXME: Rename as `id_'? + unsigned face_id_; + }; + + + /// Create a handle for \p N-face of a \p D-complex. + template <unsigned N, unsigned D> + n_face<N, D> + make_n_face(const complex<D>& c, unsigned face_id); + + + /// Comparison of two instances of mln::topo::n_face. + /// \{ + /// \brief Is \a lhs equal to \a rhs? + /// + /// \pre Arguments \a lhs and \a rhs must belong to the same + /// mln::topo::complex. + template <unsigned N, unsigned D> + bool + operator==(const n_face<N, D>& lhs, const n_face<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::topo::complex. + template <unsigned N, unsigned D> + bool + operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs); + /// \} + + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned N, unsigned D> + inline + n_face<N, D>::n_face() + : cplx_(0), face_id_(std::numeric_limits<unsigned>::max()) + { + // Ensure N is compatible with D. + metal::bool_< N <= D >::check(); + } + + template <unsigned N, unsigned D> + inline + n_face<N, D>::n_face(complex<D>& c, unsigned face_id) + : cplx_(&c), face_id_(face_id) + { + // Ensure N is compatible with D. + metal::bool_< N <= D >::check(); + } + + template <unsigned N, unsigned D> + inline + n_face<N, D>::n_face(const n_face<N, D>& rhs) + : cplx_(rhs.cplx_), face_id_(rhs.face_id_) + { + // Ensure N is compatible with D. + metal::bool_< N <= D >::check(); + } + + template <unsigned N, unsigned D> + inline + n_face<N, D>& + n_face<N, D>::operator=(const n_face<N, D>& rhs) + { + if (&rhs != this) + { + cplx_ = rhs.cplx_; + face_id_ = rhs.face_id_; + } + return *this; + } + + template <unsigned N, unsigned D> + inline + bool + n_face<N, D>::is_valid() const + { + return cplx_ != 0 && face_id_ < cplx_->template nfaces<N>(); + } + + template <unsigned N, unsigned D> + inline + void + n_face<N, D>::invalidate() + { + set_face_id(std::numeric_limits<unsigned>::max()); + } + + template <unsigned N, unsigned D> + inline + complex<D>& + n_face<N, D>::cplx() const + { + mln_precondition(cplx_); + return *cplx_; + } + + template <unsigned N, unsigned D> + inline + unsigned + n_face<N, D>::n() const + { + return N; + } + + template <unsigned N, unsigned D> + inline + unsigned + n_face<N, D>::face_id() const + { + return face_id_; + } + + template <unsigned N, unsigned D> + inline + void + n_face<N, D>::set_cplx(complex<D>& cplx) + { + cplx_ = &cplx; + } + + template <unsigned N, unsigned D> + inline + void + n_face<N, D>::set_face_id(unsigned face_id) + { + face_id_ = face_id; + } + + template <unsigned N, unsigned D> + inline + face_data<N, D>& + n_face<N, D>::face_data() const + { + mln_precondition(is_valid()); + return cplx_->template face_data_<N>(face_id_); + } + + + template <unsigned N, unsigned D> + inline + n_face<N, D> + make_n_face(const complex<D>& c, unsigned face_id) + { + return n_face<N, D>(&c, face_id); + } + + + template <unsigned N, unsigned D> + inline + bool + operator==(const n_face<N, D>& lhs, const n_face<N, D>& rhs) + { + // Ensure LHS and RHS belong to the same complex. + mln_precondition(&lhs.face.cplx() == &rhs.face.cplx()); + return lhs.face().id() == rhs.face().id(); + } + + template <unsigned N, unsigned D> + inline + bool + operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs) + { + // Ensure LHS and RHS belong to the same complex. + mln_precondition(&lhs.face.cplx() == &rhs.face.cplx()); + return lhs.face().id() < rhs.face().id(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::topo + +} // end of namespace mln + +#endif // ! MLN_TOPO_N_FACE_HH diff --git a/milena/mln/topo/n_faces_set.hh b/milena/mln/topo/n_faces_set.hh new file mode 100644 index 0000000..65f56d9 --- /dev/null +++ b/milena/mln/topo/n_faces_set.hh @@ -0,0 +1,138 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_TOPO_N_FACES_SET_HH +# define MLN_TOPO_N_FACES_SET_HH + +/// \file mln/topo/n_face_set.hh +/// \brief Set of n-face of a complex. + +#include <vector> + +#include <mln/core/contract.hh> +#include <mln/topo/n_face.hh> + + +namespace mln +{ + + namespace topo + { + + // Forward declaration. + template <unsigned D> class complex; + + + /*------------------------. + | Set of n-face handles. | + `------------------------*/ + + /// \brief Set of face handles of dimension \p N. + template <unsigned N, unsigned D> + class n_faces_set + { + public: + void add(const n_face<N, D>& f); + + /// \brief Accessors. + /// + /// Return the set of handles. + /// \{ + const std::vector< n_face<N, D> >& faces() const; + /// \} + + private: + friend class complex<D>; + + // FIXME: Rename this as `handles_'? + std::vector< n_face<N, D> > faces_; + }; + + + /// Construction helpers for mln::topo::n_faces_set. + /// \{ + template <unsigned N, unsigned D> + n_faces_set<N, D> + operator+(const n_face<N, D>& f1, const n_face<N, D>& f2); + + template <unsigned N, unsigned D> + n_faces_set<N, D> + operator+(const n_faces_set<N, D>& fs, const n_face<N, D>& f); + /// \} + + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned N, unsigned D> + inline + void + n_faces_set<N, D>::add(const n_face<N, D>& f) + { + // Check consistency. + if (!faces_.empty()) + mln_precondition(&faces_.front().cplx() == &f.cplx()); + faces_.push_back(f); + } + + template <unsigned N, unsigned D> + inline + const std::vector< n_face<N, D> >& + n_faces_set<N, D>::faces() const + { + return faces_; + } + + + template <unsigned N, unsigned D> + inline + n_faces_set<N, D> + operator+(const n_face<N, D>& f1, const n_face<N, D>& f2) + { + n_faces_set<N, D> fs; + fs.add(f1); + fs.add(f2); + return fs; + } + + template <unsigned N, unsigned D> + inline + n_faces_set<N, D> + operator+(const n_faces_set<N, D>& fs, const n_face<N, D>& f) + { + n_faces_set<N, D> fs2(fs); + fs2.add(f); + return fs2; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::topo + +} // end of namespace mln + +#endif // ! MLN_TOPO_N_FACES_SET_HH diff --git a/milena/tests/topo/complex.cc b/milena/tests/topo/complex.cc index ebe734a..6b8c17e 100644 --- a/milena/tests/topo/complex.cc +++ b/milena/tests/topo/complex.cc @@ -189,15 +189,15 @@ int main() But first, we need to clarify (existing) names. ----------------------------------------------------------------- - Current/old name New name Definition + Current name New name Definition ----------------------------------------------------------------- complex<D> (n/a) General complex - - face<N, D> face_data<N, D> Face data - face_handle<N, D> n_face<N, D> (Static) n-face handle - faces_set<N, D> n_faces_set<N, D> Set of face handles - any_face_handle<D> face<D> Dynamic face handle - + + face_data<N, D> (n/a) Face data + n_face<N, D> (n/a) (Static) n-face handle + n_faces_set<N, D> (n/a) Set of face handles + face<D> (n/a) Dynamic face handle + complex_fwd_iter_<D>(c) face_fwd_iter<D>(c) | Iterators on all complex_bkd_iter_<D>(c) face_bkd_iter<D>(c) | faces of c @@ -209,6 +209,9 @@ int main() (Note: get rid of trailing underscores, even for entities in mln::internal::.) + And likewise for image-related entities! + + Next, write these: ----------------------------------------------------------------- -- 1.6.0.1
participants (1)
-
Roland Levillain