* mln/topo/: New directory.
* tests/topo/: New directory.
* mln/core/complex.hh,
* mln/core/complex_faces_iter.hh,
* mln/core/face.hh,
* mln/core/faces_iter.hh,
* mln/core/internal/complex_iter_base.hh,
* tests/core/other/complex.cc:
Move...
* mln/topo/complex.hh,
* mln/topo/complex_faces_iter.hh,
* mln/topo/face.hh,
* mln/topo/faces_iter.hh,
* mln/topo/internal/complex_iter_base.hh,
* tests/topo/complex.cc:
...here.
Adjust.
* tests/core/other/Makefile.am
(check_PROGRAM): Remove complex.
(complex_SOURCES): Remove.
* tests/topo/Makefile.am: New.
(check_PROGRAM): Add complex.
(complex_SOURCES, TESTS): New.
* tests/Makefile.am (SUBDIRS): Add topo.
---
milena/ChangeLog | 29 +
milena/mln/core/complex.hh | 853 ------------------------
milena/mln/core/complex_faces_iter.hh | 262 --------
milena/mln/core/complex_iter.hh | 270 --------
milena/mln/core/face.hh | 729 ---------------------
milena/mln/core/faces_iter.hh | 247 -------
milena/mln/core/internal/complex_iter_base.hh | 202 ------
milena/mln/topo/complex.hh | 857 +++++++++++++++++++++++++
milena/mln/topo/complex_faces_iter.hh | 266 ++++++++
milena/mln/topo/complex_iter.hh | 275 ++++++++
milena/mln/topo/face.hh | 733 +++++++++++++++++++++
milena/mln/topo/faces_iter.hh | 251 ++++++++
milena/mln/topo/internal/complex_iter_base.hh | 208 ++++++
milena/tests/Makefile.am | 1 +
milena/tests/core/other/Makefile.am | 2 -
milena/tests/topo/Makefile.am | 10 +
milena/tests/{core/other => topo}/complex.cc | 54 +-
17 files changed, 2657 insertions(+), 2592 deletions(-)
delete mode 100644 milena/mln/core/complex.hh
delete mode 100644 milena/mln/core/complex_faces_iter.hh
delete mode 100644 milena/mln/core/complex_iter.hh
delete mode 100644 milena/mln/core/face.hh
delete mode 100644 milena/mln/core/faces_iter.hh
delete mode 100644 milena/mln/core/internal/complex_iter_base.hh
create mode 100644 milena/mln/topo/complex.hh
create mode 100644 milena/mln/topo/complex_faces_iter.hh
create mode 100644 milena/mln/topo/complex_iter.hh
create mode 100644 milena/mln/topo/face.hh
create mode 100644 milena/mln/topo/faces_iter.hh
create mode 100644 milena/mln/topo/internal/complex_iter_base.hh
create mode 100644 milena/tests/topo/Makefile.am
rename milena/tests/{core/other => topo}/complex.cc (79%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index aa7dc82..0963983 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,32 @@
+2008-09-24 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Move complex-related entities to mln/topo/.
+
+ * mln/topo/: New directory.
+ * tests/topo/: New directory.
+ * mln/core/complex.hh,
+ * mln/core/complex_faces_iter.hh,
+ * mln/core/face.hh,
+ * mln/core/faces_iter.hh,
+ * mln/core/internal/complex_iter_base.hh,
+ * tests/core/other/complex.cc:
+ Move...
+ * mln/topo/complex.hh,
+ * mln/topo/complex_faces_iter.hh,
+ * mln/topo/face.hh,
+ * mln/topo/faces_iter.hh,
+ * mln/topo/internal/complex_iter_base.hh,
+ * tests/topo/complex.cc:
+ ...here.
+ Adjust.
+ * tests/core/other/Makefile.am
+ (check_PROGRAM): Remove complex.
+ (complex_SOURCES): Remove.
+ * tests/topo/Makefile.am: New.
+ (check_PROGRAM): Add complex.
+ (complex_SOURCES, TESTS): New.
+ * tests/Makefile.am (SUBDIRS): Add topo.
+
2008-09-24 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make w_window tests pass with from_to instead of to_w_window.
diff --git a/milena/mln/core/complex.hh b/milena/mln/core/complex.hh
deleted file mode 100644
index 2329a71..0000000
--- a/milena/mln/core/complex.hh
+++ /dev/null
@@ -1,853 +0,0 @@
-// 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_CORE_COMPLEX_HH
-# define MLN_CORE_COMPLEX_HH
-
-/// \file mln/core/complex.hh
-/// \brief Structures for general complexes.
-///
-/// A complex defines a topological space which can be used as a
-/// support for an image (i.e., as site sets).
-
-# include <cstddef>
-
-# include <limits>
-# include <iosfwd>
-
-# include <mln/metal/bool.hh>
-
-# include <mln/util/tracked_ptr.hh>
-
-# include <mln/core/face.hh>
-
-# include <mln/core/complex_iter.hh>
-# include <mln/core/faces_iter.hh>
-# include <mln/core/complex_faces_iter.hh>
-
-
-namespace mln
-{
-
- // Forward declarations.
- namespace internal
- {
- template <unsigned D>
- struct complex_data;
-
- 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_;
-
-
- /*----------.
- | Complex. |
- `----------*/
-
- /// \brief General complex of dimension \p D.
- template <unsigned D>
- class complex
- {
- public:
- /// Forward mln::Iterator type iterating on all faces.
- typedef complex_fwd_iter_<D> fwd_citer;
- /// Backward mln::Iterator type iterating on all faces.
- typedef complex_bkd_iter_<D> bkd_citer;
-
- /// Forward mln::Iterator type iterating on \p N-faces.
- template <unsigned N>
- struct fwd_fiter { typedef faces_fwd_iter_<N, D> ret; };
- /// Backward mln::Iterator type iterating on \p N-faces.
- template <unsigned N>
- struct bkd_fiter { typedef faces_bkd_iter_<N, D> ret; };
-
- /// Complex construction.
- /// \{
- /// Create a new \p D-complex.
- complex();
-
- /// \brief Add a 0-face to the complex.
- face_handle<0u, D> add_face();
-
- /// \brief Add a \p (N+1)-face to the complex (with \p N >= 0).
- ///
- /// \param adjacent_faces The (\p N-1)-faces adjacent to the new
- /// \p N-face.
- template <unsigned N>
- face_handle<N + 1, D> add_face(const faces_set<N, D>&
adjacent_faces);
- /// \}
-
- /// \brief Static manipulators.
- ///
- /// These methods use statically-known input.
- /// \{
- /// \brief Return the total number of faces, whatever their
- /// dimension.
- std::size_t nfaces() const;
-
- /// \brief Return the number of \p N-faces.
- template <unsigned N>
- std::size_t nfaces() const;
- /// \}
-
- /// \brief Dynamic manipulators.
- ///
- /// These methods use input know as run time.
- /// \{
- /// \brief Return the number of \a n-faces.
- ///
- /// Warning, this function has a complexity linear in term of N,
- /// since each faces_set is checked (the present implementation
- /// does not provide a direct access to faces_set through a
- /// dynamic value of the dimension).
- std::size_t nfaces(unsigned n) const;
- /// \}
-
- /// Pretty-printing.
- /// \{
- /// Print the complex.
- void print(std::ostream& ostr) const;
- /// Print the faces of dimension \p N.
- template <unsigned N>
- void print_faces(std::ostream& ostr) const;
- /// \}
-
- private:
- /// The actual data of the complex.
- util::tracked_ptr< internal::complex_data<D> > data_;
-
- template <unsigned D_>
- friend bool operator==(const complex<D_>& lhs, const complex<D_>&
rhs);
-
- /// Accessors.
- /// \{
- template <unsigned N, unsigned D_> friend class face_handle;
- template <unsigned D_> friend class any_face_handle;
-
- template <unsigned N>
- face<N, D>& face_(unsigned face_id);
-
- template <unsigned N>
- const face<N, D>& face_(unsigned face_id) const;
- /// \}
-
- /// Functional meta-manipulators.
- /// \{
- /* FIXME: Use something more constraining than the STL's
- UnaryFunction/BinaryFunction. Use Function or Function_v2v?
- Or a new subclass of Function? */
-
- /* FIXME: Replace F and ACCU by a Milena accumulator? */
-
- /** \brief Apply a kind of static fold left operator to the
- implicit list of faces_set using a functor \a f and a value \a
- accu.
-
- Argument \a is called an "accumulator", but with a slightly
- different meaning than mln:accu members.
-
- We might want to use TypeLists or something similar, is they
- provide an explicit static fold left operator. */
- template <typename BinaryFunction, typename T>
- T fold_left_(const BinaryFunction& f, const T& accu) const;
-
- /// \brief Apply a functor \a f to this list of \a n-faces.
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
- /// \}
-
- /// \brief connect two faces.
- ///
- /// \param f1 A face of dimension \p N
- /// \param f2 A face of dimension \p N + 1
- ///
- /// \pre \p N must be lower or equal to \p D.
- template <unsigned N>
- void connect_(const face_handle<N, D>& f1,
- const face_handle<N + 1, D>& f2);
- };
-
-
- /// Compare two complexes for equality.
- template <unsigned D>
- bool
- operator==(const complex<D>& lhs, const complex<D>& rhs);
-
-
- /// Pretty print a complex.
- template <unsigned D>
- std::ostream&
- operator<<(std::ostream& ostr, const complex<D>& c);
-
-
- /*---------------.
- | Complex data. |
- `---------------*/
-
- namespace internal
- {
- // Forward declarations.
- template <unsigned N, unsigned D>
- struct faces_set_mixin;
-
- /// \brief Complex data.
- template <unsigned D>
- struct complex_data : faces_set_mixin<D, D>
- {
- // Data is contained in super classes.
- };
-
- } // end of namespace mln::internal::complex
-
-
- /*---------------------.
- | Faces of a complex. |
- `---------------------*/
-
- /// The sets of n-faces of a complex are recursively aggregated as
- /// mixins.
- namespace internal
- {
-
- // Forward declarations.
- template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin;
- template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin;
-
- // -------------------------------- //
- // mln::internal::faces_set_mixin. //
- // -------------------------------- //
-
- /// \brief Recursive mixins of set of faces.
- /// \{
- template <unsigned N, unsigned D> struct faces_set_mixin;
-
- /// Faces of highest dimension (\p D).
- template <unsigned D>
- struct faces_set_mixin<D, D> : public faces_set_mixin<D - 1, D>,
- public lower_dim_faces_set_mixin<D, D>
- {
- std::vector< face<D, D> > faces_;
-
- /// Pretty-printing.
- /// \{
- /// Print the faces of dimension \p D.
- void print(std::ostream& ostr) const;
- void print_rec_asc(std::ostream& ostr) const;
- /// \}
-
- /// Functional meta-manipulators.
- /// \{
- /// \brief Fold left.
- /// \see mln::complex<D>::fold_left_.
- template <typename BinaryFunction, typename T>
- T fold_left_(const BinaryFunction& f, const T& accu) const;
- /// \brief Apply a functor \a f to the list of faces if \a n == \p D.
- /// \see mln::complex<D>::apply_if_dim_matches_.
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
- /// \}
- };
-
- /// Faces of intermediate dimension (greater than 0, lower than \p D).
- template <unsigned N, unsigned D>
- struct faces_set_mixin : public faces_set_mixin<N - 1, D>,
- public lower_dim_faces_set_mixin<N, D>,
- public higher_dim_faces_set_mixin<N, D>
- {
- std::vector< face<N, D> > faces_;
-
- /// Pretty-printing.
- /// \{
- /// Print the faces of dimension \p N.
- void print(std::ostream& ostr) const;
- /// Recursively print the faces of dimensions 0 to \p N
- /// (in ascending dimension).
- void print_rec_asc(std::ostream& ostr) const;
- /// \}
-
- /// Functional meta-manipulators.
- /// \{
- /// \brief Fold left.
- /// \see mln::complex<D>::fold_left_.
- template <typename BinaryFunction, typename T>
- T fold_left_(const BinaryFunction& f, const T& accu) const;
- /// \brief Apply a functor \a f to the list of faces if \a n == \p N.
- /// \see mln::complex<D>::apply_if_dim_matches_.
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
- /// \}
- };
-
- /// Faces of lowest dimension (0).
- template <unsigned D>
- struct faces_set_mixin<0u, D> : public higher_dim_faces_set_mixin<0u, D>
- {
- std::vector< face<0u, D> > faces_;
-
- /// Pretty-printing.
- /// \{
- /// Print the faces of dimension 0.
- void print(std::ostream& ostr) const;
- void print_rec_asc(std::ostream& ostr) const;
- /// \}
-
- /// Functional meta-manipulators.
- /// \{
- /// \brief Fold left.
- /// \see mln::complex<D>::fold_left_.
- template <typename BinaryFunction, typename T>
- T fold_left_(const BinaryFunction& f, const T& accu) const;
- /// \brief Apply a functor \a f to the list of faces if \a n == 0.
- /// \see mln::complex<D>::apply_if_dim_matches_.
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
- /// \}
- };
-
- /// Faces of a 0-complex.
- template <>
- struct faces_set_mixin<0u, 0u>
- {
- std::vector< face<0u, 0u> > faces_;
-
- /// Pretty-printing.
- /// \{
- /// Print the faces of dimension \p D.
- void print(std::ostream& ostr) const;
- void print_rec_asc(std::ostream& ostr) const;
- /// \}
-
- /// Functional meta-manipulators.
- /// \{
- /// \brief Fold left.
- /// \see mln::complex<D>::fold_left_.
- template <typename BinaryFunction, typename T>
- T fold_left_(const BinaryFunction& f, const T& accu) const;
- /// \brief Apply a functor \a f to the list of faces if \a n == 0.
- /// \see mln::complex<D>::apply_if_dim_matches_.
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
- /// \}
- };
- /// \}
-
-
- // ------------------------------------------- //
- // mln::internal::lower_dim_faces_set_mixin. //
- // mln::internal::higher_dim_faces_set_mixin. //
- // ------------------------------------------- //
-
- /// Mixins of mixin mln::faces_set_mixin.
- /// \{
- template <unsigned N, unsigned D>
- struct lower_dim_faces_set_mixin
- {
- void print(std::ostream& ostr, const face<N, D>& f) const;
- };
-
- template <unsigned N, unsigned D>
- struct higher_dim_faces_set_mixin
- {
- void print(std::ostream& ostr, const face<N, D>& f) const;
- };
- /// \}
-
- } // end of namespace mln::internal
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- /*-----------------------.
- | Complex construction. |
- `-----------------------*/
-
- template <unsigned D>
- complex<D>::complex()
- // Allocate data for this complex.
- : data_(new internal::complex_data<D>())
- {
- }
-
- template <unsigned D>
- face_handle<0u, D>
- complex<D>::add_face()
- {
- /* FIXME: This is not thread-proof (these two lines should
- form an atomic section). */
- data_->internal::faces_set_mixin<0u, D>::faces_.push_back(face<0u,
D>());
- unsigned id = nfaces<0u>() - 1;
-
- return face_handle<0u, D>(*this, id);
- }
-
- template <unsigned D>
- template <unsigned N>
- face_handle<N + 1, D>
- complex<D>::add_face(const faces_set<N, D>& adjacent_faces)
- {
- typedef typename std::vector< face_handle<N, D> >::const_iterator
iter_t;
-
- // Ensure ADJACENT_FACES are already part of the complex.
- if (!HAS_NDEBUG)
- for (iter_t a = adjacent_faces.faces().begin();
- a != adjacent_faces.faces().end(); ++a)
- {
- mln_precondition(&a->cplx() == this);
- mln_precondition(a->is_valid());
- }
-
- face<N + 1, D> f;
- /* FIXME: This is not thread-proof (these two lines should
- form an atomic section). */
- data_->internal::faces_set_mixin<N + 1, D>::faces_.push_back(f);
- unsigned id = nfaces<N + 1>() - 1;
-
- face_handle<N + 1, D> fh(*this, id);
- // Connect F and its ADJACENT_FACES.
- for (iter_t a = adjacent_faces.faces().begin();
- a != adjacent_faces.faces().end(); ++a)
- connect_(*a, fh);
- return fh;
- }
-
-
- /*-------.
- | Misc. |
- `-------*/
-
- namespace internal
- {
-
- /// A binary meta-functor defined by:
- ///
- /// \code
- /// add_size : x, c -> x + c.size()
- /// \endcode
- ///
- /// \see mln::complex<D>::nfaces (static version).
- /// \see mln::complex<D>::fold_left_.
- struct add_size
- {
- template <typename T, typename Container>
- T operator()(const T& x, const Container& c) const
- {
- return x + c.size();
- }
- };
-
- /// An unary meta-functor defined by:
- ///
- /// \code
- /// add_size : c -> c.size()
- /// \endcode
- ///
- /// \see mln::complex<D>::nfaces (dynamic version).
- /// \see mln::complex<D>::apply_if_dim_matches_.
- struct get_size
- {
- typedef std::size_t result_type;
-
- template <typename Container>
- typename Container::size_type operator()(const Container& c) const
- {
- return c.size();
- }
- };
-
- } // end of namespace mln::internal
-
-
- /*----------------------.
- | Static manipulators. |
- `----------------------*/
-
- template <unsigned D>
- std::size_t
- complex<D>::nfaces() const
- {
- return fold_left_(internal::add_size(), 0);
- }
-
- template <unsigned D>
- template <unsigned N>
- std::size_t
- complex<D>::nfaces() const
- {
- return data_->internal::faces_set_mixin<N, D>::faces_.size();
- }
-
-
- /*-----------------------.
- | Dynamic manipulators. |
- `-----------------------*/
-
- template <unsigned D>
- std::size_t
- complex<D>::nfaces(unsigned n) const
- {
- // Ensure N is compatible with D.
- mln_precondition(n <= D);
- return apply_if_dim_matches_(n, internal::get_size());
- }
-
-
- /*-------------------.
- | Internal methods. |
- `-------------------*/
-
- template <unsigned D>
- template <unsigned N>
- face<N, D>&
- complex<D>::face_(unsigned face_id)
- {
- return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
- }
-
- template <unsigned D>
- template <unsigned N>
- const face<N, D>&
- complex<D>::face_(unsigned face_id) const
- {
- return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
- }
-
- template <unsigned D>
- template <unsigned N>
- void
- complex<D>::connect_(const face_handle<N, D>& f1,
- const face_handle<N + 1, D>& f2)
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
-
- f1.to_face().connect_higher_dim_face(f2);
- f2.to_face().connect_lower_dim_face(f1);
- }
-
-
- /*-------------.
- | Comparison. |
- `-------------*/
-
- template <unsigned D>
- bool
- operator==(const complex<D>& lhs, const complex<D>& rhs)
- {
- return lhs.data_.ptr_ == rhs.data_.ptr_;
- }
-
-
- /*------------------.
- | Pretty-printing. |
- `------------------*/
-
- template <unsigned D>
- std::ostream&
- operator<<(std::ostream& ostr, const complex<D>& c)
- {
- c.print(ostr);
- return ostr;
- }
-
- template <unsigned D>
- void
- complex<D>::print(std::ostream& ostr) const
- {
- data_->internal::faces_set_mixin<D, D>::print_rec_asc(ostr);
- }
-
- template <unsigned D>
- template <unsigned N>
- void
- complex<D>::print_faces(std::ostream& ostr) const
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
-
- data_->internal::faces_set_mixin<N, D>::print(ostr);
- }
-
-
- namespace internal
- {
-
- template <unsigned N, unsigned D>
- void
- faces_set_mixin<N, D>::print_rec_asc(std::ostream& ostr) const
- {
- faces_set_mixin<N - 1, D>::print_rec_asc(ostr);
- print(ostr);
- }
-
- template <unsigned D>
- void
- faces_set_mixin<0u, D>::print_rec_asc(std::ostream& ostr) const
- {
- print(ostr);
- }
-
- template <unsigned D>
- void
- faces_set_mixin<D, D>::print_rec_asc(std::ostream& ostr) const
- {
- faces_set_mixin<D - 1, D>::print_rec_asc(ostr);
- print(ostr);
- }
-
- void
- faces_set_mixin<0u, 0u>::print_rec_asc(std::ostream& ostr) const
- {
- print(ostr);
- }
-
-
- template <unsigned N, unsigned D>
- void
- faces_set_mixin<N, D>::print(std::ostream& ostr) const
- {
- ostr << "Faces of dimension " << N
- << " and their ajacent faces of dimension "
- << N - 1 << " and "
- << N + 1 << std::endl;
- for (unsigned f = 0; f < faces_.size(); ++f)
- {
- ostr << " " << f << ": dim " << N - 1
<< ": { ";
- lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
- ostr << "}, dim " << N + 1 << ": { ";
- higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
- ostr << "}" << std::endl;
- }
- }
-
- template <unsigned D>
- void
- faces_set_mixin<0u, D>::print(std::ostream& ostr) const
- {
- const unsigned N = 0u;
- ostr << "Faces of dimension " << N
- << " and their ajacent faces of dimension "
- << N + 1 << std::endl;
- for (unsigned f = 0; f < faces_.size(); ++f)
- {
- ostr << " " << f << ": dim " << N + 1
<< ": { ";
- higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
- ostr << "}" << std::endl;
- }
- }
-
- template <unsigned D>
- void
- faces_set_mixin<D, D>::print(std::ostream& ostr) const
- {
- const unsigned N = D;
- ostr << "Faces of dimension " << N
- << " and their ajacent faces of dimension "
- << N - 1 << std::endl;
- for (unsigned f = 0; f < faces_.size(); ++f)
- {
- ostr << " " << f << ": dim " << N - 1
<< ": { ";
- lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
- ostr << "}" << std::endl;
- }
- }
-
- void
- faces_set_mixin<0u, 0u>::print(std::ostream& ostr) const
- {
- const unsigned N = 0u;
- ostr << "Faces of dimension " << N << std::endl;
- for (unsigned f = 0; f < faces_.size(); ++f)
- ostr << " " << f << std::endl;
- }
-
-
- template <unsigned N, unsigned D>
- void
- lower_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
- const face<N, D>& f) const
- {
- for (typename std::vector< face_handle<N - 1, D> >::const_iterator l =
- f.lower_dim_faces_.begin(); l != f.lower_dim_faces_.end(); ++l)
- ostr << l->face_id() << " ";
- }
-
- template <unsigned N, unsigned D>
- void
- higher_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
- const face<N, D>& f) const
- {
- for (typename std::vector< face_handle<N + 1, D> >::const_iterator h =
- f.higher_dim_faces_.begin(); h != f.higher_dim_faces_.end(); ++h)
- ostr << h->face_id() << " ";
- }
-
- } // end of namespace mln::internal
-
-
- /*-------------------------------.
- | Functional meta-manipulators. |
- `-------------------------------*/
-
- /* ------------------------------- */
- /* ``Static Fold Left'' Operator. */
- /* ------------------------------- */
-
- template <unsigned D>
- template <typename BinaryFunction, typename T>
- T
- complex<D>::fold_left_(const BinaryFunction& f, const T& accu) const
- {
- return data_->internal::faces_set_mixin<D, D>::fold_left_(f, accu);
- }
-
- namespace internal
- {
-
- // FIXME: Try to factor.
-
- template <unsigned D>
- template <typename BinaryFunction, typename T>
- T
- faces_set_mixin<D, D>::fold_left_(const BinaryFunction& f,
- const T& accu) const
- {
- return faces_set_mixin<D - 1, D>::fold_left_(f, f(accu, faces_));
- }
-
- template <unsigned N, unsigned D>
- template <typename BinaryFunction, typename T>
- T
- faces_set_mixin<N, D>::fold_left_(const BinaryFunction& f,
- const T& accu) const
- {
- return faces_set_mixin<N - 1, D>::fold_left_(f, f(accu, faces_));
- }
-
- template <unsigned D>
- template <typename BinaryFunction, typename T>
- T
- faces_set_mixin<0u, D>::fold_left_(const BinaryFunction& f,
- const T& accu) const
- {
- return f(accu, faces_);
- }
-
- template <typename BinaryFunction, typename T>
- T
- faces_set_mixin<0u, 0u>::fold_left_(const BinaryFunction& f,
- const T& accu) const
- {
- return f(accu, faces_);
- }
-
- } // end of namespace mln::internal
-
-
- /* ------------------------------------------------ */
- /* ``Static Apply-If-Dimension-Matches'' Operator. */
- /* ------------------------------------------------ */
-
- template <unsigned D>
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- complex<D>::apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const
- {
- // Ensure N is compatible with D.
- mln_precondition(n <= D);
- return data_->internal::faces_set_mixin<D, D>::apply_if_dim_matches_(n, f);
- }
-
- namespace internal
- {
-
- // FIXME: Try to factor.
-
- template <unsigned D>
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- faces_set_mixin<D, D>::apply_if_dim_matches_(unsigned n,
- const UnaryFunction& f) const
- {
- // Ensure N and D are compatible.
- mln_precondition(n <= D);
- return n == D ?
- f(faces_) :
- faces_set_mixin<D - 1, D>::apply_if_dim_matches_(n, f);
- }
-
- template <unsigned N, unsigned D>
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- faces_set_mixin<N, D>::apply_if_dim_matches_(unsigned n,
- const UnaryFunction& f) const
- {
- // Ensure N and D are compatible.
- mln_precondition(n <= D);
- return n == N ?
- f(faces_) :
- faces_set_mixin<N - 1, D>::apply_if_dim_matches_(n, f);
- }
-
- template <unsigned D>
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- faces_set_mixin<0u, D>::apply_if_dim_matches_(unsigned n,
- const UnaryFunction& f) const
- {
- // If we reached this method, then N should be 0.
- mln_precondition(n == 0);
- return f(faces_);
- }
-
- template <typename UnaryFunction>
- typename UnaryFunction::result_type
- faces_set_mixin<0u, 0u>::apply_if_dim_matches_(unsigned n,
- const UnaryFunction& f) const
- {
- // If we reached this method, then N should be 0.
- mln_precondition(n == 0);
- return f(faces_);
- }
-
- } // end of namespace mln::internal
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CORE_COMPLEX_HH
diff --git a/milena/mln/core/complex_faces_iter.hh
b/milena/mln/core/complex_faces_iter.hh
deleted file mode 100644
index ea86f6f..0000000
--- a/milena/mln/core/complex_faces_iter.hh
+++ /dev/null
@@ -1,262 +0,0 @@
-// 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_CORE_COMPLEX_FACES_ITER_HH
-# define MLN_CORE_COMPLEX_FACES_ITER_HH
-
-/// \file mln/core/complex_faces_iter.hh
-/// \brief Definition of forward and backward iterators on the n-faces
-/// of a complex.
-
-# include <mln/core/internal/complex_iter_base.hh>
-
-/* FIXME: Should we drop N from the signature of these iterators?
- I.e., have N be dynamic? Or better: provide other iterators where
- N is dynamic? */
-
-
-namespace mln
-{
-
- /*--------------------------------.
- | complex_faces_fwd_iter_<N, D>. |
- `--------------------------------*/
-
- /// \brief Forward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p N The dimension of the face associated to this iterator.
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned N, unsigned D>
- class complex_faces_fwd_iter_
- : public internal::complex_iter_base_< any_face_handle<D>,
- complex_faces_fwd_iter_<N, D> >
- {
- public:
- /// Type of associated face.
- typedef any_face_handle<D> face;
-
- private:
- typedef complex_faces_fwd_iter_<N, D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- complex_faces_fwd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- complex_faces_fwd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Test if the iterator is valid.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
- /*--------------------------------.
- | complex_faces_bkd_iter_<N, D>. |
- `--------------------------------*/
-
- /// \brief Backward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p N The dimension of the face associated to this iterator.
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned N, unsigned D>
- class complex_faces_bkd_iter_
- : public internal::complex_iter_base_< any_face_handle<D>,
- complex_faces_bkd_iter_<N, D> >
- {
- public:
- /// Type of associated face.
- typedef any_face_handle<D> face;
-
- private:
- typedef complex_faces_bkd_iter_<N, D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- complex_faces_bkd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- complex_faces_bkd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Start an iteration.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- /*--------------------------------.
- | complex_faces_fwd_iter_<N, D>. |
- `--------------------------------*/
-
- template <unsigned N, unsigned D>
- inline
- complex_faces_fwd_iter_<N, D>::complex_faces_fwd_iter_()
- : super_()
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- face_.set_n(N);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- complex_faces_fwd_iter_<N, D>::complex_faces_fwd_iter_(complex<D>& c)
- : super_(c)
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- face_.set_n(N);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- complex_faces_fwd_iter_<N, D>::start()
- {
- face_.set_face_id(0u);
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- complex_faces_fwd_iter_<N, D>::next_()
- {
- if (is_valid())
- {
- unsigned face_id = face_.face_id();
- if (face_id + 1 < face_.cplx().template nfaces<N>())
- /* FIXME: Provide accessor any_face_handle::face_id()
- returning a mutable reference? This way, we could just
- write
-
- ++face_.face_id();
-
- instead of the following.
-
- Or add {inc,add}_face_id() services. */
- face_.set_face_id(face_id + 1);
- else
- invalidate();
- }
- }
-
-
- /*--------------------------------.
- | complex_faces_bkd_iter_<N, D>. |
- `--------------------------------*/
-
- template <unsigned N, unsigned D>
- inline
- complex_faces_bkd_iter_<N, D>::complex_faces_bkd_iter_()
- : super_()
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- face_.set_n(N);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- complex_faces_bkd_iter_<N, D>::complex_faces_bkd_iter_(complex<D>& c)
- : super_(c)
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- face_.set_n(N);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- complex_faces_bkd_iter_<N, D>::start()
- {
- face_.set_face_id(face_.cplx().template nfaces<N>() - 1);
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- complex_faces_bkd_iter_<N, D>::next_()
- {
- if (is_valid())
- {
- unsigned face_id = face_.face_id();
- if (face_id > 0)
- /* FIXME: Provide accessor any_face_handle::face_id()
- returning a mutable reference? This way, we could just
- write
-
- ++face_.face_id();
-
- instead of the following.
-
- Or add {inc,add}_face_id() services. */
- face_.set_face_id(face_id - 1);
- else
- invalidate();
- }
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // ! MLN_CORE_COMPLEX_FACES_ITER_HH
diff --git a/milena/mln/core/complex_iter.hh b/milena/mln/core/complex_iter.hh
deleted file mode 100644
index 2a486be..0000000
--- a/milena/mln/core/complex_iter.hh
+++ /dev/null
@@ -1,270 +0,0 @@
-// 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_CORE_COMPLEX_ITER_HH
-# define MLN_CORE_COMPLEX_ITER_HH
-
-/// \file mln/core/complex_iter.hh
-/// \brief Definition of forward and backward iterators on complexes.
-
-# include <mln/core/internal/complex_iter_base.hh>
-
-// FIXME: Factor a bit more? (Using complex_iter_base_.)
-
-
-namespace mln
-{
-
- // Forward declaration.
- template <unsigned D> class complex;
-
- /*-----------------------.
- | complex_fwd_iter_<D>. |
- `-----------------------*/
-
- /// \brief Forward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned D>
- class complex_fwd_iter_
- : public internal::complex_iter_base_< any_face_handle<D>,
- complex_fwd_iter_<D> >
- {
- public:
- /// Type of associated face.
- typedef any_face_handle<D> face;
-
- private:
- typedef complex_fwd_iter_<D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- complex_fwd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- complex_fwd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Test if the iterator is valid.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
- /*-----------------------.
- | complex_bkd_iter_<D>. |
- `-----------------------*/
-
- /// \brief Backward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned D>
- class complex_bkd_iter_
- : public internal::complex_iter_base_< any_face_handle<D>,
- complex_bkd_iter_<D> >
- {
- public:
- /// Type of associated face.
- typedef any_face_handle<D> face;
-
- private:
- typedef complex_bkd_iter_<D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- complex_bkd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- complex_bkd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Start an iteration.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- /*-----------------------.
- | complex_fwd_iter_<D>. |
- `-----------------------*/
-
- template <unsigned D>
- inline
- complex_fwd_iter_<D>::complex_fwd_iter_()
- : super_()
- {
- }
-
- template <unsigned D>
- inline
- complex_fwd_iter_<D>::complex_fwd_iter_(complex<D>& c)
- : super_(c)
- {
- set_cplx(c);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned D>
- inline
- void
- complex_fwd_iter_<D>::start()
- {
- face_.set_n(0u);
- face_.set_face_id(0u);
- }
-
- template <unsigned D>
- inline
- void
- complex_fwd_iter_<D>::next_()
- {
- if (is_valid())
- {
- unsigned n = face_.n();
- unsigned face_id = face_.face_id();
-
- if (face_id + 1 < face_.cplx().nfaces(n))
- /* FIXME: Provide accessor any_face_handle::face_id() returning
- a mutable reference? This way, we could just write
-
- ++face_.face_id();
-
- instead of the following.
-
- Or add {inc,add}_face_id() services. */
- face_.set_face_id(face_id + 1);
- else
- // Start to iterate on the faces of the next dimension if
- // possible.
- if (n <= D)
- {
- // FIXME: Same remark as above.
- face_.set_n(n + 1);
- face_.set_face_id(0u);
- }
- else
- invalidate();
- }
- }
-
-
- /*-----------------------.
- | complex_bkd_iter_<D>. |
- `-----------------------*/
-
- template <unsigned D>
- inline
- complex_bkd_iter_<D>::complex_bkd_iter_()
- : super_()
- {
- }
-
- template <unsigned D>
- inline
- complex_bkd_iter_<D>::complex_bkd_iter_(complex<D>& c)
- : super_(c)
- {
- set_cplx(c);
- mln_postcondition(!is_valid());
- }
-
- template <unsigned D>
- inline
- void
- complex_bkd_iter_<D>::start()
- {
- face_.set_n(D);
- face_.set_face_id(face_.cplx().template nfaces<D>() - 1);
- }
-
- template <unsigned D>
- inline
- void
- complex_bkd_iter_<D>::next_()
- {
- if (is_valid())
- {
- unsigned n = face_.n();
- unsigned face_id = face_.face_id();
-
- if (face_id > 0)
- /* FIXME: Provide accessor any_face_handle::face_id() returning
- a mutable reference? This way, we could just write
-
- ++face_.face_id();
-
- instead of the following.
-
- Or add {inc,add}_face_id() services. */
- face_.set_face_id(face_id - 1);
- else
- // Start to iterate on the faces of the previous dimension
- // if it exists.
- if (n > 0)
- {
- // FIXME: Same remark as above.
- face_.set_n(n - 1);
- face_.set_face_id(face_.cplx().nfaces(n - 1) - 1);
- }
- else
- invalidate();
- }
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // ! MLN_CORE_COMPLEX_ITER_HH
diff --git a/milena/mln/core/face.hh b/milena/mln/core/face.hh
deleted file mode 100644
index 4692d65..0000000
--- a/milena/mln/core/face.hh
+++ /dev/null
@@ -1,729 +0,0 @@
-// 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_CORE_FACE_HH
-# define MLN_CORE_FACE_HH
-
-/// \file mln/core/face.hh
-/// \brief Face of a complex.
-
-#include <limits>
-
-#include <vector>
-
-#include <mln/core/contract.hh>
-
-/* FIXME: Suggestions:
-
- - rename `face' as `face_data', and move it into complex.hh or its
- own file;
- - rename `face_handle' as `face', and move it to its own file;
- - rename `any_face_handle' as `any_face', and move it to its own file.
-
- Anyway, whatever the decision, splitting `face', `face_handle' and
- `any_face_handle' seems to be sound.
-
- (And what about `faces_set'? Should we move it to its own file as
- well?) */
-
-namespace mln
-{
-
- // 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 face_handle;
- namespace internal
- {
- template <unsigned N, unsigned D> class lower_dim_faces_mixin;
- template <unsigned N, unsigned D> class higher_dim_faces_mixin;
- }
-
-
- /*-------.
- | Face. |
- `-------*/
-
- /// \p N-face of a \p D-complex.
- template <unsigned N, unsigned D> class face;
-
-
- // Specialization for the faces of highest dimension (\p D).
- template <unsigned D>
- class face<D, D> : public internal::lower_dim_faces_mixin<D, D>
- {
- };
-
- // Specialization for the faces of intermediate dimension (greater
- // than 0, lower than \p D).
- template <unsigned N, unsigned D>
- class face : public internal::lower_dim_faces_mixin<N, D>,
- public internal::higher_dim_faces_mixin<N, D>
- {
- };
-
- // Specialization for the faces of lowest dimension (0).
- template <unsigned D>
- class face<0u, D> : public internal::higher_dim_faces_mixin<0u, D>
- {
- };
-
- // Specialization for the case of a 0-complex.
- template <>
- class face<0u, 0u>
- {
- };
-
-
- namespace internal
- {
-
- /// Factored implementation of faces.
- /// \{
- template <unsigned N, unsigned D>
- class lower_dim_faces_mixin
- {
- public:
- void connect_lower_dim_face (const face_handle<N - 1, D>& f);
- private:
- friend class mln::internal::lower_dim_faces_set_mixin<N, D>;
- std::vector< face_handle<N - 1, D> > lower_dim_faces_;
- };
-
- template <unsigned N, unsigned D>
- class higher_dim_faces_mixin
- {
- public:
- void connect_higher_dim_face(const face_handle<N + 1, D>& f);
- private:
- friend class mln::internal::higher_dim_faces_set_mixin<N, D>;
- std::vector< face_handle<N + 1, D> > higher_dim_faces_;
- };
- /// \}
-
- } // end of namespace mln::internal
-
-
-
- /*--------------.
- | Face handle. |
- `--------------*/
-
- // Face handle in a complex.
- template <unsigned N, unsigned D>
- struct face_handle
- {
- // The type of the complex this handle points to.
- typedef complex<D> complex_type;
-
- /// Build a non-initialized face handle.
- face_handle();
- /// Build a face handle from \a complex and \a face_id.
- face_handle(complex<D>& complex, unsigned face_id);
-
- /// Copy and assignment.
- /// \{
- face_handle(const face_handle<N, D>& rhs);
- face_handle<N, D>& operator=(const face_handle<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::face pointed by this handle.
- face<N, D>& to_face() const;
- /// \}
-
- private:
- /// \brief The complex the face belongs to.
- ///
- /// A const face_handle 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>
- 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. |
- `----------------------*/
-
- /// \brief Set of face handles of dimension \p N.
- template <unsigned N, unsigned D>
- class faces_set
- {
- public:
- void add(const face_handle<N, D>& f);
-
- /// \brief Accessors.
- ///
- /// Return the set of handles.
- /// \{
- const std::vector< face_handle<N, D> >& faces() const;
- /// \}
-
- private:
- friend class mln::complex<D>;
-
- // FIXME: Rename this as `handles_'?
- std::vector< face_handle<N, D> > faces_;
- };
-
-
- /// Construction helpers for mln::faces_set.
- /// \{
- template <unsigned N, unsigned D>
- faces_set<N, D>
- operator+(const face_handle<N, D>& f1, const face_handle<N, D>&
f2);
-
- template <unsigned N, unsigned D>
- faces_set<N, D>
- operator+(const faces_set<N, D>& fs, const face_handle<N, D>& f);
- /// \}
-
-
- /*----------------------.
- | ``Any-face'' handle. |
- `----------------------*/
-
- // Face handle in a complex, where the dimension is dynamic.
- template <unsigned D>
- struct any_face_handle
- {
- // The type of the complex this handle points to.
- typedef complex<D> complex_type;
-
- /// Build a non-initialized face handle.
- any_face_handle();
- /// Build a face handle from \a complex and \a face_id.
- any_face_handle(complex<D>& complex, unsigned n, unsigned face_id);
-
- /// Build a face handle from a face_handle.
- template <unsigned N>
- any_face_handle(const face_handle<N, D>& f);
-
- /// Copy and assignment.
- /// \{
- any_face_handle(const any_face_handle<D>& rhs);
- any_face_handle<D>& operator=(const any_face_handle<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 dimension of the face.
- // FIXME: Rename as `dim'?
- unsigned n() 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);
- /// Set the dimension of the face.
- void set_n(unsigned n);
- /// Set the id of the face.
- void set_face_id(unsigned face_id);
-
- /// Return the mln::face pointed by this handle.
- template <unsigned N>
- face<N, D>& to_face() const;
- /// \}
-
- private:
- /// \brief The complex the face belongs to.
- ///
- /// A const any_face_handle can be used to modify a complex.
- mutable complex<D>* cplx_;
- /// The dimension of the face.
- // FIXME: Rename as `dim_'?
- unsigned n_;
- /// \brief The id of the face.
- // FIXME: Rename as `id_'?
- unsigned face_id_;
- };
-
-
- /// Comparison of two instances of mln::any_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 D>
- bool
- operator==(const any_face_handle<D>& lhs, const any_face_handle<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.
- /// \pre Arguments \a lhs and \a rhs must have the same dimension.
- template <unsigned D>
- bool
- operator< (const any_face_handle<D>& lhs, const
any_face_handle<D>& rhs);
- /// \}
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- /*--------.
- | Faces. |
- `--------*/
-
- namespace internal
- {
- template <unsigned N, unsigned D>
- inline
- void
- lower_dim_faces_mixin<N, D>::connect_lower_dim_face(const face_handle<N - 1,
D>& f)
- {
- lower_dim_faces_.push_back(f);
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- higher_dim_faces_mixin<N, D>::connect_higher_dim_face(const face_handle<N +
1, D>& f)
- {
- higher_dim_faces_.push_back(f);
- }
-
- } // end of namespace mln::internal
-
-
- /*--------------.
- | Face handle. |
- `--------------*/
-
- template <unsigned N, unsigned D>
- inline
- face_handle<N, D>::face_handle()
- : 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
- face_handle<N, D>::face_handle(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
- face_handle<N, D>::face_handle(const face_handle<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
- face_handle<N, D>&
- face_handle<N, D>::operator=(const face_handle<N, D>& rhs)
- {
- if (&rhs != this)
- {
- cplx_ = rhs.cplx_;
- face_id_ = rhs.face_id_;
- }
- return *this;
- }
-
- template <unsigned N, unsigned D>
- inline
- bool
- face_handle<N, D>::is_valid() const
- {
- return cplx_ != 0 && face_id_ < cplx_->template nfaces<N>();
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- face_handle<N, D>::invalidate()
- {
- set_face_id(std::numeric_limits<unsigned>::max());
- }
-
- template <unsigned N, unsigned D>
- inline
- complex<D>&
- face_handle<N, D>::cplx() const
- {
- mln_precondition(cplx_);
- return *cplx_;
- }
-
- template <unsigned N, unsigned D>
- inline
- unsigned
- face_handle<N, D>::n() const
- {
- return N;
- }
-
- template <unsigned N, unsigned D>
- inline
- unsigned
- face_handle<N, D>::face_id() const
- {
- return face_id_;
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- face_handle<N, D>::set_cplx(complex<D>& cplx)
- {
- cplx_ = &cplx;
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- face_handle<N, D>::set_face_id(unsigned face_id)
- {
- face_id_ = face_id;
- }
-
- template <unsigned N, unsigned D>
- inline
- face<N, D>&
- face_handle<N, D>::to_face() const
- {
- mln_precondition(is_valid());
- return cplx_->template face_<N>(face_id_);
- }
-
-
- template <unsigned N, unsigned D>
- inline
- face_handle<N, D>
- make_face_handle(const complex<D>& c, unsigned face_id)
- {
- return face_handle<N, D>(&c, face_id);
- }
-
- template <unsigned N, unsigned D>
- inline
- bool
- operator==(const face_handle<N, D>& lhs, const face_handle<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 face_handle<N, D>& lhs, const face_handle<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
- faces_set<N, D>::add(const face_handle<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< face_handle<N, D> >&
- faces_set<N, D>::faces() const
- {
- return faces_;
- }
-
-
- template <unsigned N, unsigned D>
- inline
- faces_set<N, D>
- operator+(const face_handle<N, D>& f1, const face_handle<N, D>&
f2)
- {
- faces_set<N, D> fs;
- fs.add(f1);
- fs.add(f2);
- return fs;
- }
-
- template <unsigned N, unsigned D>
- inline
- faces_set<N, D>
- operator+(const faces_set<N, D>& fs, const face_handle<N, D>& f)
- {
- faces_set<N, D> fs2(fs);
- fs2.add(f);
- return fs2;
- }
-
-
- /*----------------------.
- | ``Any-face'' handle. |
- `----------------------*/
-
- template <unsigned D>
- inline
- any_face_handle<D>::any_face_handle()
- : cplx_(0),
- n_(std::numeric_limits<unsigned>::max()),
- face_id_(std::numeric_limits<unsigned>::max())
- {
- }
-
- template <unsigned D>
- inline
- any_face_handle<D>::any_face_handle(complex<D>& c, unsigned n,
- unsigned face_id)
- : cplx_(&c), n_(n), face_id_(face_id)
- {
- // Ensure N is compatible with D.
- mln_precondition(n <= D);
- }
-
- template <unsigned D>
- template <unsigned N>
- inline
- any_face_handle<D>::any_face_handle(const face_handle<N, D>& f)
- : cplx_(&f.cplx()), n_(N), face_id_(f.face_id())
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
-
- }
-
- template <unsigned D>
- inline
- any_face_handle<D>::any_face_handle(const any_face_handle<D>& rhs)
- : cplx_(rhs.cplx_), n_(rhs.n_), face_id_(rhs.face_id_)
- {
- }
-
- template <unsigned D>
- inline
- any_face_handle<D>&
- any_face_handle<D>::operator=(const any_face_handle<D>& rhs)
- {
- if (&rhs != this)
- {
- cplx_ = rhs.cplx_;
- n_ = rhs.n_;
- face_id_ = rhs.face_id_;
- }
- return *this;
- }
-
- template <unsigned D>
- inline
- bool
- any_face_handle<D>::is_valid() const
- {
- return cplx_ != 0 && n_ <= D && face_id_ <
cplx_->nfaces(n_);
- }
-
- template <unsigned D>
- inline
- void
- any_face_handle<D>::invalidate()
- {
- set_n(std::numeric_limits<unsigned>::max());
- set_face_id(std::numeric_limits<unsigned>::max());
- }
-
- template <unsigned D>
- inline
- complex<D>&
- any_face_handle<D>::cplx() const
- {
- mln_precondition(cplx_);
- return *cplx_;
- }
-
- template <unsigned D>
- inline
- unsigned
- any_face_handle<D>::n() const
- {
- return n_;
- }
-
- template <unsigned D>
- inline
- unsigned
- any_face_handle<D>::face_id() const
- {
- return face_id_;
- }
-
- template <unsigned D>
- inline
- void
- any_face_handle<D>::set_cplx(complex<D>& cplx)
- {
- cplx_ = &cplx;
- }
-
- template <unsigned D>
- inline
- void
- any_face_handle<D>::set_n(unsigned n)
- {
- n_ = n;
- }
-
- template <unsigned D>
- inline
- void
- any_face_handle<D>::set_face_id(unsigned face_id)
- {
- face_id_ = face_id;
- }
-
- template <unsigned D>
- template <unsigned N>
- inline
- face<N, D>&
- any_face_handle<D>::to_face() const
- {
- mln_precondition(n_ == N);
- mln_precondition(is_valid());
- return cplx_->template face_<N>(face_id_);
- }
-
-
- template <unsigned D>
- inline
- bool
- operator==(const any_face_handle<D>& lhs, const any_face_handle<D>&
rhs)
- {
- // Ensure LHS and RHS belong to the same complex.
- mln_precondition(&lhs.face.cplx() == &rhs.face.cplx());
- return
- lhs.face().n() == rhs.face().n() &&
- lhs.face().id() == rhs.face().id();
- }
-
- template <unsigned D>
- inline
- bool
- operator< (const any_face_handle<D>& lhs, const
any_face_handle<D>& rhs)
- {
- // Ensure LHS and RHS belong to the same complex.
- mln_precondition(&lhs.face.cplx() == &rhs.face.cplx());
- // Ensure LHS and RHS have the same dimension.
- mln_precondition(lhs.face().n() == rhs.face().n());
- return lhs.face().id() < rhs.face().id();
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CORE_FACE_HH
diff --git a/milena/mln/core/faces_iter.hh b/milena/mln/core/faces_iter.hh
deleted file mode 100644
index 6194deb..0000000
--- a/milena/mln/core/faces_iter.hh
+++ /dev/null
@@ -1,247 +0,0 @@
-// 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_CORE_FACES_ITER_HH
-# define MLN_CORE_FACES_ITER_HH
-
-/// \file mln/core/faces_iter.hh
-/// \brief Definition of forward and backward iterators on the n-faces
-/// of a complex.
-
-# include <mln/core/internal/complex_iter_base.hh>
-
-namespace mln
-{
-
- /*------------------------.
- | faces_fwd_iter_<N, D>. |
- `------------------------*/
-
- /// \brief Forward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p N The dimension of the face associated to this iterator.
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned N, unsigned D>
- class faces_fwd_iter_
- : public internal::complex_iter_base_< face_handle<N, D>,
- faces_fwd_iter_<N, D> >
- {
- public:
- /// Type of associated face.
- typedef face_handle<N, D> face;
-
- private:
- typedef faces_fwd_iter_<N, D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- faces_fwd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- faces_fwd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Test if the iterator is valid.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
- /*------------------------.
- | faces_bkd_iter_<N, D>. |
- `------------------------*/
-
- /// \brief Backward iterator on all the faces of a mln::complex<D>.
- ///
- /// \arg \p N The dimension of the face associated to this iterator.
- /// \arg \p D The dimension of the complex this iterator belongs to.
- template <unsigned N, unsigned D>
- class faces_bkd_iter_
- : public internal::complex_iter_base_< face_handle<N, D>,
- faces_bkd_iter_<N, D> >
- {
- public:
- /// Type of associated face.
- typedef face_handle<N, D> face;
-
- private:
- typedef faces_bkd_iter_<N, D> self_;
- typedef internal::complex_iter_base_< face, self_ > super_;
-
- public:
- using super_::is_valid;
- using super_::invalidate;
-
- public:
- /// Construction and assignment.
- /// \{
- faces_bkd_iter_();
- // FIXME: See comment in internal::complex_iter_base_'s default ctor
- faces_bkd_iter_(complex<D>& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Start an iteration.
- void start();
- /// Go to the next point.
- void next_();
- /// \}
-
- private:
- using super_::face_;
- };
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- /*------------------------.
- | faces_fwd_iter_<N, D>. |
- `------------------------*/
-
- template <unsigned N, unsigned D>
- inline
- faces_fwd_iter_<N, D>::faces_fwd_iter_()
- : super_()
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- faces_fwd_iter_<N, D>::faces_fwd_iter_(complex<D>& c)
- : super_(c)
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- faces_fwd_iter_<N, D>::start()
- {
- face_.set_face_id(0u);
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- faces_fwd_iter_<N, D>::next_()
- {
- if (is_valid())
- {
- unsigned face_id = face_.face_id();
- if (face_id + 1 < face_.cplx().template nfaces<N>())
- /* FIXME: Provide accessor face_handle::n() returning
- a mutable reference? This way, we could just write
-
- ++face_.face_id();
-
- instead of the following. */
- face_.set_face_id(face_id + 1);
- else
- invalidate();
- }
- }
-
-
- /*------------------------.
- | faces_bkd_iter_<N, D>. |
- `------------------------*/
-
- template <unsigned N, unsigned D>
- inline
- faces_bkd_iter_<N, D>::faces_bkd_iter_()
- : super_()
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- faces_bkd_iter_<N, D>::faces_bkd_iter_(complex<D>& c)
- : super_(c)
- {
- // Ensure N is compatible with D.
- metal::bool_< N <= D >::check();
- mln_postcondition(!is_valid());
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- faces_bkd_iter_<N, D>::start()
- {
- face_.set_face_id(face_.cplx().template nfaces<N>() - 1);
- }
-
- template <unsigned N, unsigned D>
- inline
- void
- faces_bkd_iter_<N, D>::next_()
- {
- if (is_valid())
- {
- unsigned face_id = face_.face_id();
- if (face_id > 0)
- /* FIXME: Provide accessor face_handle::n() returning
- a mutable reference? This way, we could just write
-
- ++face_.face_id();
-
- instead of the following. */
- face_.set_face_id(face_id - 1);
- else
- invalidate();
- }
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // ! MLN_CORE_FACES_ITER_HH
diff --git a/milena/mln/core/internal/complex_iter_base.hh
b/milena/mln/core/internal/complex_iter_base.hh
deleted file mode 100644
index e2c747a..0000000
--- a/milena/mln/core/internal/complex_iter_base.hh
+++ /dev/null
@@ -1,202 +0,0 @@
-// 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_CORE_INTERNAL_COMPLEX_ITER_BASE_HH
-# define MLN_CORE_INTERNAL_COMPLEX_ITER_BASE_HH
-
-/// \file mln/core/internal/complex_iter_base.hh
-/// \brief Definition of an implementation (factoring) class for
-/// iterators on mln::complex.
-
-# include <limits>
-
-# include <mln/metal/equal.hh>
-
-# include <mln/core/concept/iterator.hh>
-# include <mln/core/complex.hh>
-
-namespace mln
-{
-
- namespace internal
- {
- /// \brief Factoring class for iterators on mln::complex.
- ///
- /// \arg \p F The type of the face handle.
- /// \arg \p E The type exact type of the iterator.
- template <typename F, typename E>
- class complex_iter_base_ : public Iterator<E>
- {
- typedef complex_iter_base_<F, E> self_;
-
- public:
- typedef F face;
- // FIXME: Maybe we could just get the dimension D of the face's
- // complex, an define complex_type as mln::complex<D>?
- typedef typename F::complex_type complex_type;
-
- /// Construction and assignment.
- /// \{
- /* FIXME: Keep this non-const? See a (big) comment about this in
- milena/tests/complex_image.cc. */
- complex_iter_base_();
- complex_iter_base_(complex_type& c);
- /// \}
-
- /// Manipulation.
- /// \{
- /// Change the target complex.
- // FIXME: Same comment as the ctor above.
- void set_cplx(complex_type& c);
-
- /// Test if the iterator is valid.
- bool is_valid() const;
- /// Invalidate the iterator.
- void invalidate();
- /// \}
-
- /// Conversion and accessors.
- /// \{
- /// Reference to the corresponding face handle.
- const face& to_face () const;
- /// Convert the iterator into an face handle.
- operator face() const;
- /// \}
-
- protected:
- /// The face handle this iterator is pointing to.
- face face_;
- };
-
-
- /* FIXME: This hand-made delegation is painful. We should rely on
- the general mechanism provided by Point_Site. But then again, we
- need to refine/adjust the interface of Point_Site w.r.t. the
- mandatory conversions to points. */
- template <typename F, typename E>
- inline
- std::ostream&
- operator<<(std::ostream& ostr, const complex_iter_base_<F, E>&
p);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename F, typename E>
- inline
- complex_iter_base_<F, E>::complex_iter_base_()
- {
- // Ensure F and E are compatible.
- mlc_equal(F, typename E::face)::check();
-
- invalidate();
- }
-
- template <typename F, typename E>
- inline
- complex_iter_base_<F, E>::complex_iter_base_(complex_type& c)
- {
- // Ensure F and E are compatible.
- mlc_equal(F, typename E::face)::check();
-
- face_.set_cplx(c);
- // Invalidate face_.
- invalidate();
- }
-
- template <typename F, typename E>
- inline
- void
- complex_iter_base_<F, E>::set_cplx(complex_type& c)
- {
- face_.set_cplx(c);
- // Invalidate face_.
- invalidate();
- }
-
- template <typename F, typename E>
- inline
- bool
- complex_iter_base_<F, E>::is_valid() const
- {
- return face_.is_valid();
- }
-
- template <typename F, typename E>
- inline
- void
- complex_iter_base_<F, E>::invalidate()
- {
- face_.invalidate();
- }
-
- template <typename F, typename E>
- inline
- const F&
- complex_iter_base_<F, E>::to_face() const
- {
- return face_;
- }
-
- template <typename F, typename E>
- inline
- complex_iter_base_<F, E>::operator F() const
- {
- mln_precondition(is_valid());
- return face_;
- }
-
-
- template <typename F, typename E>
- inline
- std::ostream&
- operator<<(std::ostream& ostr, const complex_iter_base_<F, E>&
p)
- {
- /* FIXME: We should use p.to_face() here, but as it lacks the
- precondition the conversion operator has, so we use the latter.
-
- We should
- - rename `to_face' as `to_face_';
- - write a new `to_face' routine checking the validity of the
- iterator;
- - have the conversion operator to face use this new `to_face'
- routine;
- - adjust former clients of `to_face'
-
- This is a general remark that applies to all iterators of
- Milena. */
- F f = p;
- return ostr << "(dim = " << f.n() << ", id =
" << f.face_id() << ')';
- }
-
- } // end of mln::internal
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-#endif // ! MLN_CORE_INTERNAL_COMPLEX_ITER_BASE_HH
diff --git a/milena/mln/topo/complex.hh b/milena/mln/topo/complex.hh
new file mode 100644
index 0000000..ae69dee
--- /dev/null
+++ b/milena/mln/topo/complex.hh
@@ -0,0 +1,857 @@
+// 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_COMPLEX_HH
+# define MLN_TOPO_COMPLEX_HH
+
+/// \file mln/core/topo/complex.hh
+/// \brief Structures for general complexes.
+///
+/// A complex defines a topological space which can be used as a
+/// support for an image (i.e., as site sets).
+
+# include <cstddef>
+
+# include <limits>
+# include <iosfwd>
+
+# include <mln/metal/bool.hh>
+
+# include <mln/util/tracked_ptr.hh>
+
+# include <mln/topo/face.hh>
+
+# include <mln/topo/complex_iter.hh>
+# include <mln/topo/faces_iter.hh>
+# include <mln/topo/complex_faces_iter.hh>
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ // Forward declarations.
+ namespace internal
+ {
+ template <unsigned D>
+ struct complex_data;
+
+ 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_;
+
+
+ /*----------.
+ | Complex. |
+ `----------*/
+
+ /// \brief General complex of dimension \p D.
+ template <unsigned D>
+ class complex
+ {
+ public:
+ /// Forward mln::Iterator type iterating on all faces.
+ typedef complex_fwd_iter_<D> fwd_citer;
+ /// Backward mln::Iterator type iterating on all faces.
+ typedef complex_bkd_iter_<D> bkd_citer;
+
+ /// Forward mln::Iterator type iterating on \p N-faces.
+ template <unsigned N>
+ struct fwd_fiter { typedef faces_fwd_iter_<N, D> ret; };
+ /// Backward mln::Iterator type iterating on \p N-faces.
+ template <unsigned N>
+ struct bkd_fiter { typedef faces_bkd_iter_<N, D> ret; };
+
+ /// Complex construction.
+ /// \{
+ /// Create a new \p D-complex.
+ complex();
+
+ /// \brief Add a 0-face to the complex.
+ face_handle<0u, D> add_face();
+
+ /// \brief Add a \p (N+1)-face to the complex (with \p N >= 0).
+ ///
+ /// \param adjacent_faces The (\p N-1)-faces adjacent to the new
+ /// \p N-face.
+ template <unsigned N>
+ face_handle<N + 1, D> add_face(const faces_set<N, D>&
adjacent_faces);
+ /// \}
+
+ /// \brief Static manipulators.
+ ///
+ /// These methods use statically-known input.
+ /// \{
+ /// \brief Return the total number of faces, whatever their
+ /// dimension.
+ std::size_t nfaces() const;
+
+ /// \brief Return the number of \p N-faces.
+ template <unsigned N>
+ std::size_t nfaces() const;
+ /// \}
+
+ /// \brief Dynamic manipulators.
+ ///
+ /// These methods use input know as run time.
+ /// \{
+ /// \brief Return the number of \a n-faces.
+ ///
+ /// Warning, this function has a complexity linear in term of N,
+ /// since each faces_set is checked (the present implementation
+ /// does not provide a direct access to faces_set through a
+ /// dynamic value of the dimension).
+ std::size_t nfaces(unsigned n) const;
+ /// \}
+
+ /// Pretty-printing.
+ /// \{
+ /// Print the complex.
+ void print(std::ostream& ostr) const;
+ /// Print the faces of dimension \p N.
+ template <unsigned N>
+ void print_faces(std::ostream& ostr) const;
+ /// \}
+
+ private:
+ /// The actual data of the complex.
+ util::tracked_ptr< internal::complex_data<D> > data_;
+
+ template <unsigned D_>
+ friend bool operator==(const complex<D_>& lhs, const
complex<D_>& rhs);
+
+ /// Accessors.
+ /// \{
+ template <unsigned N, unsigned D_> friend class face_handle;
+ template <unsigned D_> friend class any_face_handle;
+
+ template <unsigned N>
+ face<N, D>& face_(unsigned face_id);
+
+ template <unsigned N>
+ const face<N, D>& face_(unsigned face_id) const;
+ /// \}
+
+ /// Functional meta-manipulators.
+ /// \{
+ /* FIXME: Use something more constraining than the STL's
+ UnaryFunction/BinaryFunction. Use Function or Function_v2v?
+ Or a new subclass of Function? */
+
+ /* FIXME: Replace F and ACCU by a Milena accumulator? */
+
+ /** \brief Apply a kind of static fold left operator to the
+ implicit list of faces_set using a functor \a f and a value \a
+ accu.
+
+ Argument \a is called an "accumulator", but with a slightly
+ different meaning than mln:accu members.
+
+ We might want to use TypeLists or something similar, is they
+ provide an explicit static fold left operator. */
+ template <typename BinaryFunction, typename T>
+ T fold_left_(const BinaryFunction& f, const T& accu) const;
+
+ /// \brief Apply a functor \a f to this list of \a n-faces.
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
+ /// \}
+
+ /// \brief connect two faces.
+ ///
+ /// \param f1 A face of dimension \p N
+ /// \param f2 A face of dimension \p N + 1
+ ///
+ /// \pre \p N must be lower or equal to \p D.
+ template <unsigned N>
+ void connect_(const face_handle<N, D>& f1,
+ const face_handle<N + 1, D>& f2);
+ };
+
+
+ /// Compare two complexes for equality.
+ template <unsigned D>
+ bool
+ operator==(const complex<D>& lhs, const complex<D>& rhs);
+
+
+ /// Pretty print a complex.
+ template <unsigned D>
+ std::ostream&
+ operator<<(std::ostream& ostr, const complex<D>& c);
+
+
+ /*---------------.
+ | Complex data. |
+ `---------------*/
+
+ namespace internal
+ {
+ // Forward declarations.
+ template <unsigned N, unsigned D>
+ struct faces_set_mixin;
+
+ /// \brief Complex data.
+ template <unsigned D>
+ struct complex_data : faces_set_mixin<D, D>
+ {
+ // Data is contained in super classes.
+ };
+
+ } // end of namespace mln::topo::internal
+
+
+ /*---------------------.
+ | Faces of a complex. |
+ `---------------------*/
+
+ /// The sets of n-faces of a complex are recursively aggregated as
+ /// mixins.
+ namespace internal
+ {
+
+ // Forward declarations.
+ template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin;
+ template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin;
+
+ // -------------------------------------- //
+ // mln::topo::internal::faces_set_mixin. //
+ // -------------------------------------- //
+
+ /// \brief Recursive mixins of set of faces.
+ /// \{
+ template <unsigned N, unsigned D> struct faces_set_mixin;
+
+ /// Faces of highest dimension (\p D).
+ template <unsigned D>
+ struct faces_set_mixin<D, D> : public faces_set_mixin<D - 1, D>,
+ public lower_dim_faces_set_mixin<D, D>
+ {
+ std::vector< face<D, D> > faces_;
+
+ /// Pretty-printing.
+ /// \{
+ /// Print the faces of dimension \p D.
+ void print(std::ostream& ostr) const;
+ void print_rec_asc(std::ostream& ostr) const;
+ /// \}
+
+ /// Functional meta-manipulators.
+ /// \{
+ /// \brief Fold left.
+ /// \see mln::complex<D>::fold_left_.
+ template <typename BinaryFunction, typename T>
+ T fold_left_(const BinaryFunction& f, const T& accu) const;
+ /// \brief Apply a functor \a f to the list of faces if \a n == \p D.
+ /// \see mln::complex<D>::apply_if_dim_matches_.
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
+ /// \}
+ };
+
+ /// Faces of intermediate dimension (greater than 0, lower than \p D).
+ template <unsigned N, unsigned D>
+ struct faces_set_mixin : public faces_set_mixin<N - 1, D>,
+ public lower_dim_faces_set_mixin<N, D>,
+ public higher_dim_faces_set_mixin<N, D>
+ {
+ std::vector< face<N, D> > faces_;
+
+ /// Pretty-printing.
+ /// \{
+ /// Print the faces of dimension \p N.
+ void print(std::ostream& ostr) const;
+ /// Recursively print the faces of dimensions 0 to \p N
+ /// (in ascending dimension).
+ void print_rec_asc(std::ostream& ostr) const;
+ /// \}
+
+ /// Functional meta-manipulators.
+ /// \{
+ /// \brief Fold left.
+ /// \see mln::complex<D>::fold_left_.
+ template <typename BinaryFunction, typename T>
+ T fold_left_(const BinaryFunction& f, const T& accu) const;
+ /// \brief Apply a functor \a f to the list of faces if \a n == \p N.
+ /// \see mln::complex<D>::apply_if_dim_matches_.
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
+ /// \}
+ };
+
+ /// Faces of lowest dimension (0).
+ template <unsigned D>
+ struct faces_set_mixin<0u, D> : public higher_dim_faces_set_mixin<0u,
D>
+ {
+ std::vector< face<0u, D> > faces_;
+
+ /// Pretty-printing.
+ /// \{
+ /// Print the faces of dimension 0.
+ void print(std::ostream& ostr) const;
+ void print_rec_asc(std::ostream& ostr) const;
+ /// \}
+
+ /// Functional meta-manipulators.
+ /// \{
+ /// \brief Fold left.
+ /// \see mln::complex<D>::fold_left_.
+ template <typename BinaryFunction, typename T>
+ T fold_left_(const BinaryFunction& f, const T& accu) const;
+ /// \brief Apply a functor \a f to the list of faces if \a n == 0.
+ /// \see mln::complex<D>::apply_if_dim_matches_.
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
+ /// \}
+ };
+
+ /// Faces of a 0-complex.
+ template <>
+ struct faces_set_mixin<0u, 0u>
+ {
+ std::vector< face<0u, 0u> > faces_;
+
+ /// Pretty-printing.
+ /// \{
+ /// Print the faces of dimension \p D.
+ void print(std::ostream& ostr) const;
+ void print_rec_asc(std::ostream& ostr) const;
+ /// \}
+
+ /// Functional meta-manipulators.
+ /// \{
+ /// \brief Fold left.
+ /// \see mln::complex<D>::fold_left_.
+ template <typename BinaryFunction, typename T>
+ T fold_left_(const BinaryFunction& f, const T& accu) const;
+ /// \brief Apply a functor \a f to the list of faces if \a n == 0.
+ /// \see mln::complex<D>::apply_if_dim_matches_.
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
+ /// \}
+ };
+ /// \}
+
+
+ // ------------------------------------------------- //
+ // mln::topo::internal::lower_dim_faces_set_mixin. //
+ // mln::topo::internal::higher_dim_faces_set_mixin. //
+ // ------------------------------------------------- //
+
+ /// Mixins of mixin mln::faces_set_mixin.
+ /// \{
+ template <unsigned N, unsigned D>
+ struct lower_dim_faces_set_mixin
+ {
+ void print(std::ostream& ostr, const face<N, D>& f) const;
+ };
+
+ template <unsigned N, unsigned D>
+ struct higher_dim_faces_set_mixin
+ {
+ void print(std::ostream& ostr, const face<N, D>& f) const;
+ };
+ /// \}
+
+ } // end of namespace mln::topo::internal
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*-----------------------.
+ | Complex construction. |
+ `-----------------------*/
+
+ template <unsigned D>
+ complex<D>::complex()
+ // Allocate data for this complex.
+ : data_(new internal::complex_data<D>())
+ {
+ }
+
+ template <unsigned D>
+ face_handle<0u, D>
+ complex<D>::add_face()
+ {
+ /* FIXME: This is not thread-proof (these two lines should
+ form an atomic section). */
+ data_->internal::faces_set_mixin<0u, D>::faces_.push_back(face<0u,
D>());
+ unsigned id = nfaces<0u>() - 1;
+
+ return face_handle<0u, D>(*this, id);
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ face_handle<N + 1, D>
+ complex<D>::add_face(const faces_set<N, D>& adjacent_faces)
+ {
+ typedef typename std::vector< face_handle<N, D> >::const_iterator
iter_t;
+
+ // Ensure ADJACENT_FACES are already part of the complex.
+ if (!HAS_NDEBUG)
+ for (iter_t a = adjacent_faces.faces().begin();
+ a != adjacent_faces.faces().end(); ++a)
+ {
+ mln_precondition(&a->cplx() == this);
+ mln_precondition(a->is_valid());
+ }
+
+ face<N + 1, D> f;
+ /* FIXME: This is not thread-proof (these two lines should
+ form an atomic section). */
+ data_->internal::faces_set_mixin<N + 1, D>::faces_.push_back(f);
+ unsigned id = nfaces<N + 1>() - 1;
+
+ face_handle<N + 1, D> fh(*this, id);
+ // Connect F and its ADJACENT_FACES.
+ for (iter_t a = adjacent_faces.faces().begin();
+ a != adjacent_faces.faces().end(); ++a)
+ connect_(*a, fh);
+ return fh;
+ }
+
+
+ /*-------.
+ | Misc. |
+ `-------*/
+
+ namespace internal
+ {
+
+ /// A binary meta-functor defined by:
+ ///
+ /// \code
+ /// add_size : x, c -> x + c.size()
+ /// \endcode
+ ///
+ /// \see mln::complex<D>::nfaces (static version).
+ /// \see mln::complex<D>::fold_left_.
+ struct add_size
+ {
+ template <typename T, typename Container>
+ T operator()(const T& x, const Container& c) const
+ {
+ return x + c.size();
+ }
+ };
+
+ /// An unary meta-functor defined by:
+ ///
+ /// \code
+ /// add_size : c -> c.size()
+ /// \endcode
+ ///
+ /// \see mln::complex<D>::nfaces (dynamic version).
+ /// \see mln::complex<D>::apply_if_dim_matches_.
+ struct get_size
+ {
+ typedef std::size_t result_type;
+
+ template <typename Container>
+ typename Container::size_type operator()(const Container& c) const
+ {
+ return c.size();
+ }
+ };
+
+ } // end of namespace mln::topo::internal
+
+
+ /*----------------------.
+ | Static manipulators. |
+ `----------------------*/
+
+ template <unsigned D>
+ std::size_t
+ complex<D>::nfaces() const
+ {
+ return fold_left_(internal::add_size(), 0);
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ std::size_t
+ complex<D>::nfaces() const
+ {
+ return data_->internal::faces_set_mixin<N, D>::faces_.size();
+ }
+
+
+ /*-----------------------.
+ | Dynamic manipulators. |
+ `-----------------------*/
+
+ template <unsigned D>
+ std::size_t
+ complex<D>::nfaces(unsigned n) const
+ {
+ // Ensure N is compatible with D.
+ mln_precondition(n <= D);
+ return apply_if_dim_matches_(n, internal::get_size());
+ }
+
+
+ /*-------------------.
+ | Internal methods. |
+ `-------------------*/
+
+ template <unsigned D>
+ template <unsigned N>
+ face<N, D>&
+ complex<D>::face_(unsigned face_id)
+ {
+ return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ const face<N, D>&
+ complex<D>::face_(unsigned face_id) const
+ {
+ return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ void
+ complex<D>::connect_(const face_handle<N, D>& f1,
+ const face_handle<N + 1, D>& f2)
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+
+ f1.to_face().connect_higher_dim_face(f2);
+ f2.to_face().connect_lower_dim_face(f1);
+ }
+
+
+ /*-------------.
+ | Comparison. |
+ `-------------*/
+
+ template <unsigned D>
+ bool
+ operator==(const complex<D>& lhs, const complex<D>& rhs)
+ {
+ return lhs.data_.ptr_ == rhs.data_.ptr_;
+ }
+
+
+ /*------------------.
+ | Pretty-printing. |
+ `------------------*/
+
+ template <unsigned D>
+ std::ostream&
+ operator<<(std::ostream& ostr, const complex<D>& c)
+ {
+ c.print(ostr);
+ return ostr;
+ }
+
+ template <unsigned D>
+ void
+ complex<D>::print(std::ostream& ostr) const
+ {
+ data_->internal::faces_set_mixin<D, D>::print_rec_asc(ostr);
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ void
+ complex<D>::print_faces(std::ostream& ostr) const
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+
+ data_->internal::faces_set_mixin<N, D>::print(ostr);
+ }
+
+
+ namespace internal
+ {
+
+ template <unsigned N, unsigned D>
+ void
+ faces_set_mixin<N, D>::print_rec_asc(std::ostream& ostr) const
+ {
+ faces_set_mixin<N - 1, D>::print_rec_asc(ostr);
+ print(ostr);
+ }
+
+ template <unsigned D>
+ void
+ faces_set_mixin<0u, D>::print_rec_asc(std::ostream& ostr) const
+ {
+ print(ostr);
+ }
+
+ template <unsigned D>
+ void
+ faces_set_mixin<D, D>::print_rec_asc(std::ostream& ostr) const
+ {
+ faces_set_mixin<D - 1, D>::print_rec_asc(ostr);
+ print(ostr);
+ }
+
+ void
+ faces_set_mixin<0u, 0u>::print_rec_asc(std::ostream& ostr) const
+ {
+ print(ostr);
+ }
+
+
+ template <unsigned N, unsigned D>
+ void
+ faces_set_mixin<N, D>::print(std::ostream& ostr) const
+ {
+ ostr << "Faces of dimension " << N
+ << " and their ajacent faces of dimension "
+ << N - 1 << " and "
+ << N + 1 << std::endl;
+ for (unsigned f = 0; f < faces_.size(); ++f)
+ {
+ ostr << " " << f << ": dim " << N - 1
<< ": { ";
+ lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
+ ostr << "}, dim " << N + 1 << ": { ";
+ higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
+ ostr << "}" << std::endl;
+ }
+ }
+
+ template <unsigned D>
+ void
+ faces_set_mixin<0u, D>::print(std::ostream& ostr) const
+ {
+ const unsigned N = 0u;
+ ostr << "Faces of dimension " << N
+ << " and their ajacent faces of dimension "
+ << N + 1 << std::endl;
+ for (unsigned f = 0; f < faces_.size(); ++f)
+ {
+ ostr << " " << f << ": dim " << N + 1
<< ": { ";
+ higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
+ ostr << "}" << std::endl;
+ }
+ }
+
+ template <unsigned D>
+ void
+ faces_set_mixin<D, D>::print(std::ostream& ostr) const
+ {
+ const unsigned N = D;
+ ostr << "Faces of dimension " << N
+ << " and their ajacent faces of dimension "
+ << N - 1 << std::endl;
+ for (unsigned f = 0; f < faces_.size(); ++f)
+ {
+ ostr << " " << f << ": dim " << N - 1
<< ": { ";
+ lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
+ ostr << "}" << std::endl;
+ }
+ }
+
+ void
+ faces_set_mixin<0u, 0u>::print(std::ostream& ostr) const
+ {
+ const unsigned N = 0u;
+ ostr << "Faces of dimension " << N << std::endl;
+ for (unsigned f = 0; f < faces_.size(); ++f)
+ ostr << " " << f << std::endl;
+ }
+
+
+ template <unsigned N, unsigned D>
+ void
+ lower_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
+ const face<N, D>& f) const
+ {
+ for (typename std::vector< face_handle<N - 1, D> >::const_iterator l =
+ f.lower_dim_faces_.begin(); l != f.lower_dim_faces_.end(); ++l)
+ ostr << l->face_id() << " ";
+ }
+
+ template <unsigned N, unsigned D>
+ void
+ higher_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
+ const face<N, D>& f) const
+ {
+ for (typename std::vector< face_handle<N + 1, D> >::const_iterator h =
+ f.higher_dim_faces_.begin(); h != f.higher_dim_faces_.end(); ++h)
+ ostr << h->face_id() << " ";
+ }
+
+ } // end of namespace mln::topo::internal
+
+
+ /*-------------------------------.
+ | Functional meta-manipulators. |
+ `-------------------------------*/
+
+ /* ------------------------------- */
+ /* ``Static Fold Left'' Operator. */
+ /* ------------------------------- */
+
+ template <unsigned D>
+ template <typename BinaryFunction, typename T>
+ T
+ complex<D>::fold_left_(const BinaryFunction& f, const T& accu) const
+ {
+ return data_->internal::faces_set_mixin<D, D>::fold_left_(f, accu);
+ }
+
+ namespace internal
+ {
+
+ // FIXME: Try to factor.
+
+ template <unsigned D>
+ template <typename BinaryFunction, typename T>
+ T
+ faces_set_mixin<D, D>::fold_left_(const BinaryFunction& f,
+ const T& accu) const
+ {
+ return faces_set_mixin<D - 1, D>::fold_left_(f, f(accu, faces_));
+ }
+
+ template <unsigned N, unsigned D>
+ template <typename BinaryFunction, typename T>
+ T
+ faces_set_mixin<N, D>::fold_left_(const BinaryFunction& f,
+ const T& accu) const
+ {
+ return faces_set_mixin<N - 1, D>::fold_left_(f, f(accu, faces_));
+ }
+
+ template <unsigned D>
+ template <typename BinaryFunction, typename T>
+ T
+ faces_set_mixin<0u, D>::fold_left_(const BinaryFunction& f,
+ const T& accu) const
+ {
+ return f(accu, faces_);
+ }
+
+ template <typename BinaryFunction, typename T>
+ T
+ faces_set_mixin<0u, 0u>::fold_left_(const BinaryFunction& f,
+ const T& accu) const
+ {
+ return f(accu, faces_);
+ }
+
+ } // end of namespace mln::topo::internal
+
+
+ /* ------------------------------------------------ */
+ /* ``Static Apply-If-Dimension-Matches'' Operator. */
+ /* ------------------------------------------------ */
+
+ template <unsigned D>
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ complex<D>::apply_if_dim_matches_(unsigned n, const UnaryFunction& f)
const
+ {
+ // Ensure N is compatible with D.
+ mln_precondition(n <= D);
+ return data_->internal::faces_set_mixin<D, D>::apply_if_dim_matches_(n,
f);
+ }
+
+ namespace internal
+ {
+
+ // FIXME: Try to factor.
+
+ template <unsigned D>
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ faces_set_mixin<D, D>::apply_if_dim_matches_(unsigned n,
+ const UnaryFunction& f) const
+ {
+ // Ensure N and D are compatible.
+ mln_precondition(n <= D);
+ return n == D ?
+ f(faces_) :
+ faces_set_mixin<D - 1, D>::apply_if_dim_matches_(n, f);
+ }
+
+ template <unsigned N, unsigned D>
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ faces_set_mixin<N, D>::apply_if_dim_matches_(unsigned n,
+ const UnaryFunction& f) const
+ {
+ // Ensure N and D are compatible.
+ mln_precondition(n <= D);
+ return n == N ?
+ f(faces_) :
+ faces_set_mixin<N - 1, D>::apply_if_dim_matches_(n, f);
+ }
+
+ template <unsigned D>
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ faces_set_mixin<0u, D>::apply_if_dim_matches_(unsigned n,
+ const UnaryFunction& f) const
+ {
+ // If we reached this method, then N should be 0.
+ mln_precondition(n == 0);
+ return f(faces_);
+ }
+
+ template <typename UnaryFunction>
+ typename UnaryFunction::result_type
+ faces_set_mixin<0u, 0u>::apply_if_dim_matches_(unsigned n,
+ const UnaryFunction& f) const
+ {
+ // If we reached this method, then N should be 0.
+ mln_precondition(n == 0);
+ return f(faces_);
+ }
+
+ } // end of namespace mln::topo::internal
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_COMPLEX_HH
diff --git a/milena/mln/topo/complex_faces_iter.hh
b/milena/mln/topo/complex_faces_iter.hh
new file mode 100644
index 0000000..05713da
--- /dev/null
+++ b/milena/mln/topo/complex_faces_iter.hh
@@ -0,0 +1,266 @@
+// 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_COMPLEX_FACES_ITER_HH
+# define MLN_TOPO_COMPLEX_FACES_ITER_HH
+
+/// \file mln/topo/complex_faces_iter.hh
+/// \brief Definition of forward and backward iterators on the n-faces
+/// of a complex.
+
+# include <mln/topo/internal/complex_iter_base.hh>
+
+/* FIXME: Should we drop N from the signature of these iterators?
+ I.e., have N be dynamic? Or better: provide other iterators where
+ N is dynamic? */
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ /*--------------------------------------.
+ | topo::complex_faces_fwd_iter_<N, D>. |
+ `--------------------------------------*/
+
+ /// \brief Forward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p N The dimension of the face associated to this iterator.
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned N, unsigned D>
+ class complex_faces_fwd_iter_
+ : public internal::complex_iter_base_< any_face_handle<D>,
+ complex_faces_fwd_iter_<N, D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef any_face_handle<D> face;
+
+ private:
+ typedef complex_faces_fwd_iter_<N, D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ complex_faces_fwd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ complex_faces_fwd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+ /*--------------------------------------.
+ | topo::complex_faces_bkd_iter_<N, D>. |
+ `--------------------------------------*/
+
+ /// \brief Backward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p N The dimension of the face associated to this iterator.
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned N, unsigned D>
+ class complex_faces_bkd_iter_
+ : public internal::complex_iter_base_< any_face_handle<D>,
+ complex_faces_bkd_iter_<N, D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef any_face_handle<D> face;
+
+ private:
+ typedef complex_faces_bkd_iter_<N, D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ complex_faces_bkd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ complex_faces_bkd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Start an iteration.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*--------------------------------------.
+ | topo::complex_faces_fwd_iter_<N, D>. |
+ `--------------------------------------*/
+
+ template <unsigned N, unsigned D>
+ inline
+ complex_faces_fwd_iter_<N, D>::complex_faces_fwd_iter_()
+ : super_()
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ face_.set_n(N);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ complex_faces_fwd_iter_<N, D>::complex_faces_fwd_iter_(complex<D>&
c)
+ : super_(c)
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ face_.set_n(N);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ complex_faces_fwd_iter_<N, D>::start()
+ {
+ face_.set_face_id(0u);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ complex_faces_fwd_iter_<N, D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ if (face_id + 1 < face_.cplx().template nfaces<N>())
+ /* FIXME: Provide accessor any_face_handle::face_id()
+ returning a mutable reference? This way, we could just
+ write
+
+ ++face_.face_id();
+
+ instead of the following.
+
+ Or add {inc,add}_face_id() services. */
+ face_.set_face_id(face_id + 1);
+ else
+ invalidate();
+ }
+ }
+
+
+ /*--------------------------------------.
+ | topo::complex_faces_bkd_iter_<N, D>. |
+ `--------------------------------------*/
+
+ template <unsigned N, unsigned D>
+ inline
+ complex_faces_bkd_iter_<N, D>::complex_faces_bkd_iter_()
+ : super_()
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ face_.set_n(N);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ complex_faces_bkd_iter_<N, D>::complex_faces_bkd_iter_(complex<D>&
c)
+ : super_(c)
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ face_.set_n(N);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ complex_faces_bkd_iter_<N, D>::start()
+ {
+ face_.set_face_id(face_.cplx().template nfaces<N>() - 1);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ complex_faces_bkd_iter_<N, D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ if (face_id > 0)
+ /* FIXME: Provide accessor any_face_handle::face_id()
+ returning a mutable reference? This way, we could just
+ write
+
+ ++face_.face_id();
+
+ instead of the following.
+
+ Or add {inc,add}_face_id() services. */
+ face_.set_face_id(face_id - 1);
+ else
+ invalidate();
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_COMPLEX_FACES_ITER_HH
diff --git a/milena/mln/topo/complex_iter.hh b/milena/mln/topo/complex_iter.hh
new file mode 100644
index 0000000..b30ca00
--- /dev/null
+++ b/milena/mln/topo/complex_iter.hh
@@ -0,0 +1,275 @@
+// 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_COMPLEX_ITER_HH
+# define MLN_TOPO_COMPLEX_ITER_HH
+
+/// \file mln/topo/complex_iter.hh
+/// \brief Definition of forward and backward iterators on complexes.
+
+# include <mln/topo/internal/complex_iter_base.hh>
+
+// FIXME: Factor a bit more? (Using complex_iter_base_.)
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ // Forward declaration.
+ template <unsigned D> class complex;
+
+
+ /*-----------------------------.
+ | topo::complex_fwd_iter_<D>. |
+ `-----------------------------*/
+
+ /// \brief Forward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned D>
+ class complex_fwd_iter_
+ : public internal::complex_iter_base_< any_face_handle<D>,
+ complex_fwd_iter_<D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef any_face_handle<D> face;
+
+ private:
+ typedef complex_fwd_iter_<D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ complex_fwd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ complex_fwd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+ /*-----------------------------.
+ | topo::complex_bkd_iter_<D>. |
+ `-----------------------------*/
+
+ /// \brief Backward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned D>
+ class complex_bkd_iter_
+ : public internal::complex_iter_base_< any_face_handle<D>,
+ complex_bkd_iter_<D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef any_face_handle<D> face;
+
+ private:
+ typedef complex_bkd_iter_<D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ complex_bkd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ complex_bkd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Start an iteration.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*-----------------------------.
+ | topo::complex_fwd_iter_<D>. |
+ `-----------------------------*/
+
+ template <unsigned D>
+ inline
+ complex_fwd_iter_<D>::complex_fwd_iter_()
+ : super_()
+ {
+ }
+
+ template <unsigned D>
+ inline
+ complex_fwd_iter_<D>::complex_fwd_iter_(complex<D>& c)
+ : super_(c)
+ {
+ set_cplx(c);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned D>
+ inline
+ void
+ complex_fwd_iter_<D>::start()
+ {
+ face_.set_n(0u);
+ face_.set_face_id(0u);
+ }
+
+ template <unsigned D>
+ inline
+ void
+ complex_fwd_iter_<D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned n = face_.n();
+ unsigned face_id = face_.face_id();
+
+ if (face_id + 1 < face_.cplx().nfaces(n))
+ /* FIXME: Provide accessor any_face_handle::face_id() returning
+ a mutable reference? This way, we could just write
+
+ ++face_.face_id();
+
+ instead of the following.
+
+ Or add {inc,add}_face_id() services. */
+ face_.set_face_id(face_id + 1);
+ else
+ // Start to iterate on the faces of the next dimension if
+ // possible.
+ if (n <= D)
+ {
+ // FIXME: Same remark as above.
+ face_.set_n(n + 1);
+ face_.set_face_id(0u);
+ }
+ else
+ invalidate();
+ }
+ }
+
+
+ /*-----------------------------.
+ | topo::complex_bkd_iter_<D>. |
+ `-----------------------------*/
+
+ template <unsigned D>
+ inline
+ complex_bkd_iter_<D>::complex_bkd_iter_()
+ : super_()
+ {
+ }
+
+ template <unsigned D>
+ inline
+ complex_bkd_iter_<D>::complex_bkd_iter_(complex<D>& c)
+ : super_(c)
+ {
+ set_cplx(c);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned D>
+ inline
+ void
+ complex_bkd_iter_<D>::start()
+ {
+ face_.set_n(D);
+ face_.set_face_id(face_.cplx().template nfaces<D>() - 1);
+ }
+
+ template <unsigned D>
+ inline
+ void
+ complex_bkd_iter_<D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned n = face_.n();
+ unsigned face_id = face_.face_id();
+
+ if (face_id > 0)
+ /* FIXME: Provide accessor any_face_handle::face_id() returning
+ a mutable reference? This way, we could just write
+
+ ++face_.face_id();
+
+ instead of the following.
+
+ Or add {inc,add}_face_id() services. */
+ face_.set_face_id(face_id - 1);
+ else
+ // Start to iterate on the faces of the previous dimension
+ // if it exists.
+ if (n > 0)
+ {
+ // FIXME: Same remark as above.
+ face_.set_n(n - 1);
+ face_.set_face_id(face_.cplx().nfaces(n - 1) - 1);
+ }
+ else
+ invalidate();
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_COMPLEX_ITER_HH
diff --git a/milena/mln/topo/face.hh b/milena/mln/topo/face.hh
new file mode 100644
index 0000000..11f22b2
--- /dev/null
+++ b/milena/mln/topo/face.hh
@@ -0,0 +1,733 @@
+// 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_HH
+# define MLN_TOPO_FACE_HH
+
+/// \file mln/topo/face.hh
+/// \brief Face of a complex.
+
+#include <limits>
+
+#include <vector>
+
+#include <mln/core/contract.hh>
+
+/* FIXME: Suggestions:
+
+ - rename `face' as `face_data', and move it into complex.hh or its
+ own file;
+ - rename `face_handle' as `face', and move it to its own file;
+ - rename `any_face_handle' as `any_face', and move it to its own file.
+
+ Anyway, whatever the decision, splitting `face', `face_handle' and
+ `any_face_handle' seems to be sound.
+
+ (And what about `faces_set'? Should we move it to its own file as
+ well?) */
+
+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 face_handle;
+ namespace internal
+ {
+ template <unsigned N, unsigned D> class lower_dim_faces_mixin;
+ template <unsigned N, unsigned D> class higher_dim_faces_mixin;
+ }
+
+
+ /*-------.
+ | Face. |
+ `-------*/
+
+ /// \p N-face of a \p D-complex.
+ template <unsigned N, unsigned D> class face;
+
+
+ // Specialization for the faces of highest dimension (\p D).
+ template <unsigned D>
+ class face<D, D> : public internal::lower_dim_faces_mixin<D, D>
+ {
+ };
+
+ // Specialization for the faces of intermediate dimension (greater
+ // than 0, lower than \p D).
+ template <unsigned N, unsigned D>
+ class face : public internal::lower_dim_faces_mixin<N, D>,
+ public internal::higher_dim_faces_mixin<N, D>
+ {
+ };
+
+ // Specialization for the faces of lowest dimension (0).
+ template <unsigned D>
+ class face<0u, D> : public internal::higher_dim_faces_mixin<0u, D>
+ {
+ };
+
+ // Specialization for the case of a 0-complex.
+ template <>
+ class face<0u, 0u>
+ {
+ };
+
+
+ namespace internal
+ {
+
+ /// Factored implementation of faces.
+ /// \{
+ template <unsigned N, unsigned D>
+ class lower_dim_faces_mixin
+ {
+ public:
+ void connect_lower_dim_face (const face_handle<N - 1, D>& f);
+ private:
+ friend class mln::topo::internal::lower_dim_faces_set_mixin<N, D>;
+ std::vector< face_handle<N - 1, D> > lower_dim_faces_;
+ };
+
+ template <unsigned N, unsigned D>
+ class higher_dim_faces_mixin
+ {
+ public:
+ void connect_higher_dim_face(const face_handle<N + 1, D>& f);
+ private:
+ friend class mln::topo::internal::higher_dim_faces_set_mixin<N, D>;
+ std::vector< face_handle<N + 1, D> > higher_dim_faces_;
+ };
+ /// \}
+
+ } // end of namespace mln::topo::internal
+
+
+
+ /*--------------.
+ | Face handle. |
+ `--------------*/
+
+ // Face handle in a complex.
+ template <unsigned N, unsigned D>
+ struct face_handle
+ {
+ // The type of the complex this handle points to.
+ typedef complex<D> complex_type;
+
+ /// Build a non-initialized face handle.
+ face_handle();
+ /// Build a face handle from \a complex and \a face_id.
+ face_handle(complex<D>& complex, unsigned face_id);
+
+ /// Copy and assignment.
+ /// \{
+ face_handle(const face_handle<N, D>& rhs);
+ face_handle<N, D>& operator=(const face_handle<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::face pointed by this handle.
+ face<N, D>& to_face() const;
+ /// \}
+
+ private:
+ /// \brief The complex the face belongs to.
+ ///
+ /// A const face_handle 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>
+ 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. |
+ `----------------------*/
+
+ /// \brief Set of face handles of dimension \p N.
+ template <unsigned N, unsigned D>
+ class faces_set
+ {
+ public:
+ void add(const face_handle<N, D>& f);
+
+ /// \brief Accessors.
+ ///
+ /// Return the set of handles.
+ /// \{
+ const std::vector< face_handle<N, D> >& faces() const;
+ /// \}
+
+ private:
+ friend class complex<D>;
+
+ // FIXME: Rename this as `handles_'?
+ std::vector< face_handle<N, D> > faces_;
+ };
+
+
+ /// Construction helpers for mln::faces_set.
+ /// \{
+ template <unsigned N, unsigned D>
+ faces_set<N, D>
+ operator+(const face_handle<N, D>& f1, const face_handle<N, D>&
f2);
+
+ template <unsigned N, unsigned D>
+ faces_set<N, D>
+ operator+(const faces_set<N, D>& fs, const face_handle<N, D>&
f);
+ /// \}
+
+
+ /*----------------------.
+ | ``Any-face'' handle. |
+ `----------------------*/
+
+ // Face handle in a complex, where the dimension is dynamic.
+ template <unsigned D>
+ struct any_face_handle
+ {
+ // The type of the complex this handle points to.
+ typedef complex<D> complex_type;
+
+ /// Build a non-initialized face handle.
+ any_face_handle();
+ /// Build a face handle from \a complex and \a face_id.
+ any_face_handle(complex<D>& complex, unsigned n, unsigned face_id);
+
+ /// Build a face handle from a face_handle.
+ template <unsigned N>
+ any_face_handle(const face_handle<N, D>& f);
+
+ /// Copy and assignment.
+ /// \{
+ any_face_handle(const any_face_handle<D>& rhs);
+ any_face_handle<D>& operator=(const any_face_handle<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 dimension of the face.
+ // FIXME: Rename as `dim'?
+ unsigned n() 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);
+ /// Set the dimension of the face.
+ void set_n(unsigned n);
+ /// Set the id of the face.
+ void set_face_id(unsigned face_id);
+
+ /// Return the mln::face pointed by this handle.
+ template <unsigned N>
+ face<N, D>& to_face() const;
+ /// \}
+
+ private:
+ /// \brief The complex the face belongs to.
+ ///
+ /// A const any_face_handle can be used to modify a complex.
+ mutable complex<D>* cplx_;
+ /// The dimension of the face.
+ // FIXME: Rename as `dim_'?
+ unsigned n_;
+ /// \brief The id of the face.
+ // FIXME: Rename as `id_'?
+ unsigned face_id_;
+ };
+
+
+ /// Comparison of two instances of mln::any_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 D>
+ bool
+ operator==(const any_face_handle<D>& lhs, const
any_face_handle<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.
+ /// \pre Arguments \a lhs and \a rhs must have the same dimension.
+ template <unsigned D>
+ bool
+ operator< (const any_face_handle<D>& lhs, const
any_face_handle<D>& rhs);
+ /// \}
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*--------.
+ | Faces. |
+ `--------*/
+
+ namespace internal
+ {
+ template <unsigned N, unsigned D>
+ inline
+ void
+ lower_dim_faces_mixin<N, D>::connect_lower_dim_face(const face_handle<N -
1, D>& f)
+ {
+ lower_dim_faces_.push_back(f);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ higher_dim_faces_mixin<N, D>::connect_higher_dim_face(const face_handle<N
+ 1, D>& f)
+ {
+ higher_dim_faces_.push_back(f);
+ }
+
+ } // end of namespace mln::topo::internal
+
+
+ /*--------------.
+ | Face handle. |
+ `--------------*/
+
+ template <unsigned N, unsigned D>
+ inline
+ face_handle<N, D>::face_handle()
+ : 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
+ face_handle<N, D>::face_handle(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
+ face_handle<N, D>::face_handle(const face_handle<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
+ face_handle<N, D>&
+ face_handle<N, D>::operator=(const face_handle<N, D>& rhs)
+ {
+ if (&rhs != this)
+ {
+ cplx_ = rhs.cplx_;
+ face_id_ = rhs.face_id_;
+ }
+ return *this;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ bool
+ face_handle<N, D>::is_valid() const
+ {
+ return cplx_ != 0 && face_id_ < cplx_->template nfaces<N>();
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ face_handle<N, D>::invalidate()
+ {
+ set_face_id(std::numeric_limits<unsigned>::max());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ complex<D>&
+ face_handle<N, D>::cplx() const
+ {
+ mln_precondition(cplx_);
+ return *cplx_;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ unsigned
+ face_handle<N, D>::n() const
+ {
+ return N;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ unsigned
+ face_handle<N, D>::face_id() const
+ {
+ return face_id_;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ face_handle<N, D>::set_cplx(complex<D>& cplx)
+ {
+ cplx_ = &cplx;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ face_handle<N, D>::set_face_id(unsigned face_id)
+ {
+ face_id_ = face_id;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ face<N, D>&
+ face_handle<N, D>::to_face() const
+ {
+ mln_precondition(is_valid());
+ return cplx_->template face_<N>(face_id_);
+ }
+
+
+ template <unsigned N, unsigned D>
+ inline
+ face_handle<N, D>
+ make_face_handle(const complex<D>& c, unsigned face_id)
+ {
+ return face_handle<N, D>(&c, face_id);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ bool
+ operator==(const face_handle<N, D>& lhs, const face_handle<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 face_handle<N, D>& lhs, const face_handle<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
+ faces_set<N, D>::add(const face_handle<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< face_handle<N, D> >&
+ faces_set<N, D>::faces() const
+ {
+ return faces_;
+ }
+
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_set<N, D>
+ operator+(const face_handle<N, D>& f1, const face_handle<N, D>&
f2)
+ {
+ faces_set<N, D> fs;
+ fs.add(f1);
+ fs.add(f2);
+ return fs;
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_set<N, D>
+ operator+(const faces_set<N, D>& fs, const face_handle<N, D>& f)
+ {
+ faces_set<N, D> fs2(fs);
+ fs2.add(f);
+ return fs2;
+ }
+
+
+ /*----------------------.
+ | ``Any-face'' handle. |
+ `----------------------*/
+
+ template <unsigned D>
+ inline
+ any_face_handle<D>::any_face_handle()
+ : cplx_(0),
+ n_(std::numeric_limits<unsigned>::max()),
+ face_id_(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+ template <unsigned D>
+ inline
+ any_face_handle<D>::any_face_handle(complex<D>& c, unsigned n,
+ unsigned face_id)
+ : cplx_(&c), n_(n), face_id_(face_id)
+ {
+ // Ensure N is compatible with D.
+ mln_precondition(n <= D);
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ inline
+ any_face_handle<D>::any_face_handle(const face_handle<N, D>& f)
+ : cplx_(&f.cplx()), n_(N), face_id_(f.face_id())
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+
+ }
+
+ template <unsigned D>
+ inline
+ any_face_handle<D>::any_face_handle(const any_face_handle<D>& rhs)
+ : cplx_(rhs.cplx_), n_(rhs.n_), face_id_(rhs.face_id_)
+ {
+ }
+
+ template <unsigned D>
+ inline
+ any_face_handle<D>&
+ any_face_handle<D>::operator=(const any_face_handle<D>& rhs)
+ {
+ if (&rhs != this)
+ {
+ cplx_ = rhs.cplx_;
+ n_ = rhs.n_;
+ face_id_ = rhs.face_id_;
+ }
+ return *this;
+ }
+
+ template <unsigned D>
+ inline
+ bool
+ any_face_handle<D>::is_valid() const
+ {
+ return cplx_ != 0 && n_ <= D && face_id_ <
cplx_->nfaces(n_);
+ }
+
+ template <unsigned D>
+ inline
+ void
+ any_face_handle<D>::invalidate()
+ {
+ set_n(std::numeric_limits<unsigned>::max());
+ set_face_id(std::numeric_limits<unsigned>::max());
+ }
+
+ template <unsigned D>
+ inline
+ complex<D>&
+ any_face_handle<D>::cplx() const
+ {
+ mln_precondition(cplx_);
+ return *cplx_;
+ }
+
+ template <unsigned D>
+ inline
+ unsigned
+ any_face_handle<D>::n() const
+ {
+ return n_;
+ }
+
+ template <unsigned D>
+ inline
+ unsigned
+ any_face_handle<D>::face_id() const
+ {
+ return face_id_;
+ }
+
+ template <unsigned D>
+ inline
+ void
+ any_face_handle<D>::set_cplx(complex<D>& cplx)
+ {
+ cplx_ = &cplx;
+ }
+
+ template <unsigned D>
+ inline
+ void
+ any_face_handle<D>::set_n(unsigned n)
+ {
+ n_ = n;
+ }
+
+ template <unsigned D>
+ inline
+ void
+ any_face_handle<D>::set_face_id(unsigned face_id)
+ {
+ face_id_ = face_id;
+ }
+
+ template <unsigned D>
+ template <unsigned N>
+ inline
+ face<N, D>&
+ any_face_handle<D>::to_face() const
+ {
+ mln_precondition(n_ == N);
+ mln_precondition(is_valid());
+ return cplx_->template face_<N>(face_id_);
+ }
+
+
+ template <unsigned D>
+ inline
+ bool
+ operator==(const any_face_handle<D>& lhs, const
any_face_handle<D>& rhs)
+ {
+ // Ensure LHS and RHS belong to the same complex.
+ mln_precondition(&lhs.face.cplx() == &rhs.face.cplx());
+ return
+ lhs.face().n() == rhs.face().n() &&
+ lhs.face().id() == rhs.face().id();
+ }
+
+ template <unsigned D>
+ inline
+ bool
+ operator< (const any_face_handle<D>& lhs, const
any_face_handle<D>& rhs)
+ {
+ // Ensure LHS and RHS belong to the same complex.
+ mln_precondition(&lhs.face.cplx() == &rhs.face.cplx());
+ // Ensure LHS and RHS have the same dimension.
+ mln_precondition(lhs.face().n() == rhs.face().n());
+ return lhs.face().id() < rhs.face().id();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_FACE_HH
diff --git a/milena/mln/topo/faces_iter.hh b/milena/mln/topo/faces_iter.hh
new file mode 100644
index 0000000..8f444c7
--- /dev/null
+++ b/milena/mln/topo/faces_iter.hh
@@ -0,0 +1,251 @@
+// 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_FACES_ITER_HH
+# define MLN_TOPO_FACES_ITER_HH
+
+/// \file mln/topo/faces_iter.hh
+/// \brief Definition of forward and backward iterators on the n-faces
+/// of a complex.
+
+# include <mln/topo/internal/complex_iter_base.hh>
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ /*------------------------------.
+ | topo::faces_fwd_iter_<N, D>. |
+ `------------------------------*/
+
+ /// \brief Forward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p N The dimension of the face associated to this iterator.
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned N, unsigned D>
+ class faces_fwd_iter_
+ : public internal::complex_iter_base_< face_handle<N, D>,
+ faces_fwd_iter_<N, D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef face_handle<N, D> face;
+
+ private:
+ typedef faces_fwd_iter_<N, D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ faces_fwd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ faces_fwd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+ /*------------------------------.
+ | topo::faces_bkd_iter_<N, D>. |
+ `------------------------------*/
+
+ /// \brief Backward iterator on all the faces of a mln::complex<D>.
+ ///
+ /// \arg \p N The dimension of the face associated to this iterator.
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned N, unsigned D>
+ class faces_bkd_iter_
+ : public internal::complex_iter_base_< face_handle<N, D>,
+ faces_bkd_iter_<N, D> >
+ {
+ public:
+ /// Type of associated face.
+ typedef face_handle<N, D> face;
+
+ private:
+ typedef faces_bkd_iter_<N, D> self_;
+ typedef internal::complex_iter_base_< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ faces_bkd_iter_();
+ // FIXME: See comment in internal::complex_iter_base_'s default ctor
+ faces_bkd_iter_(complex<D>& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Start an iteration.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*------------------------------.
+ | topo::faces_fwd_iter_<N, D>. |
+ `------------------------------*/
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_fwd_iter_<N, D>::faces_fwd_iter_()
+ : super_()
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_fwd_iter_<N, D>::faces_fwd_iter_(complex<D>& c)
+ : super_(c)
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ faces_fwd_iter_<N, D>::start()
+ {
+ face_.set_face_id(0u);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ faces_fwd_iter_<N, D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ if (face_id + 1 < face_.cplx().template nfaces<N>())
+ /* FIXME: Provide accessor face_handle::n() returning
+ a mutable reference? This way, we could just write
+
+ ++face_.face_id();
+
+ instead of the following. */
+ face_.set_face_id(face_id + 1);
+ else
+ invalidate();
+ }
+ }
+
+
+ /*------------------------------.
+ | topo::faces_bkd_iter_<N, D>. |
+ `------------------------------*/
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_bkd_iter_<N, D>::faces_bkd_iter_()
+ : super_()
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ faces_bkd_iter_<N, D>::faces_bkd_iter_(complex<D>& c)
+ : super_(c)
+ {
+ // Ensure N is compatible with D.
+ metal::bool_< N <= D >::check();
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ faces_bkd_iter_<N, D>::start()
+ {
+ face_.set_face_id(face_.cplx().template nfaces<N>() - 1);
+ }
+
+ template <unsigned N, unsigned D>
+ inline
+ void
+ faces_bkd_iter_<N, D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ if (face_id > 0)
+ /* FIXME: Provide accessor face_handle::n() returning
+ a mutable reference? This way, we could just write
+
+ ++face_.face_id();
+
+ instead of the following. */
+ face_.set_face_id(face_id - 1);
+ else
+ invalidate();
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_FACES_ITER_HH
diff --git a/milena/mln/topo/internal/complex_iter_base.hh
b/milena/mln/topo/internal/complex_iter_base.hh
new file mode 100644
index 0000000..d371372
--- /dev/null
+++ b/milena/mln/topo/internal/complex_iter_base.hh
@@ -0,0 +1,208 @@
+// 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_INTERNAL_COMPLEX_ITER_BASE_HH
+# define MLN_TOPO_INTERNAL_COMPLEX_ITER_BASE_HH
+
+/// \file mln/topo/internal/complex_iter_base.hh
+/// \brief Definition of an implementation (factoring) class for
+/// iterators on mln::complex.
+
+# include <limits>
+
+# include <mln/metal/equal.hh>
+
+# include <mln/core/concept/iterator.hh>
+# include <mln/topo/complex.hh>
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ namespace internal
+ {
+ /// \brief Factoring class for iterators on mln::complex.
+ ///
+ /// \arg \p F The type of the face handle.
+ /// \arg \p E The type exact type of the iterator.
+ template <typename F, typename E>
+ class complex_iter_base_ : public Iterator<E>
+ {
+ typedef complex_iter_base_<F, E> self_;
+
+ public:
+ typedef F face;
+ // FIXME: Maybe we could just get the dimension D of the face's
+ // complex, an define complex_type as mln::complex<D>?
+ typedef typename F::complex_type complex_type;
+
+ /// Construction and assignment.
+ /// \{
+ /* FIXME: Keep this non-const? See a (big) comment about this in
+ milena/tests/complex_image.cc. */
+ complex_iter_base_();
+ complex_iter_base_(complex_type& c);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Change the target complex.
+ // FIXME: Same comment as the ctor above.
+ void set_cplx(complex_type& c);
+
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+ /// Invalidate the iterator.
+ void invalidate();
+ /// \}
+
+ /// Conversion and accessors.
+ /// \{
+ /// Reference to the corresponding face handle.
+ const face& to_face () const;
+ /// Convert the iterator into an face handle.
+ operator face() const;
+ /// \}
+
+ protected:
+ /// The face handle this iterator is pointing to.
+ face face_;
+ };
+
+
+ /* FIXME: This hand-made delegation is painful. We should rely on
+ the general mechanism provided by Point_Site. But then again, we
+ need to refine/adjust the interface of Point_Site w.r.t. the
+ mandatory conversions to points. */
+ template <typename F, typename E>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const complex_iter_base_<F, E>&
p);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename F, typename E>
+ inline
+ complex_iter_base_<F, E>::complex_iter_base_()
+ {
+ // Ensure F and E are compatible.
+ mlc_equal(F, typename E::face)::check();
+
+ invalidate();
+ }
+
+ template <typename F, typename E>
+ inline
+ complex_iter_base_<F, E>::complex_iter_base_(complex_type& c)
+ {
+ // Ensure F and E are compatible.
+ mlc_equal(F, typename E::face)::check();
+
+ face_.set_cplx(c);
+ // Invalidate face_.
+ invalidate();
+ }
+
+ template <typename F, typename E>
+ inline
+ void
+ complex_iter_base_<F, E>::set_cplx(complex_type& c)
+ {
+ face_.set_cplx(c);
+ // Invalidate face_.
+ invalidate();
+ }
+
+ template <typename F, typename E>
+ inline
+ bool
+ complex_iter_base_<F, E>::is_valid() const
+ {
+ return face_.is_valid();
+ }
+
+ template <typename F, typename E>
+ inline
+ void
+ complex_iter_base_<F, E>::invalidate()
+ {
+ face_.invalidate();
+ }
+
+ template <typename F, typename E>
+ inline
+ const F&
+ complex_iter_base_<F, E>::to_face() const
+ {
+ return face_;
+ }
+
+ template <typename F, typename E>
+ inline
+ complex_iter_base_<F, E>::operator F() const
+ {
+ mln_precondition(is_valid());
+ return face_;
+ }
+
+
+ template <typename F, typename E>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const complex_iter_base_<F, E>&
p)
+ {
+ /* FIXME: We should use p.to_face() here, but as it lacks the
+ precondition the conversion operator has, so we use the latter.
+
+ We should
+ - rename `to_face' as `to_face_';
+ - write a new `to_face' routine checking the validity of the
+ iterator;
+ - have the conversion operator to face use this new `to_face'
+ routine;
+ - adjust former clients of `to_face'
+
+ This is a general remark that applies to all iterators of
+ Milena. */
+ F f = p;
+ return ostr << "(dim = " << f.n() << ", id = "
<< f.face_id() << ')';
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo::internal
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_INTERNAL_COMPLEX_ITER_BASE_HH
diff --git a/milena/tests/Makefile.am b/milena/tests/Makefile.am
index a26dd92..a6ec1dc 100644
--- a/milena/tests/Makefile.am
+++ b/milena/tests/Makefile.am
@@ -35,6 +35,7 @@ SUBDIRS = \
subsampling \
tag \
test \
+ topo \
trace \
trait \
util \
diff --git a/milena/tests/core/other/Makefile.am b/milena/tests/core/other/Makefile.am
index 4ecef66..f0e5fdf 100644
--- a/milena/tests/core/other/Makefile.am
+++ b/milena/tests/core/other/Makefile.am
@@ -7,7 +7,6 @@ check_PROGRAMS = \
category \
clock_neighb2d \
clock_test \
- complex \
dpoints_pixter \
graph_elt_neighborhood \
graph_elt_window \
@@ -27,7 +26,6 @@ box_runstart_piter_SOURCES = box_runstart_piter.cc
category_SOURCES = category.cc
clock_neighb2d_SOURCES = clock_neighb2d.cc
clock_test_SOURCES = clock_test.cc
-complex_SOURCES = complex.cc
dpoints_pixter_SOURCES = dpoints_pixter.cc
graph_elt_neighborhood_SOURCES = graph_elt_neighborhood.cc
graph_elt_window_SOURCES = graph_elt_window.cc
diff --git a/milena/tests/topo/Makefile.am b/milena/tests/topo/Makefile.am
new file mode 100644
index 0000000..d6258d8
--- /dev/null
+++ b/milena/tests/topo/Makefile.am
@@ -0,0 +1,10 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ complex
+
+complex_SOURCES = complex.cc
+
+TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/core/other/complex.cc b/milena/tests/topo/complex.cc
similarity index 79%
rename from milena/tests/core/other/complex.cc
rename to milena/tests/topo/complex.cc
index a131f63..08be130 100644
--- a/milena/tests/core/other/complex.cc
+++ b/milena/tests/topo/complex.cc
@@ -25,19 +25,19 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/core/other/complex.cc
+/// \file tests/topo/complex.cc
/// \brief Test of mln::complex.
#include <iostream>
-#include <mln/core/complex.hh>
+#include <mln/topo/complex.hh>
using namespace mln;
// Forward declaration.
-template <unsigned N, unsigned D> void test_faces_iter(complex<D>& c);
-template <unsigned N, unsigned D> void
test_complex_faces_iter(complex<D>& c);
+template <unsigned N, unsigned D> void test_faces_iter(topo::complex<D>&
c);
+template <unsigned N, unsigned D> void
test_complex_faces_iter(topo::complex<D>& c);
int main()
@@ -66,24 +66,24 @@ int main()
| Complex construction. |
`-----------------------*/
- complex<D> c;
+ topo::complex<D> c;
// 0-faces (points).
- face_handle<0, D> v0 = c.add_face();
- face_handle<0, D> v1 = c.add_face();
- face_handle<0, D> v2 = c.add_face();
- face_handle<0, D> v3 = c.add_face();
+ topo::face_handle<0, D> v0 = c.add_face();
+ topo::face_handle<0, D> v1 = c.add_face();
+ topo::face_handle<0, D> v2 = c.add_face();
+ topo::face_handle<0, D> v3 = c.add_face();
// 1-faces (segments).
- face_handle<1, D> e0 = c.add_face(v0 + v1);
- face_handle<1, D> e1 = c.add_face(v0 + v2);
- face_handle<1, D> e2 = c.add_face(v1 + v2);
- face_handle<1, D> e3 = c.add_face(v0 + v3);
- face_handle<1, D> e4 = c.add_face(v2 + v3);
+ topo::face_handle<1, D> e0 = c.add_face(v0 + v1);
+ topo::face_handle<1, D> e1 = c.add_face(v0 + v2);
+ topo::face_handle<1, D> e2 = c.add_face(v1 + v2);
+ topo::face_handle<1, D> e3 = c.add_face(v0 + v3);
+ topo::face_handle<1, D> e4 = c.add_face(v2 + v3);
// 2-faces (triangles).
- face_handle<2, D> t0 = c.add_face(e0 + e1 + e2);
- face_handle<2, D> t1 = c.add_face(e1 + e3 + e4);
+ topo::face_handle<2, D> t0 = c.add_face(e0 + e1 + e2);
+ topo::face_handle<2, D> t1 = c.add_face(e1 + e3 + e4);
std::cout << c << std::endl;
@@ -107,12 +107,12 @@ int main()
`-------------------*/
// Get the face data from (``static'') face handle E0.
- const face<1, D>& face1 = e0.to_face();
+ const topo::face<1, D>& face1 = e0.to_face();
// Any-face handle.
- any_face_handle<D> af(e0);
+ topo::any_face_handle<D> af(e0);
// Get the face data from (``dynamic'') face handle AF.
- const face<1, D>& face2 = af.to_face<1>();
+ const topo::face<1, D>& face2 = af.to_face<1>();
mln_assertion(&face1 == &face2);
@@ -128,8 +128,8 @@ int main()
// Iterators on a complex (not complex_image), or more precisely on
// (all) the faces of complex C.
- mln_fwd_citer_(complex<D>) fwd_f(c);
- mln_bkd_citer_(complex<D>) bkd_f(c);
+ mln_fwd_citer_(topo::complex<D>) fwd_f(c);
+ mln_bkd_citer_(topo::complex<D>) bkd_f(c);
for_all_2(fwd_f, bkd_f)
std::cout << fwd_f << ' ' << bkd_f << std::endl;
std::cout << std::endl;
@@ -165,12 +165,12 @@ int main()
template <unsigned N, unsigned D>
void
-test_faces_iter(complex<D>& c)
+test_faces_iter(topo::complex<D>& c)
{
std::cout << "test_faces_iter<" << N << ", "
<< D << ">:"
<< std::endl;
- mln_fwd_fiter(N, complex<D>) fwd_nf(c);
- mln_bkd_fiter(N, complex<D>) bkd_nf(c);
+ mln_fwd_fiter(N, topo::complex<D>) fwd_nf(c);
+ mln_bkd_fiter(N, topo::complex<D>) bkd_nf(c);
for_all_2(fwd_nf, bkd_nf)
std::cout << fwd_nf << ' ' << bkd_nf << std::endl;
std::cout << std::endl;
@@ -178,15 +178,15 @@ test_faces_iter(complex<D>& c)
template <unsigned N, unsigned D>
void
-test_complex_faces_iter(complex<D>& c)
+test_complex_faces_iter(topo::complex<D>& c)
{
std::cout << "test_complex_faces_iter<" << N << ",
" << D << ">:"
<< std::endl;
/* FIXME: Provide sugar. Maybe redefined mln_fwd_fiter and
mln_bkd_fiter so that they expand as complex_faces_iters (instead
of faces_iters). */
- complex_faces_fwd_iter_<N, D> fwd_ncf(c);
- complex_faces_bkd_iter_<N, D> bkd_ncf(c);
+ topo::complex_faces_fwd_iter_<N, D> fwd_ncf(c);
+ topo::complex_faces_bkd_iter_<N, D> bkd_ncf(c);
for_all_2(fwd_ncf, bkd_ncf)
std::cout << fwd_ncf << ' ' << bkd_ncf << std::endl;
std::cout << std::endl;
--
1.6.0.1