* mln/core/image/complex_neighborhood_piter.hh New.
* tests/core/image/complex_image.cc: Exercise these iterators as
well as lower- and higher-dimension complex neighborhoods.
---
milena/ChangeLog | 8 +
.../mln/core/image/complex_neighborhood_piter.hh | 356 ++++++++++++++++++++
milena/tests/core/image/complex_image.cc | 49 +++
3 files changed, 413 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/core/image/complex_neighborhood_piter.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index be5fc43..ff4f385 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
2008-10-01 Roland Levillain <roland(a)lrde.epita.fr>
+ Add iterators on complex neighborhood.
+
+ * mln/core/image/complex_neighborhood_piter.hh New.
+ * tests/core/image/complex_image.cc: Exercise these iterators as
+ well as lower- and higher-dimension complex neighborhoods.
+
+2008-10-01 Roland Levillain <roland(a)lrde.epita.fr>
+
Add neighborhoods of lower- and higher-dimension adjacent faces.
* mln/core/image/complex_lower_neighborhood.hh,
diff --git a/milena/mln/core/image/complex_neighborhood_piter.hh
b/milena/mln/core/image/complex_neighborhood_piter.hh
new file mode 100644
index 0000000..ff06cd0
--- /dev/null
+++ b/milena/mln/core/image/complex_neighborhood_piter.hh
@@ -0,0 +1,356 @@
+// 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH
+# define MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH
+
+/// \file mln/core/image/complex_neighborhood_piter.hh
+/// \brief Definition of a site iterator on a complex neighborhood.
+
+# include <mln/core/internal/site_relative_iterator_base.hh>
+
+// FIXME: These might be factor-able.
+
+/* FIXME: Do we really want to inherit from
+ internal::site_relative_iterator_base? I might duplicate things,
+ since most of the implementation of this iterator is delegated to
+ the underlying complex iter. Moreover, change_target_() is
+ useless, and center_at() ``hides'' an existing method in (one of)
+ the super class(es) which is not sound, IMHO. Think about
+ introducing base class replacement. */
+
+
+namespace mln
+{
+
+ /*------------------------------------------.
+ | complex_neighborhood_fwd_piter<I, P, N>. |
+ `------------------------------------------*/
+
+ /// \brief Forward iterator on complex neighborhood.
+ template <typename I, typename P, typename N>
+ class complex_neighborhood_fwd_piter
+ : public internal::site_relative_iterator_base< N,
+ complex_neighborhood_fwd_piter<I, P, N> >
+ {
+ typedef complex_neighborhood_fwd_piter<I, P, N> self_;
+ typedef internal::site_relative_iterator_base< N, self_ > super_;
+
+ public:
+ /// The Point_Site type.
+ typedef mln_psite(N) psite;
+
+ // FIXME: Dummy typedef.
+// typedef void dpoint;
+ // FIXME: Dummy typedef.
+// typedef void mesh;
+
+ public:
+ /// Construction.
+ /// \{
+ complex_neighborhood_fwd_piter();
+ template <typename Pref>
+ complex_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
+ const Pref& p_ref);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void do_start_();
+ /// Go to the next point.
+ void do_next_();
+
+ /// Set the reference psite.
+ /* FIXME: Careful, this method overrides the (non virtual) method
+ internal::site_relative_iterator_base<S, E>::center_at. See
+ FIXME above. */
+ template <typename Pref>
+ void center_at(const Pref& c);
+ /// Compute the current psite.
+ psite compute_p_() const;
+ /// \}
+
+ private:
+ /// The type of the underlying complex iterator.
+ typedef typename N::complex_fwd_iter iter;
+ /// The underlying complex iterator.
+ iter iter_;
+ };
+
+
+ /// Print an mln::complex_neighborhood_fwd_piter.
+ template <typename I, typename P, typename N>
+ std::ostream&
+ operator<<(std::ostream& ostr,
+ const complex_neighborhood_fwd_piter<I, P, N>& p);
+
+
+ /*------------------------------------------.
+ | complex_neighborhood_bkd_piter<I, P, N>. |
+ `------------------------------------------*/
+
+ /// \brief Backward iterator on complex neighborhood.
+ template <typename I, typename P, typename N>
+ class complex_neighborhood_bkd_piter
+ : public internal::site_relative_iterator_base< N,
+ complex_neighborhood_bkd_piter<I, P, N> >
+ {
+ typedef complex_neighborhood_bkd_piter<I, P, N> self_;
+ typedef internal::site_relative_iterator_base< N, self_ > super_;
+
+ public:
+ /// The Point_Site type.
+ typedef mln_psite(N) psite;
+
+ // FIXME: Dummy typedef.
+// typedef void dpoint;
+ // FIXME: Dummy typedef.
+// typedef void mesh;
+
+ public:
+ /// Construction.
+ /// \{
+ complex_neighborhood_bkd_piter();
+ template <typename Pref>
+ complex_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
+ const Pref& p_ref);
+ /// \}
+
+ /// Manipulation.
+ /// \{
+ /// Test if the iterator is valid.
+ bool is_valid_() const;
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void do_start_();
+ /// Go to the next point.
+ void do_next_();
+
+ /// Set the reference psite.
+ /* FIXME: Careful, this method overrides the (non virtual) method
+ internal::site_relative_iterator_base<S, E>::center_at. See
+ FIXME above. */
+ template <typename Pref>
+ void center_at(const Pref& c);
+ /// Compute the current psite.
+ psite compute_p_() const;
+ /// \}
+
+ private:
+ /// The type of the underlying complex iterator.
+ typedef typename N::complex_fwd_iter iter;
+ /// The underlying complex iterator.
+ iter iter_;
+ };
+
+
+ /// Print an mln::complex_neighborhood_bkd_piter.
+ template <typename I, typename P, typename N>
+ std::ostream&
+ operator<<(std::ostream& ostr,
+ const complex_neighborhood_bkd_piter<I, P, N>& p);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*------------------------------------------.
+ | complex_neighborhood_fwd_piter<I, P, N>. |
+ `------------------------------------------*/
+
+ template <typename I, typename P, typename N>
+ inline
+ complex_neighborhood_fwd_piter<I, P, N>::complex_neighborhood_fwd_piter()
+ {
+ }
+
+ template <typename I, typename P, typename N>
+ template <typename Pref>
+ inline
+ complex_neighborhood_fwd_piter<I, P, N>::complex_neighborhood_fwd_piter(const
Neighborhood<N>& nbh,
+ const Pref& p_ref)
+ {
+ this->change_target(exact(nbh));
+ center_at(p_ref);
+ mln_postcondition(!this->is_valid());
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ bool
+ complex_neighborhood_fwd_piter<I, P, N>::is_valid_() const
+ {
+ return iter_.is_valid();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_fwd_piter<I, P, N>::invalidate_()
+ {
+ iter_.invalidate();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_fwd_piter<I, P, N>::do_start_()
+ {
+ iter_.start();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_fwd_piter<I, P, N>::do_next_()
+ {
+ iter_.next();
+ }
+
+ template <typename I, typename P, typename N>
+ template <typename Pref>
+ inline
+ void
+ complex_neighborhood_fwd_piter<I, P, N>::center_at(const Pref& c)
+ {
+ super_::center_at(c);
+ iter_.center_at(this->center().face());
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ mln_psite(N)
+ complex_neighborhood_fwd_piter<I, P, N>::compute_p_() const
+ {
+ return psite(this->center().site_set(), iter_);
+ }
+
+
+ template <typename I, typename P, typename N>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr,
+ const complex_neighborhood_fwd_piter<I, P, N>& p)
+ {
+ return ostr << p.unproxy_();
+ }
+
+
+ /*------------------------------------------.
+ | complex_neighborhood_bkd_piter<I, P, N>. |
+ `------------------------------------------*/
+
+ template <typename I, typename P, typename N>
+ inline
+ complex_neighborhood_bkd_piter<I, P, N>::complex_neighborhood_bkd_piter()
+ {
+ }
+
+ template <typename I, typename P, typename N>
+ template <typename Pref>
+ inline
+ complex_neighborhood_bkd_piter<I, P, N>::complex_neighborhood_bkd_piter(const
Neighborhood<N>& nbh,
+ const Pref& p_ref)
+ {
+ this->change_target(exact(nbh));
+ center_at(p_ref);
+ mln_postcondition(!this->is_valid());
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ bool
+ complex_neighborhood_bkd_piter<I, P, N>::is_valid_() const
+ {
+ return iter_.is_valid();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_bkd_piter<I, P, N>::invalidate_()
+ {
+ iter_.invalidate();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_bkd_piter<I, P, N>::do_start_()
+ {
+ iter_.start();
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ void
+ complex_neighborhood_bkd_piter<I, P, N>::do_next_()
+ {
+ iter_.next();
+ }
+
+ template <typename I, typename P, typename N>
+ template <typename Pref>
+ inline
+ void
+ complex_neighborhood_bkd_piter<I, P, N>::center_at(const Pref& c)
+ {
+ super_::center_at(c);
+ iter_.center_at(this->center().face());
+ }
+
+ template <typename I, typename P, typename N>
+ inline
+ mln_psite(N)
+ complex_neighborhood_bkd_piter<I, P, N>::compute_p_() const
+ {
+ return psite(this->center().site_set(), iter_);
+ }
+
+
+ template <typename I, typename P, typename N>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr,
+ const complex_neighborhood_bkd_piter<I, P, N>& p)
+ {
+ return ostr << p.unproxy_();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // ! MLN_CORE_IMAGE_COMPLEX_NEIGHBORHOOD_PITER_HH
diff --git a/milena/tests/core/image/complex_image.cc
b/milena/tests/core/image/complex_image.cc
index 8ac6b4f..76f55db 100644
--- a/milena/tests/core/image/complex_image.cc
+++ b/milena/tests/core/image/complex_image.cc
@@ -36,6 +36,11 @@
#include <mln/core/site_set/p_faces.hh>
#include <mln/core/image/complex_image.hh>
+// FIXME: Include these elsewhere? (In complex_image.hh?)
+#include <mln/core/image/complex_lower_neighborhood.hh>
+#include <mln/core/image/complex_higher_neighborhood.hh>
+#include <mln/core/image/complex_neighborhood_piter.hh>
+
int main()
{
@@ -196,6 +201,50 @@ int main()
// Iterators on windows and neighborhoods. //
// ---------------------------------------- //
+ // FIXME: Factor: these two test cases only differ by their neighborhood.
+
+ // Iterate on the lower-dimension faces of each face.
+ {
+ typedef complex_lower_neighborhood<D, P> nbh_t;
+ nbh_t nbh;
+ mln_fwd_niter_(nbh_t) fn(nbh, fp);
+ mln_bkd_niter_(nbh_t) bn(nbh, fp);
+ for_all(fp)
+ {
+ std::cout << "Lower-dimension faces adjacent to " << fp
<< std::endl;
+ for_all_2(fn, bn)
+ {
+ mln_assertion((fn.center() ==
+ static_cast<const complex_psite<D, P>&>(fp)));
+ mln_assertion((bn.center() ==
+ static_cast<const complex_psite<D, P>&>(fp)));
+ std::cout << " " << fn << '\t' << bn
<< std::endl;
+ }
+ }
+ std::cout << std::endl;
+ }
+
+ // Iterate on the higher-dimension faces of each face.
+ {
+ typedef complex_higher_neighborhood<D, P> nbh_t;
+ nbh_t nbh;
+ mln_fwd_niter_(nbh_t) fn(nbh, fp);
+ mln_bkd_niter_(nbh_t) bn(nbh, fp);
+ for_all(fp)
+ {
+ std::cout << "Higher-dimension faces adjacent to " << fp
<< std::endl;
+ for_all_2(fn, bn)
+ {
+ mln_assertion((fn.center() ==
+ static_cast<const complex_psite<D, P>&>(fp)));
+ mln_assertion((bn.center() ==
+ static_cast<const complex_psite<D, P>&>(fp)));
+ std::cout << " " << fn << '\t' << bn
<< std::endl;
+ }
+ }
+ std::cout << std::endl;
+ }
+
/* FIXME: Implement windows (and neighborhoods) and corresponding
iterators for complex-based images.
--
1.6.0.1