
* 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@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@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