
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make relative iterators---qiter and niter---work. * doc/tutorial/examples/image2d.cc (picture): New display proc. (fill_null): New to illustrate a double loop. (main): Add a test of window browsing from every array point. Add a test about updating a relative site iterator. * mln/core/macros.hh (mln_deduce): New. * mln/core/window.hh (b_): Remove; it was useless and unused. (sym): Remove return value to disambiguate w.r.t. geom::sym. (include): Remove obsolete dpoints_piter. * mln/core/internal/basic_window_impl.hh (vect): Rename as... (std_vector): ...this. (fwd_qiter, bkd_qiter): Update. (include): New for iterators. * mln/core/internal/neighborhood_impl_mixin.hh: New. * mln/core/internal/site_relative_iterator_base.hh: New. * mln/core/internal/site_iterator_base.hh: Add documentation. (site_iterator_base_): Rename as... (site_iterator_base): ...this. (change_target, s_): New to factor code. * mln/core/internal/site_set_iterator_base.hh: New. * mln/core/internal/window_base.hh: Fix doc. * mln/core/internal/neighborhood_base.hh: New; created from window_base. (is_centered, is_symmetric, sym): New factored code. * mln/core/neighb.hh (neighb_): Rename as... (neighb): ...this. Update; that means remove about everything, now factored in super classes. (insert): Rename as... (insert_): ...this. * mln/core/box_piter.hh: Update inheritance. (b_, target_): Remove cause factored; b_ is now s_. (box_bkd_piter_): Fix ctor. * mln/core/p_array_piter.hh: Likewise. * mln/core/dpsites_piter.hh: New from dpoints_piter. (start, next): Rename as... (do_start_, do_next_): ...these. Now rely on internal::site_relative_iterator_base. (dps_, p_ref_, p_): Remove; obsolete cause factored. (operator[]): Remove; now obsolete thanks to proxy_impl. (compute_p_, update): New. * mln/core/neighb2d.hh: Update. * mln/core/p_array.hh (target_t): New type in psite. (is_valid, p_, update_p_, has_index): New. * mln/core/concept/pseudo_site.hh (change_target): New. Add doc. * mln/core/concept/site_iterator.hh (change_target): Move... * mln/core/internal/site_iterator_base.hh: ...here. * mln/core/concept/site_set.hh (insert_all): New. * mln/core/image2d.hh (point): Re-new; to compile more easily. (line_piter): Remove; it shall be re-inserted somewhere else. (coord): Remove; useless. (include): Remove dependance upon w_window which is not updated yet. * mln/level/fill.hh: Update. * mln/geom/max_col.hh: Update. * mln/geom/min_row.hh: Update. doc/tutorial/examples/image2d.cc | 64 +++++ mln/core/box_piter.hh | 68 +---- mln/core/concept/pseudo_site.hh | 35 ++ mln/core/concept/site_iterator.hh | 20 - mln/core/concept/site_set.hh | 15 + mln/core/dpsites_piter.hh | 274 +++++++---------------- mln/core/image2d.hh | 9 mln/core/internal/basic_window_impl.hh | 23 + mln/core/internal/neighborhood_base.hh | 66 ++++- mln/core/internal/neighborhood_impl_mixin.hh | 64 +++++ mln/core/internal/site_iterator_base.hh | 49 +++- mln/core/internal/site_relative_iterator_base.hh | 167 ++++++++++++++ mln/core/internal/site_set_iterator_base.hh | 87 +++++++ mln/core/internal/window_base.hh | 2 mln/core/macros.hh | 3 mln/core/neighb.hh | 114 +-------- mln/core/neighb2d.hh | 2 mln/core/p_array.hh | 66 +++++ mln/core/p_array_piter.hh | 42 +-- mln/core/window.hh | 18 - mln/geom/max_col.hh | 6 mln/geom/min_row.hh | 6 mln/level/fill.hh | 3 23 files changed, 781 insertions(+), 422 deletions(-) Index: doc/tutorial/examples/image2d.cc --- doc/tutorial/examples/image2d.cc (revision 2014) +++ doc/tutorial/examples/image2d.cc (working copy) @@ -1,12 +1,48 @@ # include <mln/core/image2d.hh> # include <mln/core/window2d.hh> +# include <mln/core/p_array.hh> + +# include <mln/debug/iota.hh> +# include <mln/debug/println.hh> + +# include <mln/core/neighb2d.hh> + + +template <typename I, typename W, typename P> +void picture(const I& ima, const W& win, const P& p) +{ + std::cout << ima(p) << ": "; + mln_qiter(W) q(win, p); + for_all(q) + if (ima.has(q)) + std::cout << ima(q) << ' '; + else + std::cout << "- "; + std::cout << std::endl; +} + + +template <typename I, typename W> +void fill_null(I& ima, const W& win) +{ + mln_piter(I) p(ima.domain()); + mln_qiter(W) q(win, p); + for_all(p) + for_all(q) + if (ima.has(q)) + ima(q) = 0; +} + int main() { using namespace mln; - image2d<char> ima(2, 3); + typedef image2d<unsigned> I; + I ima(2, 3, 0); // no border + debug::iota(ima); + debug::println(ima); mln_invariant(ima.nsites() == 6); window2d win; @@ -15,4 +51,30 @@ .insert(0, -1) .insert(-1,-1); std::cout << win << std::endl; + + { + mln_fwd_piter_(I) p(ima.domain()); + for_all(p) + picture(ima, win, p); + } + + { + typedef p_array<point2d> A; + A arr; + arr.insert_all(ima.domain()); + mln_fwd_piter_(A) p(arr); + for_all(p) + picture(ima, win, p); + + // FIXME: Move this new test in a separate file. + mln_psite_(A) c(arr, 0); + window2d it; it.insert(0,0); + mln_qiter_(window2d) q(it, c); + q.start(); + q.to_site() == c.to_site(); + c.inc_index(); + mln_assertion(q.update().to_site() == c.to_site()); + } + + fill_null(ima, win); } Index: mln/core/macros.hh --- mln/core/macros.hh (revision 2014) +++ mln/core/macros.hh (working copy) @@ -35,6 +35,9 @@ */ +# define mln_deduce(T, A1, A2) typename T::A1::A2 + + // a /// Shortcuts to access the argument type associated to T. Index: mln/core/window.hh --- mln/core/window.hh (revision 2014) +++ mln/core/window.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -77,13 +77,9 @@ */ bool is_symmetric() const; - - /// Apply a central symmetry to the target window. - window<D>& sym(); - - protected: - - box_<mln_point(D)> b_; + /*! Apply a central symmetry to the target window. + */ + void sym(); }; @@ -122,7 +118,7 @@ template <typename D> inline - window<D>& + void window<D>::sym() { window<D> tmp; @@ -130,7 +126,6 @@ for (unsigned i = 0; i < n; ++i) tmp.insert(- this->dp(i)); *this = tmp; - return *this; } template <typename D> @@ -144,7 +139,4 @@ } // end of namespace mln -# include <mln/core/dpoints_piter.hh> - - #endif // ! MLN_CORE_WINDOW_HH Index: mln/core/internal/basic_window_impl.hh --- mln/core/internal/basic_window_impl.hh (revision 2014) +++ mln/core/internal/basic_window_impl.hh (working copy) @@ -42,8 +42,8 @@ { // Fwd decls. - template <typename D> class dpoints_fwd_piter; - template <typename D> class dpoints_bkd_piter; + template <typename V> class dpsites_fwd_piter; + template <typename V> class dpsites_bkd_piter; namespace internal @@ -59,20 +59,21 @@ public: - /*! \brief Site_Iterator type to browse the points of a basic window - * whatever the ordering of delta-points. - */ - typedef dpoints_fwd_piter<D> qiter; /*! \brief Site_Iterator type to browse the points of a basic window * w.r.t. the ordering of delta-points. */ - typedef dpoints_fwd_piter<D> fwd_qiter; + typedef dpsites_fwd_piter<E> fwd_qiter; /*! \brief Site_Iterator type to browse the points of a basic window * w.r.t. the reverse ordering of delta-points. */ - typedef dpoints_bkd_piter<D> bkd_qiter; + typedef dpsites_bkd_piter<E> bkd_qiter; + + /*! \brief Site_Iterator type to browse the points of a basic window + * whatever the ordering of delta-points. + */ + typedef fwd_qiter qiter; /*! \brief Test if the window is empty (null size; no delta-point). @@ -126,7 +127,6 @@ }; - # ifndef MLN_INCLUDE_ONLY template <typename D, typename E> @@ -178,7 +178,7 @@ template <typename D, typename E> inline const std::vector<D>& - basic_window_impl<D,E>::vect() const + basic_window_impl<D,E>::std_vector() const { return dps_.vect(); } @@ -255,4 +255,7 @@ } // end of namespace mln +# include <mln/core/dpsites_piter.hh> + + #endif // ! MLN_CORE_INTERNAL_BASIC_WINDOW_IMPLHH Index: mln/core/internal/neighborhood_impl_mixin.hh --- mln/core/internal/neighborhood_impl_mixin.hh (revision 0) +++ mln/core/internal/neighborhood_impl_mixin.hh (revision 0) @@ -0,0 +1,64 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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_INTERNAL_NEIGHBORHOOD_IMPL_MIXIN_HH +# define MLN_CORE_INTERNAL_NEIGHBORHOOD_IMPL_MIXIN_HH + +/*! \file mln/core/internal/neighborhood_impl_mixin.hh + * + * \brief Definition of a mixin to turn a window implementation class + * into a neighborhood impl class. + */ + + +namespace mln +{ + + namespace internal + { + + template <typename W_impl, typename E> + struct neighborhood_impl_mixin : W_impl + { + /// Site_Iterator type to browse the neighborhood sites. + typedef typename W_impl::qiter niter; + + /// Site_Iterator type to browse the neighborhood sites in the + /// forward way. + typedef typename W_impl::fwd_qiter fwd_niter; + + /// Site_Iterator type to browse the neighborhood sites in the + /// backward way. + typedef typename W_impl::bkd_qiter bkd_niter; + }; + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_NEIGHBORHOOD_IMPL_MIXIN_HH Index: mln/core/internal/site_relative_iterator_base.hh --- mln/core/internal/site_relative_iterator_base.hh (revision 0) +++ mln/core/internal/site_relative_iterator_base.hh (revision 0) @@ -0,0 +1,167 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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_SITE_RELATIVE_ITERATOR_BASE_HH +# define MLN_CORE_SITE_RELATIVE_ITERATOR_BASE_HH + +/*! \file mln/core/site_relative_iterator_base.hh + * + * \brief Definition of forward and backward mln::dpoint_ based + * iterators. + * + * \todo Add a method to get the site set (if the center is defined) or + * the site set at a given center. + */ + +# include <vector> +# include <mln/core/internal/site_iterator_base.hh> + + +namespace mln +{ + + namespace internal + { + + /*! \brief A generic forward iterator on points of windows and of + * neighborhoods. + * + * The parameter \c S is the type of std::vector enclosing + * structure. + */ + template <typename S, typename E> + class site_relative_iterator_base : public site_iterator_base< S, E > + { + public: + + /// Constructor witout argument. + site_relative_iterator_base(); + + template <typename P> + void center_at(const P& c); + + /// Test the iterator validity. + bool is_valid_() const; + + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void start_(); + + /// Go to the next point. + void next_(); + + /// The psite around which this iterator moves. + const mln_psite(S)& center() const; + + /// Overriding that adds a test to prevent getting an invalid + /// iterator when its center has moved. Some sub-classes + /// provide an update() method for the client to say that she + /// really want to read the iterator just after the center has + /// changed. + const mln_psite(S)& unproxy() const; + + protected: + + const mln_psite(S)* c_; + }; + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename S, typename E> + inline + site_relative_iterator_base<S,E>::site_relative_iterator_base() + : c_(0) + { + void (E::*m1)() = & E::do_start_; + m1 = 0; + void (E::*m2)() = & E::do_next_; + m2 = 0; + mln_psite(S) (E::*m3)() const = & E::compute_p_; + m3 = 0; + } + + template <typename S, typename E> + template <typename P> + inline + void + site_relative_iterator_base<S,E>::center_at(const P& c) + { + internal::get_adr(c_, c); + this->invalidate(); + } + + template <typename S, typename E> + inline + void + site_relative_iterator_base<S,E>::start_() + { + exact(this)->do_start_(); + if (this->is_valid()) + this->p_ = exact(this)->compute_p_(); + } + + template <typename S, typename E> + inline + void + site_relative_iterator_base<S,E>::next_() + { + exact(this)->do_next_(); + if (this->is_valid()) + this->p_ = exact(this)->compute_p_(); + } + + template <typename S, typename E> + inline + const mln_psite(S)& + site_relative_iterator_base<S,E>::center() const + { + mln_precondition(c_ != 0); + return *c_; + } + + template <typename S, typename E> + inline + const mln_psite(S)& + site_relative_iterator_base<S,E>::unproxy() const + { + mln_psite(S) p_now = exact(this)->compute_p_(); + mln_assertion(p_now == this->p_); + return this->p_; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_SITE_RELATIVE_ITERATOR_BASE_HH Index: mln/core/internal/site_iterator_base.hh --- mln/core/internal/site_iterator_base.hh (revision 2014) +++ mln/core/internal/site_iterator_base.hh (working copy) @@ -34,6 +34,7 @@ */ # include <mln/core/concept/site_iterator.hh> +# include <mln/core/concept/pseudo_site.hh> // Use of if_possible::change_target. namespace mln @@ -44,10 +45,15 @@ /*! \internal A base class for site iterators. * + * NEVER DIRECTLY DERIVE FROM THIS CLASS. + * + * Instead derive from EITHER site_set_iterator_base OR + * site_relative_iterator_base. + * * Parameter \c S is the targeted site set type. */ template <typename S, typename E> - struct site_iterator_base_ : Site_Iterator<E>, + struct site_iterator_base : Site_Iterator<E>, proxy_impl< mln_psite(S), E>, @@ -57,7 +63,7 @@ { /// The associated site type (as a Site_Proxy). - typedef mln_site(S) site; // typename internal::site_from<P>::ret site; + typedef mln_site(S) site; /// Return the site it points to (as a Site_Proxy). const mln_site(S)& to_site() const; @@ -80,14 +86,20 @@ /// Give the subject (required by the Proxy interface). const mln_psite(S)& unproxy() const; - /// Access to the target address; default impl. + /// Give the target address. It might be 0. const S*& target_(); + /// Change the iterator target. + void change_target(const S& s); + protected: - site_iterator_base_(); + site_iterator_base(); - /// The site designated by this iterator. + /// The target. + const S* s_; + + /// The psite designated by this iterator. mln_psite(S) p_; }; @@ -96,13 +108,13 @@ template <typename S, typename E> inline - site_iterator_base_<S, E>::site_iterator_base_() + site_iterator_base<S, E>::site_iterator_base() { } template <typename S, typename E> inline - site_iterator_base_<S, E>::operator mln_site(S)() const + site_iterator_base<S, E>::operator mln_site(S)() const { typedef proxy_impl<mln_psite(S), E> super; mln_precondition(exact(this)->is_valid()); @@ -112,16 +124,16 @@ template <typename S, typename E> inline const mln_site(S)& - site_iterator_base_<S, E>::to_site() const + site_iterator_base<S, E>::to_site() const { mln_precondition(exact(*this).is_valid()); // FIXME: OK? - return internal::to_site(p_); + return internal::to_site( exact(this)->unproxy() ); } template <typename S, typename E> inline const mln_psite(S)& - site_iterator_base_<S, E>::unproxy() const + site_iterator_base<S, E>::unproxy() const { return p_; } @@ -129,9 +141,22 @@ template <typename S, typename E> inline const S*& - site_iterator_base_<S, E>::target_() + site_iterator_base<S, E>::target_() + { + return s_; + } + + template <typename S, typename E> + inline + void + site_iterator_base<S, E>::change_target(const S& s) { - return this->p_.target(); + s_ = & s; + // p_ might be also updated since it can hold a pointer towards + // the set it designates, so: + if_possible::change_target(p_, s); + // Last: + this->invalidate(); } #endif // ! MLN_INCLUDE_ONLY Index: mln/core/internal/site_set_iterator_base.hh --- mln/core/internal/site_set_iterator_base.hh (revision 0) +++ mln/core/internal/site_set_iterator_base.hh (revision 0) @@ -0,0 +1,87 @@ +// Copyright (C) 2008 EPITA Research and Development Laboratory +// +// 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_INTERNAL_SITE_SET_ITERATOR_BASE_HH +# define MLN_CORE_INTERNAL_SITE_SET_ITERATOR_BASE_HH + +/*! \file mln/core/internal/site_set_iterator_base.hh + * + * \brief Base class to factor code for iterator classes directly + * working on site sets. + */ + +# include <mln/core/internal/site_iterator_base.hh> + + +namespace mln +{ + + namespace internal + { + + /*! \internal A base class for site iterators. + * + * Parameter \c S is the targeted site set type. + */ + template <typename S, typename E> + struct site_set_iterator_base : site_iterator_base<S, E> + { + + /// Give the site set that this iterator browses. + const S& site_set() const; + + protected: + + site_set_iterator_base(); + }; + + +#ifndef MLN_INCLUDE_ONLY + + template <typename S, typename E> + inline + site_set_iterator_base<S, E>::site_set_iterator_base() + { + } + + template <typename S, typename E> + inline + const S& + site_set_iterator_base<S, E>::site_set() const + { + mln_precondition(this->s_ != 0); + return *this->s_; + } + +#endif // ! MLN_INCLUDE_ONLY + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_SITE_SET_ITERATOR_BASE_HH Index: mln/core/internal/window_base.hh --- mln/core/internal/window_base.hh (revision 2014) +++ mln/core/internal/window_base.hh (working copy) @@ -30,7 +30,7 @@ /*! \file mln/core/internal/window_base.hh * - * \brief Definition of a base class for site set classes. + * \brief Definition of a base class for window classes. */ # include <mln/core/concept/window.hh> Index: mln/core/internal/neighborhood_base.hh --- mln/core/internal/neighborhood_base.hh (revision 2013) +++ mln/core/internal/neighborhood_base.hh (working copy) @@ -25,15 +25,15 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_CORE_INTERNAL_WINDOW_BASE_HH -# define MLN_CORE_INTERNAL_WINDOW_BASE_HH +#ifndef MLN_CORE_INTERNAL_NEIGHBORHOOD_BASE_HH +# define MLN_CORE_INTERNAL_NEIGHBORHOOD_BASE_HH -/*! \file mln/core/internal/window_base.hh +/*! \file mln/core/internal/neighborhood_base.hh * - * \brief Definition of a base class for site set classes. + * \brief Definition of a base class for neighborhood classes. */ -# include <mln/core/concept/window.hh> +# include <mln/core/concept/neighborhood.hh> namespace mln @@ -43,12 +43,12 @@ { - /*! \internal A base class for window classes. + /*! \internal A base class for neighborhood classes. * * \p D is a dpsite type. */ template <typename D, typename E> - struct window_base : public Window<E> + struct neighborhood_base : public Neighborhood<E> { /// DPsite associated type. @@ -60,17 +60,61 @@ /// Site associated type. typedef mln_site(D) site; + + /*! \brief Test (as a window) if it is centered so (as a + * neighborhood) return false. + * + * \return Always false. + */ + bool is_centered() const; + + /*! \brief Test (as a window) if it is symmetric so (as a + * neighborhood) return true. + * + * \return Always true. + */ + bool is_symmetric() const; + + /*! Apply (as a window) a central symmetry so (as a + neighborhood) it is a no-op. + */ + void sym(); + protected: - window_base(); + neighborhood_base(); }; # ifndef MLN_INCLUDE_ONLY - template <typename S, typename E> + template <typename D, typename E> + inline + neighborhood_base<D,E>::neighborhood_base() + { + } + + template <typename D, typename E> + inline + bool + neighborhood_base<D,E>::is_centered() const + { + return false; + } + + template <typename D, typename E> + inline + bool + neighborhood_base<D,E>::is_symmetric() const + { + return true; + } + + template <typename D, typename E> inline - window_base<S,E>::window_base() + void + neighborhood_base<D,E>::sym() { + // No-op. } # endif // ! MLN_INCLUDE_ONLY @@ -80,4 +124,4 @@ } // end of namespace mln -#endif // ! MLN_CORE_INTERNAL_WINDOW_BASE_HH +#endif // ! MLN_CORE_INTERNAL_NEIGHBORHOOD_BASE_HH Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2014) +++ mln/core/neighb.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -30,21 +30,17 @@ /*! \file mln/core/neighb.hh * - * \brief Definition of the generic neighborhood class mln::neighb_. + * \brief Definition of the generic neighborhood class mln::neighb. */ -# include <mln/core/concept/neighborhood.hh> -# include <mln/core/internal/dpoints_base.hh> -# include <mln/core/dpoint.hh> +# include <mln/core/internal/neighborhood_base.hh> +# include <mln/core/internal/basic_window_impl.hh> +# include <mln/core/internal/neighborhood_impl_mixin.hh> namespace mln { - // fwd decls - template <typename D> class dpoints_fwd_piter; - template <typename D> class dpoints_bkd_piter; - /*! \brief Generic neighborhood class. * @@ -52,58 +48,20 @@ * The parameter is \c D, type of delta-point. */ template <typename D> - struct neighb_ : public Neighborhood< neighb_<D> >, - public internal::dpoints_base_<D, neighb_<D> > + struct neighb : internal::neighborhood_base< D, neighb<D> >, + internal::neighborhood_impl_mixin< internal::basic_window_impl< D, neighb<D> >, + neighb<D> > { - /// Dpoint associated type. - typedef D dpoint; - - /// Point associated type. - typedef mln_point(D) point; - - /*! \brief Site_Iterator type to browse the points of a generic - * neighborhood w.r.t. the ordering of delta-points. - */ - typedef dpoints_fwd_piter<D> fwd_niter; - - /*! \brief Site_Iterator type to browse the points of a generic - * neighborhood w.r.t. the reverse ordering of delta-points. - */ - typedef dpoints_bkd_piter<D> bkd_niter; - - /*! \brief Same as fwd_niter. - */ - typedef fwd_niter niter; - /*! \brief Constructor without argument. * * The constructed neighborhood is empty. You have to use insert() * to proceed to the neighborhood definition. */ - neighb_(); + neighb(); - /*! \brief Insert a delta-point \p dp in the neighborhood - * definition. - * - * \param[in] dp The delta-point to insert. - * - * This method also insert the symmetrical delta-point, - \p dp, - * in the neighborhood definition; thus the client has not to - * ensure the symmetry property; that is automatic. - */ - neighb_<D>& insert(const D& dp); - - /// \{ Insertion of a delta-point with different numbers of - /// arguments (coordinates) w.r.t. the dimension. - neighb_<D>& insert(const mln_coord(D)& dind); // For 1D. - - neighb_<D>& insert(const mln_coord(D)& drow, - const mln_coord(D)& dcol); // For 2D. - - neighb_<D>& insert(const mln_coord(D)& dsli, - const mln_coord(D)& drow, - const mln_coord(D)& dcol); // For 3D. - /// \} + // Overridden from internal::basic_window_impl so that it also + // inserts \a -dp. + neighb<D>& insert_(const D& dp); }; @@ -111,58 +69,26 @@ template <typename D> inline - neighb_<D>::neighb_() + neighb<D>::neighb() { } template <typename D> inline - neighb_<D>& - neighb_<D>::insert(const D& dp) + neighb<D>& + neighb<D>::insert_(const D& dp) { - mln_precondition(! has(dp)); - typedef internal::set_of_<D> super; - this->super::insert( dp); - this->super::insert(-dp); + typedef neighb<D> self; + typedef internal::basic_window_impl< D, neighb<D> > win_impl; + typedef internal::neighborhood_impl_mixin< win_impl, neighb<D> > super_; + this->super_::insert_( dp); + this->super_::insert_(-dp); return *this; } - template <typename D> - inline - neighb_<D>& - neighb_<D>::insert(const mln_coord(D)& dind) - { - D dp(dind); - mln_precondition(! has(dp)); - return this->insert(dp); - } - - template <typename D> - inline - neighb_<D>& - neighb_<D>::insert(const mln_coord(D)& drow, const mln_coord(D)& dcol) - { - D dp(drow, dcol); - mln_precondition(! has(dp)); - return this->insert(dp); - } - - template <typename D> - inline - neighb_<D>& - neighb_<D>::insert(const mln_coord(D)& dsli, const mln_coord(D)& drow, const mln_coord(D)& dcol) - { - D dp(dsli, drow, dcol); - mln_precondition(! has(dp)); - return this->insert(dp); - } - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln -# include <mln/core/dpoints_piter.hh> - - #endif // ! MLN_CORE_NEIGHB_HH Index: mln/core/box_piter.hh --- mln/core/box_piter.hh (revision 2014) +++ mln/core/box_piter.hh (working copy) @@ -33,7 +33,7 @@ * \brief Definition of iterators on points of boxes. */ -# include <mln/core/internal/site_iterator_base.hh> +# include <mln/core/internal/site_set_iterator_base.hh> # include <mln/core/concept/box.hh> @@ -47,11 +47,11 @@ * \see mln::box_ */ template <typename P> - class box_fwd_piter_ : public internal::site_iterator_base_< box_<P>, + class box_fwd_piter_ : public internal::site_set_iterator_base< box_<P>, box_fwd_piter_<P> > { typedef box_fwd_piter_<P> self_; - typedef internal::site_iterator_base_< box_<P>, self_ > super_; + typedef internal::site_iterator_base< box_<P>, self_ > super_; public: @@ -76,13 +76,10 @@ /// Go to the next point. void next_(); - /// Give the site set target address. - const box_<P>*& target_(); - - private: + protected: using super_::p_; - const box_<P>* b_; + using super_::s_; }; @@ -94,11 +91,11 @@ * \see mln::box_ */ template <typename P> - class box_bkd_piter_ : public internal::site_iterator_base_< box_<P>, + class box_bkd_piter_ : public internal::site_iterator_base< box_<P>, box_bkd_piter_<P> > { typedef box_bkd_piter_<P> self_; - typedef internal::site_iterator_base_< box_<P>, self_ > super_; + typedef internal::site_iterator_base< box_<P>, self_ > super_; public: @@ -123,13 +120,10 @@ /// Go to the next point. void next_(); - /// Give the site set target address. - const box_<P>*& target_(); - - private: + protected: using super_::p_; - const box_<P>* b_; + using super_::s_; }; @@ -144,7 +138,7 @@ inline box_fwd_piter_<P>::box_fwd_piter_(const box_<P>& b) { - change_target(b); + this->change_target(b); } template <typename P> @@ -152,7 +146,7 @@ bool box_fwd_piter_<P>::is_valid_() const { - return p_[0] != b_->pmax()[0] + 1; + return p_[0] != s_->pmax()[0] + 1; } template <typename P> @@ -160,7 +154,7 @@ void box_fwd_piter_<P>::invalidate_() { - p_[0] = b_->pmax()[0] + 1; + p_[0] = s_->pmax()[0] + 1; } template <typename P> @@ -168,7 +162,7 @@ void box_fwd_piter_<P>::start_() { - p_ = b_->pmin(); + p_ = s_->pmin(); } template <typename P> @@ -177,25 +171,17 @@ box_fwd_piter_<P>::next_() { for (int i = dim - 1; i >= 0; --i) - if (p_[i] == b_->pmax()[i]) - p_[i] = b_->pmin()[i]; + if (p_[i] == s_->pmax()[i]) + p_[i] = s_->pmin()[i]; else { ++p_[i]; break; } - if (p_ == b_->pmin()) + if (p_ == s_->pmin()) invalidate_(); } - template <typename P> - inline - const box_<P>*& - box_fwd_piter_<P>::target_() - { - return b_; - } - // box_bkd_piter_<P> @@ -203,7 +189,7 @@ inline box_bkd_piter_<P>::box_bkd_piter_(const box_<P>& b) { - change_target(&b); + this->change_target(b); } template <typename P> @@ -211,7 +197,7 @@ bool box_bkd_piter_<P>::is_valid_() const { - return p_[0] != b_->pmin()[0] - 1; + return p_[0] != s_->pmin()[0] - 1; } template <typename P> @@ -219,7 +205,7 @@ void box_bkd_piter_<P>::invalidate_() { - p_[0] = b_->pmin()[0] - 1; + p_[0] = s_->pmin()[0] - 1; } template <typename P> @@ -227,7 +213,7 @@ void box_bkd_piter_<P>::start_() { - p_ = b_->pmax(); + p_ = s_->pmax(); } template <typename P> @@ -236,25 +222,17 @@ box_bkd_piter_<P>::next_() { for (int i = dim - 1; i >= 0; --i) - if (p_[i] == b_->pmin()[i]) - p_[i] = b_->pmax()[i]; + if (p_[i] == s_->pmin()[i]) + p_[i] = s_->pmax()[i]; else { --p_[i]; break; } - if (p_ == b_->pmax()) + if (p_ == s_->pmax()) invalidate_(); } - template <typename P> - inline - const box_<P>*& - box_bkd_piter_<P>::target_() - { - return b_; - } - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/p_array_piter.hh --- mln/core/p_array_piter.hh (revision 2014) +++ mln/core/p_array_piter.hh (working copy) @@ -32,7 +32,7 @@ /// \brief Definition of point iterators on mln::p_array. # include <mln/core/p_array.hh> -# include <mln/core/internal/site_iterator_base.hh> +# include <mln/core/internal/site_set_iterator_base.hh> namespace mln @@ -42,14 +42,11 @@ template <typename P> class p_array_fwd_piter_ : - public internal::site_iterator_base_< p_array<P>, + public internal::site_set_iterator_base< p_array<P>, p_array_fwd_piter_<P> > { typedef p_array_fwd_piter_<P> self; - typedef internal::site_iterator_base_<p_array<P>, self> super; - - protected: - using super::p_; + typedef internal::site_set_iterator_base<p_array<P>, self> super; public: @@ -73,6 +70,11 @@ /// Return the current index. int index() const; + + protected: + + using super::p_; + using super::s_; }; @@ -85,14 +87,11 @@ template <typename P> class p_array_bkd_piter_ : - public internal::site_iterator_base_< p_array<P>, + public internal::site_set_iterator_base< p_array<P>, p_array_bkd_piter_<P> > { typedef p_array_bkd_piter_<P> self; - typedef internal::site_iterator_base_<p_array<P>, self> super; - - protected: - using super::p_; + typedef internal::site_set_iterator_base<p_array<P>, self> super; public: @@ -116,6 +115,11 @@ /// Return the current index. int index() const; + + protected: + + using super::p_; + using super::s_; }; @@ -148,7 +152,7 @@ p_array_fwd_piter_<P>::is_valid_() const { mln_invariant(p_.index() >= 0); - return p_.index() < int(p_.target()->nsites()); + return p_.index() < int(s_->nsites()); } template <typename P> @@ -156,7 +160,7 @@ void p_array_fwd_piter_<P>::invalidate_() { - p_.index() = int(p_.target()->nsites()); + p_.change_index(s_->nsites()); } template <typename P> @@ -164,7 +168,7 @@ void p_array_fwd_piter_<P>::start_() { - p_.index() = 0; + p_.change_index(0); } template <typename P> @@ -172,7 +176,7 @@ void p_array_fwd_piter_<P>::next_() { - ++p_.index(); + p_.inc_index(); } template <typename P> @@ -206,7 +210,7 @@ bool p_array_bkd_piter_<P>::is_valid_() const { - mln_invariant(p_.index() < int(p_.target()->nsites())); + mln_invariant(p_.index() < int(s_->nsites())); return p_.index() >= 0; } @@ -215,7 +219,7 @@ void p_array_bkd_piter_<P>::invalidate_() { - p_.index() = -1; + p_.change_index(-1); } template <typename P> @@ -223,7 +227,7 @@ void p_array_bkd_piter_<P>::start_() { - p_.index() = int(p_.target()->nsites()) - 1; + p_.change_index(s_->nsites() - 1); } template <typename P> @@ -231,7 +235,7 @@ void p_array_bkd_piter_<P>::next_() { - --p_.index(); + p_.dec_index(); } template <typename P> Index: mln/core/dpsites_piter.hh --- mln/core/dpsites_piter.hh (revision 2013) +++ mln/core/dpsites_piter.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -25,18 +25,17 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_CORE_DPOINTS_PITER_HH -# define MLN_CORE_DPOINTS_PITER_HH +#ifndef MLN_CORE_DPSITES_PITER_HH +# define MLN_CORE_DPSITES_PITER_HH -/*! \file mln/core/dpoints_piter.hh +/*! \file mln/core/dpsites_piter.hh * * \brief Definition of forward and backward mln::dpoint_ based * iterators. */ # include <vector> -# include <mln/core/internal/site_iterator_base.hh> -# include <mln/core/concept/point_site.hh> +# include <mln/core/internal/site_relative_iterator_base.hh> namespace mln @@ -45,10 +44,12 @@ /*! \brief A generic forward iterator on points of windows and of * neighborhoods. * - * The parameter \c D is the type of delta-points. + * The parameter \c V is the type of std::vector enclosing + * structure. */ - template <typename D> - class dpoints_fwd_piter : public internal::site_iterator_base_< mln_point(D), dpoints_fwd_piter<D> > + template <typename V> + class dpsites_fwd_piter + : public internal::site_relative_iterator_base< V, dpsites_fwd_piter<V> > { public: @@ -57,56 +58,41 @@ * \param[in] dps Object that can provide an array of delta-points. * \param[in] p_ref Center point to iterate around. */ - template <typename Dps, typename Pref> - dpoints_fwd_piter(const Dps& dps, // FIXME: explicitly set_of_<D>? - const Point_Site<Pref>& p_ref); - - /// Convertion to point. - operator mln_point(D) () const; - - /// Reference to the corresponding point. - const mln_point(D)& to_point() const; + template <typename P> + dpsites_fwd_piter(const V& v, const P& c); /// Test the iterator validity. - bool is_valid() const; + bool is_valid_() const; /// Invalidate the iterator. - void invalidate(); + void invalidate_(); /// Start an iteration. - void start(); + void do_start_(); /// Go to the next point. - void next_(); - - /// Give the i-th coordinate. - mln_coord(D) operator[](unsigned i) const; + void do_next_(); - /// The point around which this iterator moves. - const mln_point(D)& center_point() const; + /// Compute the current psite. + mln_psite(V) compute_p_() const; - /// Force this iterator to update its location to take into - /// account that its center point may have moved. - void update(); + dpsites_fwd_piter<V>& update(); protected: - const std::vector<D>& dps_; - const mln_point(D)& p_ref_; // reference point (or "center point") - unsigned i_; - mln_point(D) p_; // location of this iterator; p_ makes this iterator be - // itself a potential center point. }; /*! \brief A generic backward iterator on points of windows and of * neighborhoods. * - * The parameter \c D is the type of delta-points. + * The parameter \c V is the type of std::vector enclosing + * structure. */ - template <typename D> - class dpoints_bkd_piter : public internal::site_iterator_base_< mln_point(D), dpoints_bkd_piter<D> > + template <typename V> + class dpsites_bkd_piter : + public internal::site_relative_iterator_base< V, dpsites_bkd_piter<V> > { public: @@ -115,248 +101,166 @@ * \param[in] dps Object that can provide an array of delta-points. * \param[in] p_ref Center point to iterate around. */ - template <typename Dps, typename Pref> - dpoints_bkd_piter(const Dps& dps, // FIXME: explicitly set_of_<D>? - const Point_Site<Pref>& p_ref); - - /// Convertion to point. - operator mln_point(D) () const; - - /// Reference to the corresponding point. - const mln_point(D)& to_point() const; + template <typename P> + dpsites_bkd_piter(const V& v, const P& c); /// Test the iterator validity. - bool is_valid() const; + bool is_valid_() const; /// Invalidate the iterator. - void invalidate(); + void invalidate_(); /// Start an iteration. - void start(); + void do_start_(); /// Go to the next point. - void next_(); - - /// Give the i-th coordinate. - mln_coord(D) operator[](unsigned i) const; + void do_next_(); - /// The point around which this iterator moves. - const mln_point(D)& center_point() const; + /// Compute the current psite. + mln_psite(V) compute_p_() const; - /// Force this iterator to update its location to take into - /// account that its center point may have moved. - void update(); + dpsites_fwd_piter<V>& update(); protected: - const std::vector<D>& dps_; - const mln_point(D)& p_ref_; // reference point (or "center point") - int i_; - mln_point(D) p_; // location of this iterator; p_ makes this iterator be - // itself a potential center point. }; # ifndef MLN_INCLUDE_ONLY - template <typename D> - template <typename Dps, typename Pref> - inline - dpoints_fwd_piter<D>::dpoints_fwd_piter(const Dps& dps, - const Point_Site<Pref>& p_ref) - : dps_(exact(dps).vect()), - p_ref_(exact(p_ref).to_point()) - { - invalidate(); - } - template <typename D> - inline - dpoints_fwd_piter<D>::operator mln_point(D) () const - { - mln_precondition(is_valid()); - return p_; - } + // Forward. + - template <typename D> + template <typename V> + template <typename P> inline - const mln_point(D)& - dpoints_fwd_piter<D>::to_point() const + dpsites_fwd_piter<V>::dpsites_fwd_piter(const V& v, const P& c) { - return p_; + this->change_target(v); + this->center_at(c); } - template <typename D> + template <typename V> inline bool - dpoints_fwd_piter<D>::is_valid() const + dpsites_fwd_piter<V>::is_valid_() const { - return i_ != dps_.size(); + return i_ != this->s_->std_vector().size(); } - template <typename D> + template <typename V> inline void - dpoints_fwd_piter<D>::invalidate() + dpsites_fwd_piter<V>::invalidate_() { - i_ = dps_.size(); + i_ = this->s_->std_vector().size(); } - template <typename D> + template <typename V> inline void - dpoints_fwd_piter<D>::start() + dpsites_fwd_piter<V>::do_start_() { i_ = 0; - update(); } - template <typename D> + template <typename V> inline void - dpoints_fwd_piter<D>::next_() + dpsites_fwd_piter<V>::do_next_() { ++i_; - update(); - } - - template <typename D> - inline - const mln_point(D)& - dpoints_fwd_piter<D>::center_point() const - { - return p_ref_; } - template <typename D> + template <typename V> inline - void - dpoints_fwd_piter<D>::update() + mln_psite(V) + dpsites_fwd_piter<V>::compute_p_() const { - if (is_valid()) - p_ = p_ref_ + dps_[i_]; + return *this->c_ + this->s_->std_vector()[i_]; } - template <typename D> + template <typename V> inline - mln_coord(D) - dpoints_fwd_piter<D>::operator[](unsigned i) const + dpsites_fwd_piter<V>& + dpsites_fwd_piter<V>::update() { - mln_precondition(is_valid()); - - // below we test that no update is required - // meaning that p_ref_ has not moved or that - // the user has explicitly called update() - mln_precondition(p_ref_ + dps_[i_] == p_); - // FIXME: Explain this issue in the class documentation... - - return p_[i]; + mln_precondition(this->s_ && this->c_); + this->p_ = compute_p_(); + mln_postcondition(this->is_valid()); + return *this; } + // Backward. - template <typename D> - template <typename Dps, typename Pref> - inline - dpoints_bkd_piter<D>::dpoints_bkd_piter(const Dps& dps, - const Point_Site<Pref>& p_ref) - : dps_(exact(dps).vect()), - p_ref_(exact(p_ref).to_point()) - { - invalidate(); - } - - template <typename D> - inline - dpoints_bkd_piter<D>::operator mln_point(D) () const - { - mln_precondition(is_valid()); - return p_; - } - template <typename D> + template <typename V> + template <typename P> inline - const mln_point(D)& - dpoints_bkd_piter<D>::to_point() const + dpsites_bkd_piter<V>::dpsites_bkd_piter(const V& v, const P& c) { - return p_; + this->change_target(v); + this->center_at(c); } - template <typename D> + template <typename V> inline bool - dpoints_bkd_piter<D>::is_valid() const + dpsites_bkd_piter<V>::is_valid_() const { - unsigned i = i_; - - return i < dps_.size(); + return i_ != -1; } - template <typename D> + template <typename V> inline void - dpoints_bkd_piter<D>::invalidate() + dpsites_bkd_piter<V>::invalidate_() { i_ = -1; } - template <typename D> + template <typename V> inline void - dpoints_bkd_piter<D>::start() + dpsites_bkd_piter<V>::do_start_() { - i_ = dps_.size() - 1; - update(); + i_ = this->s_->std_vector().size() - 1; } - template <typename D> + template <typename V> inline void - dpoints_bkd_piter<D>::next_() + dpsites_bkd_piter<V>::do_next_() { --i_; - update(); } - template <typename D> + template <typename V> inline - const mln_point(D)& - dpoints_bkd_piter<D>::center_point() const + mln_psite(V) + dpsites_bkd_piter<V>::compute_p_() const { - return p_ref_; + return *this->c_ + this->s_->std_vector()[i_]; } - template <typename D> + template <typename V> inline - void - dpoints_bkd_piter<D>::update() + dpsites_fwd_piter<V>& + dpsites_bkd_piter<V>::update() { - if (is_valid()) - p_ = p_ref_ + dps_[i_]; + mln_precondition(this->s_ && this->c_); + this->p_ = compute_p_(); + mln_postcondition(this->is_valid()); + return *this; } - template <typename D> - inline - mln_coord(D) - dpoints_bkd_piter<D>::operator[](unsigned i) const - { - mln_precondition(is_valid()); - - // below we test that no update is required - // meaning that p_ref_ has not moved or that - // the user has explicitly called update() - mln_precondition(p_ref_ + dps_[i_] == p_); - // FIXME: Explain this issue in the class documentation... - - return p_[i]; - } - - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln -#endif // ! MLN_CORE_DPOINTS_PITER_HH +#endif // ! MLN_CORE_DPSITES_PITER_HH Index: mln/core/neighb2d.hh --- mln/core/neighb2d.hh (revision 2014) +++ mln/core/neighb2d.hh (working copy) @@ -45,7 +45,7 @@ /*! \brief Type alias for a neighborhood defined on the 2D square * grid with integer coordinates. */ - typedef neighb_<dpoint2d> neighb2d; + typedef neighb<dpoint2d> neighb2d; /*! \brief 4-connectivity neighborhood on the 2D grid. Index: mln/core/p_array.hh --- mln/core/p_array.hh (revision 2014) +++ mln/core/p_array.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -61,6 +61,11 @@ public: + // This associated type is important to know that this particular + // pseudo site knows the site set it refers to. + typedef p_array<P> target_t; + + // As a Proxy: const P& unproxy() const; @@ -79,16 +84,23 @@ int index() const; - int& index(); + void change_index(int i); + void inc_index(); + void dec_index(); const p_array<P>* target() const; const p_array<P>*& target(); + bool is_valid() const; + private: const p_array<P>* arr_; int i_; + mutable P p_; + + void update_p_() const; }; @@ -150,7 +162,9 @@ /// Test is \p p belongs to this site set. bool has(const psite& p) const; + /// Test is index \p i belongs to this site set. // FIXME: Add an overload "has(index)". + bool has_index(int i) const; /// Change site \p p into \p new_p. void change(const psite& p, const P& new_p); @@ -227,6 +241,14 @@ template <typename P> inline + bool + p_array<P>::has_index(int i) const + { + return i >= 0 && i < int(vect_.size()); + } + + template <typename P> + inline std::size_t p_array<P>::nsites() const { @@ -303,6 +325,7 @@ vect_[p.index()] = new_p; } + // p_array_psite<P> template <typename P> @@ -315,10 +338,21 @@ template <typename P> inline + void + p_array_psite<P>::update_p_() const + { + if (arr_ == 0 || ! arr_->has_index(i_)) + return; + p_ = (*arr_)[i_]; + } + + template <typename P> + inline p_array_psite<P>::p_array_psite(const p_array<P>& arr, int i) : arr_(&arr), i_(i) { + update_p_(); } template <typename P> @@ -341,10 +375,29 @@ template <typename P> inline - int& - p_array_psite<P>::index() + void + p_array_psite<P>::change_index(int i) { - return i_; + i_ = i; + update_p_(); + } + + template <typename P> + inline + void + p_array_psite<P>::dec_index() + { + --i_; + update_p_(); + } + + template <typename P> + inline + void + p_array_psite<P>::inc_index() + { + ++i_; + update_p_(); } template <typename P> @@ -369,7 +422,8 @@ p_array_psite<P>::unproxy() const { mln_precondition(arr_ != 0); - return (*arr_)[i_]; + update_p_(); + return p_; } Index: mln/core/concept/pseudo_site.hh --- mln/core/concept/pseudo_site.hh (revision 2014) +++ mln/core/concept/pseudo_site.hh (working copy) @@ -64,12 +64,30 @@ { typedef Pseudo_Site<void> category; + // When a pseudo site features this associated type... + // typedef target_t; + + // ...then it also features the method: + // const target_t* target(); protected: Pseudo_Site(); }; + namespace if_possible + { + // Nota: This procedure is used in internal::site_iterator_base. + + template <typename P> + void change_target(Pseudo_Site<P>& p, const typename P::target_t& new_target); + + template <typename O, typename T> + void change_target(Object<O>&, const T&); + + } // end of namespace mln::if_possible + + # ifndef MLN_INCLUDE_ONLY template <typename E> @@ -78,6 +96,23 @@ // FIXME } + namespace if_possible + { + + template <typename P> + void change_target(Pseudo_Site<P>& p, const typename P::target_t& new_target) + { + exact(p).target() = & new_target; + } + + template <typename O, typename D> + void change_target(Object<O>&, const D&) + { + // No-op. + } + + } // end of namespace mln::if_possible + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/site_iterator.hh --- mln/core/concept/site_iterator.hh (revision 2014) +++ mln/core/concept/site_iterator.hh (working copy) @@ -77,9 +77,8 @@ void invalidate(); void start(); - /// Change of site set target. - template <typename T> - void change_target(const T& the); + // Defined in site_iterator_base: + // void change_target(s); protected: Site_Iterator(); @@ -94,7 +93,7 @@ void Site_Iterator<E>::next() { - mln_precondition(exact(this)->is_valid()); + mln_precondition(is_valid()); exact(this)->next_(); } @@ -117,6 +116,7 @@ if (exact(this)->target_() == 0) return; // No-op. exact(this)->invalidate_(); + mln_postcondition(is_valid() == false); } template <typename E> @@ -129,16 +129,6 @@ } template <typename E> - template <typename T> - inline - void - Site_Iterator<E>::change_target(const T& the) - { - exact(this)->target_() = & the; - exact(this)->invalidate_(); - } - - template <typename E> inline Site_Iterator<E>::Site_Iterator() { @@ -152,6 +142,8 @@ m3 = 0; void (E::*m4)() = & E::next_; m4 = 0; + bool m5 = (& E::change_target) == (& E::change_target); + m5 = 0; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/concept/site_set.hh --- mln/core/concept/site_set.hh (revision 2014) +++ mln/core/concept/site_set.hh (working copy) @@ -81,6 +81,9 @@ bool has(const psite& p) const; */ + template <typename S> + E& insert_all(const Site_Set<S>& other); + protected: Site_Set(); }; @@ -167,6 +170,18 @@ } + template <typename E> + template <typename S> + inline + E& Site_Set<E>::insert_all(const Site_Set<S>& other) + { + E& self = exact(*this); + mln_fwd_piter(S) p(exact(other)); + for_all(p) + self.insert(p); + return self; + } + // operators Index: mln/core/image2d.hh --- mln/core/image2d.hh (revision 2014) +++ mln/core/image2d.hh (working copy) @@ -39,7 +39,7 @@ # include <mln/border/thickness.hh> # include <mln/value/set.hh> # include <mln/fun/i2v/all_to.hh> -# include <mln/core/line_piter.hh> +// # include <mln/core/line_piter.hh> // FIXME // FIXME: @@ -122,7 +122,11 @@ template <typename T> struct image2d : public internal::image_primary_< box2d, image2d<T> > { + typedef point2d point; // FIXME: HOT: to be removed. + + // Warning: just to make effective types appear in Doxygen: + typedef box2d pset; typedef point2d psite; @@ -132,7 +136,6 @@ typedef mln_fwd_piter(box2d) fwd_piter; typedef mln_bkd_piter(box2d) bkd_piter; - typedef line_piter_<point2d> line_piter; // End of warning. @@ -550,7 +553,7 @@ # include <mln/core/trait/pixter.hh> # include <mln/core/dpoints_pixter.hh> # include <mln/core/pixter2d.hh> -# include <mln/core/w_window.hh> +// # include <mln/core/w_window.hh> namespace mln Index: mln/level/fill.hh --- mln/level/fill.hh (revision 2014) +++ mln/level/fill.hh (working copy) @@ -164,7 +164,8 @@ { trace::entering("level::fill"); - mlc_is(mln_trait_image_io(I), trait::image::io::write)::check(); // FIXME: Only the upcoming general facade!!! + mlc_is(mln_trait_image_value_io(I), + trait::image::value_io::read_write)::check(); // FIXME: Only the upcoming general facade!!! mln_precondition(exact(ima).has_data()); impl::fill_with_value(mln_trait_image_speed(I)(), exact(ima), value); Index: mln/geom/max_col.hh --- mln/geom/max_col.hh (revision 2014) +++ mln/geom/max_col.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -44,7 +44,7 @@ /// Give the maximum column of an image. template <typename I> - mln_coord(I) max_col(const Image<I>& ima); + mln_deduce(I, site, coord) max_col(const Image<I>& ima); /// Give the maximum col of an box 2d or 3d. template <typename B> @@ -54,7 +54,7 @@ template <typename I> inline - mln_coord(I) max_col(const Image<I>& ima) + mln_deduce(I, site, coord) max_col(const Image<I>& ima) { mln_precondition(exact(ima).has_data()); return exact(ima).bbox().pmax().col(); Index: mln/geom/min_row.hh --- mln/geom/min_row.hh (revision 2014) +++ mln/geom/min_row.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -47,7 +47,7 @@ /// Give the minimum row of an image. template <typename I> - mln_coord(I) min_row(const Image<I>& ima); + mln_deduce(I, site, coord) min_row(const Image<I>& ima); /// Give the minimum row of an box 2d or 3d. template <typename B> @@ -58,7 +58,7 @@ template <typename I> inline - mln_coord(I) min_row(const Image<I>& ima) + mln_deduce(I, site, coord) min_row(const Image<I>& ima) { mln_precondition(exact(ima).has_data()); return exact(ima).bbox().pmin().row();