* mln/topo/n_face_iter.hh: New.
* mln/topo/complex.hh: Include mln/topo/n_face_iter.hh.
* tests/topo/complex.cc: Exercise n_face_fwd_iter and
n_face_bkd_iter.
---
milena/ChangeLog | 9 ++
milena/mln/topo/complex.hh | 1 +
milena/mln/topo/n_face_iter.hh | 311 ++++++++++++++++++++++++++++++++++++++++
milena/tests/topo/complex.cc | 33 +++--
4 files changed, 345 insertions(+), 9 deletions(-)
create mode 100644 milena/mln/topo/n_face_iter.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 4d9412b..d5309e4 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2008-09-26 Roland Levillain <roland(a)lrde.epita.fr>
+ Add iterators on n-faces (with a dynamically known `n').
+
+ * mln/topo/n_face_iter.hh: New.
+ * mln/topo/complex.hh: Include mln/topo/n_face_iter.hh.
+ * tests/topo/complex.cc: Exercise n_face_fwd_iter and
+ n_face_bkd_iter.
+
+2008-09-26 Roland Levillain <roland(a)lrde.epita.fr>
+
Revive iterators on n-faces (with a statically known `n').
* mln/topo/attic/complex_faces_iter.hh: Rename as...
diff --git a/milena/mln/topo/complex.hh b/milena/mln/topo/complex.hh
index 61ce84b..13e21d0 100644
--- a/milena/mln/topo/complex.hh
+++ b/milena/mln/topo/complex.hh
@@ -49,6 +49,7 @@
# include <mln/topo/n_faces_set.hh>
# include <mln/topo/face_iter.hh>
+# include <mln/topo/n_face_iter.hh>
# include <mln/topo/static_n_face_iter.hh>
// FIXME: Disabled (moved to the attic).
# if 0
diff --git a/milena/mln/topo/n_face_iter.hh b/milena/mln/topo/n_face_iter.hh
new file mode 100644
index 0000000..1156707
--- /dev/null
+++ b/milena/mln/topo/n_face_iter.hh
@@ -0,0 +1,311 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_TOPO_N_FACE_ITER_HH
+# define MLN_TOPO_N_FACE_ITER_HH
+
+/// \file mln/topo/n_face_iter.hh
+/// \brief Definition of forward and backward iterators on all the
+/// \a n-faces of a complex, \a n being a dynamic value.
+
+# include <mln/topo/internal/complex_iter_base.hh>
+# include <mln/topo/face.hh>
+
+// FIXME: Factor a bit more? (Using complex_iter_base.)
+
+// FIXME: Rename the old commplex_faces_{fwd,bkd}_iter as
+// static_n_face_{fwd,bkd}_iter.
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ // Forward declaration.
+ template <unsigned D> class complex;
+
+
+ /*---------------------------.
+ | topo::n_face_fwd_iter<D>. |
+ `---------------------------*/
+
+ /// \brief Forward iterator on all the faces of an mln::complex<D>.
+ ///
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned D>
+ class n_face_fwd_iter
+ : public internal::complex_iter_base< face<D>, n_face_fwd_iter<D>
>
+ {
+ public:
+ /// Type of associated face.
+ typedef face<D> face;
+
+ private:
+ typedef n_face_fwd_iter<D> self_;
+ typedef internal::complex_iter_base< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ n_face_fwd_iter();
+ // FIXME: See comment in internal::complex_iter_base's default ctor
+ n_face_fwd_iter(complex<D>& c, unsigned n);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ /// \brief Accessors.
+ ///
+ /// Shortcuts to face_'s accessors.
+ /// \{
+ unsigned n() const;
+ void set_n (unsigned n);
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+ /*---------------------------.
+ | topo::n_face_bkd_iter<D>. |
+ `---------------------------*/
+
+ /// \brief Backward iterator on all the faces of an mln::complex<D>.
+ ///
+ /// \arg \p D The dimension of the complex this iterator belongs to.
+ template <unsigned D>
+ class n_face_bkd_iter
+ : public internal::complex_iter_base< face<D>, n_face_bkd_iter<D>
>
+ {
+ public:
+ /// Type of associated face.
+ typedef face<D> face;
+
+ private:
+ typedef n_face_bkd_iter<D> self_;
+ typedef internal::complex_iter_base< face, self_ > super_;
+
+ public:
+ using super_::is_valid;
+ using super_::invalidate;
+
+ public:
+ /// Construction and assignment.
+ /// \{
+ n_face_bkd_iter();
+ // FIXME: See comment in internal::complex_iter_base's default ctor
+ n_face_bkd_iter(complex<D>& c, unsigned n);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Start an iteration.
+ void start();
+ /// Go to the next point.
+ void next_();
+ /// \}
+
+ /// \brief Accessors.
+ ///
+ /// Shortcuts to face_'s accessors.
+ /// \{
+ unsigned n() const;
+ void set_n (unsigned n);
+ /// \}
+
+ private:
+ using super_::face_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*---------------------------.
+ | topo::n_face_fwd_iter<D>. |
+ `---------------------------*/
+
+ template <unsigned D>
+ inline
+ n_face_fwd_iter<D>::n_face_fwd_iter()
+ : super_()
+ {
+ }
+
+ template <unsigned D>
+ inline
+ n_face_fwd_iter<D>::n_face_fwd_iter(complex<D>& c, unsigned n)
+ : super_(c)
+ {
+ mln_precondition(n <= D);
+ set_cplx(c);
+ set_n(n);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_fwd_iter<D>::start()
+ {
+ face_.set_face_id(0u);
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_fwd_iter<D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ // The number of faces of dimension N in cplx_.
+ unsigned nn_faces = face_.cplx().nfaces(n());
+ if (face_id + 1 < nn_faces)
+ /* FIXME: Provide accessor face::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();
+ }
+ }
+
+ template <unsigned D>
+ inline
+ unsigned
+ n_face_fwd_iter<D>::n() const
+ {
+ return face_.n();
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_fwd_iter<D>::set_n(unsigned n)
+ {
+ mln_precondition(n <= D);
+ face_.set_n(n);
+ }
+
+
+ /*---------------------------.
+ | topo::n_face_bkd_iter<D>. |
+ `---------------------------*/
+
+ template <unsigned D>
+ inline
+ n_face_bkd_iter<D>::n_face_bkd_iter()
+ : super_()
+ {
+ }
+
+ template <unsigned D>
+ inline
+ n_face_bkd_iter<D>::n_face_bkd_iter(complex<D>& c, unsigned n)
+ : super_(c)
+ {
+ mln_precondition(n <= D);
+ set_cplx(c);
+ set_n(n);
+ mln_postcondition(!is_valid());
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_bkd_iter<D>::start()
+ {
+ face_.set_n(n());
+ face_.set_face_id(face_.cplx().nfaces(n()) - 1);
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_bkd_iter<D>::next_()
+ {
+ if (is_valid())
+ {
+ unsigned face_id = face_.face_id();
+ if (face_id > 0)
+ /* FIXME: Provide accessor face::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();
+ }
+ }
+
+ template <unsigned D>
+ inline
+ unsigned
+ n_face_bkd_iter<D>::n() const
+ {
+ return face_.n();
+ }
+
+ template <unsigned D>
+ inline
+ void
+ n_face_bkd_iter<D>::set_n(unsigned n)
+ {
+ mln_precondition(n <= D);
+ face_.set_n(n);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_N_FACE_ITER_HH
diff --git a/milena/tests/topo/complex.cc b/milena/tests/topo/complex.cc
index 4d220e7..16099f5 100644
--- a/milena/tests/topo/complex.cc
+++ b/milena/tests/topo/complex.cc
@@ -148,6 +148,18 @@ int main()
actual complex processing since they are not really flexible ---
but I'm not sure. */
+ // Dynamic version.
+ for (unsigned n = 0; n <= D; ++n)
+ {
+ topo::n_face_fwd_iter<D> fwd_nf(c, n);
+ topo::n_face_fwd_iter<D> bkd_nf(c, n);
+ std::cout << "test (dynamic) n_face_iters (n = " << n
<< "):"
+ << std::endl;
+ for_all_2(fwd_nf, bkd_nf)
+ std::cout << fwd_nf << ' ' << bkd_nf << std::endl;
+ std::cout << std::endl;
+ }
+
// Static version.
test_static_n_face_iter<0>(c);
test_static_n_face_iter<1>(c);
@@ -200,15 +212,21 @@ int main()
-----------------------------------------------------------------
Name Definition
-----------------------------------------------------------------
- complex<D> General complex
+ complex<D> General complex.
- face_data<N, D> Face data
- n_face<N, D> (Static) n-face handle
- n_faces_set<N, D> Set of face handles
- face<D> Dynamic face handle
+ face_data<N, D> Face data.
+ n_face<N, D> (Static) n-face handle.
+ n_faces_set<N, D> Set of face handles.
+ face<D> Dynamic face handle.
face_fwd_iter<D>(c) | Iterators on all the faces
- face_bkd_iter<D>(c) | of c
+ face_bkd_iter<D>(c) | of c.
+
+ n_face_fwd_iter<D>(c) | Iterators on n-faces,
+ n_face_bkd_iter<D>(c) | n being dynamic.
+
+ static_n_face_fwd_iter<D>(c) | Iterators on n-faces,
+ static_n_face_bkd_iter<D>(c) | n being static.
internal::complex_iter_base<F, E> Factoring base class.
-----------------------------------------------------------------
@@ -224,9 +242,6 @@ int main()
-----------------------------------------------------------------
Name Definition
-----------------------------------------------------------------
- n_faces_fwd_iter<D>(c) | Iterators on n-faces,
- n_faces_bkd_iter<D>(c) | n being dynamic
-
adj_lower_faces_fwd_iter<D>(c, f) | Iterators on the adjacent
adj_lower_faces_bkd_iter<D>(c, f) | (lower) (n-1)-faces of the
| n-face f of the complex c,
--
1.6.0.1