* 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(a)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(a)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