cleanup-2008 1987: Clean Site_Iterator design and propagate to p_array and box.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Clean Site_Iterator design and propagate to p_array and box. * doc/tutorial/examples/box.cc: New. * mln/core/internal/site_iterator_base.hh (P): Change into... (S): ...this; it is now a site set type (no more a psite). (site): Change into... (mln_site(S)): ...this; more readable. (unproxy, target_): New. * mln/core/concept/site_iterator.hh (is_valid, invalidate, start): New methods. Now concrete classes should implement the 'underscored' version. (target_): New expected method in concrete classes. (change_target): New. (Site_Iterator): Update the constructor. * mln/core/box_piter.hh: Update inheritance. (operator P, to_point, operator[]): Remove; obsolete. (is_valid, invalidate, start): Rename as... (is_valid_, invalidate_, start_): ...these and update. (p_): Change from attribute to 'using' (thru inheritance). (b_): Turn into a pointer. (nop_): Remove; it was overkill. (target_): New. (dim): Rely on P. (box_bounds_piter_): Remove this dead class. * mln/core/p_array_piter.hh (is_valid, invalidate, start): Rename as... (is_valid_, invalidate_, start_): ...these and update. (p_): Change from attribute to 'using' (thru inheritance). (unproxy, site, to_site): Remove; now inherited. (index_of_in): New overload for bkd piter. (p_array_bkd_piter_): Uncomment and update likewise. * mln/core/point2d.hh (operator[]): New. * mln/core/concept/site_proxy.hh (to_site): New. For use in site_iterator_base_<S, E>::to_site(). * mln/core/p_array.hh (target): New method in psite. (bkd_piter): Reactivate. doc/tutorial/examples/box.cc | 30 +++ mln/core/box_piter.hh | 296 ++++++------------------------- mln/core/concept/site_iterator.hh | 67 ++++++- mln/core/concept/site_proxy.hh | 39 ++++ mln/core/internal/site_iterator_base.hh | 76 ++++++-- mln/core/p_array.hh | 10 - mln/core/p_array_piter.hh | 303 ++++++++++++-------------------- mln/core/point2d.hh | 5 8 files changed, 372 insertions(+), 454 deletions(-) Index: doc/tutorial/examples/box.cc --- doc/tutorial/examples/box.cc (revision 0) +++ doc/tutorial/examples/box.cc (revision 0) @@ -0,0 +1,30 @@ +# include <mln/core/image2d.hh> +# include <mln/debug/println.hh> +# include <mln/level/fill.hh> + + +template <typename B> +void picture(const B& b) +{ + using namespace mln; + + image2d<char> ima(5, 5); + level::fill(ima, '-'); + + unsigned i = 0; + mln_piter(B) p(b); + for_all(p) + ima(p) = '0' + i++; + + debug::println(ima); +} + + + +int main() +{ + using namespace mln; + + box2d b = make::box2d(1,1, 3,2); + picture(b); +} Index: mln/core/internal/site_iterator_base.hh --- mln/core/internal/site_iterator_base.hh (revision 1985) +++ mln/core/internal/site_iterator_base.hh (working copy) @@ -44,56 +44,94 @@ /*! \internal A base class for site iterators. * - * Parameter \c P is FIXME: a point site type. + * Parameter \c S is the targeted site set type. */ - template <typename P, typename E> + template <typename S, typename E> struct site_iterator_base_ : Site_Iterator<E>, - proxy_impl<P, E>, + proxy_impl< mln_psite(S), E>, site_impl< false, // Constant access to site / subject. - typename site_from<P>::ret, + mln_site(S), // HOT: typename site_from< >::ret, E > { - // The associated site type. - typedef typename internal::site_from<P>::ret site; + /// The associated site type (as a Site_Proxy). + typedef mln_site(S) site; // typename internal::site_from<P>::ret site; - // The associated subject type (as a Proxy). - typedef P subject; + /// Return the site it points to (as a Site_Proxy). + const mln_site(S)& to_site() const; - // The associated q_subject type (as a Proxy). - typedef const P& q_subject; - - /*! \brief Conversion towards the site it designates. + /*! \brief Conversion towards the site it designates (as a Site_Proxy). * * \warning This is a final method; iterator classes should not * re-defined this method. * * \pre The iterator is valid. */ - operator site() const; + operator mln_site(S)() const; + + /// The associated subject type (as a Proxy). + typedef mln_psite(S) subject; + + /// The associated q_subject type (as a Proxy). + typedef const mln_psite(S)& q_subject; + + /// Give the subject (required by the Proxy interface). + const mln_psite(S)& unproxy() const; + + /// Access to the target address; default impl. + const S*& target_(); protected: + site_iterator_base_(); + + /// The site designated by this iterator. + mln_psite(S) p_; }; #ifndef MLN_INCLUDE_ONLY - template <typename P, typename E> + template <typename S, typename E> inline - site_iterator_base_<P, E>::site_iterator_base_() + site_iterator_base_<S, E>::site_iterator_base_() { } - template <typename P, typename E> + template <typename S, typename E> inline - site_iterator_base_<P, E>::operator site() const + site_iterator_base_<S, E>::operator mln_site(S)() const { - typedef proxy_impl<P, E> super; + typedef proxy_impl<mln_psite(S), E> super; mln_precondition(exact(this)->is_valid()); - return this->super::operator site(); + return this->super::operator site(); // Featured by internal::proxy_impl<*>. + } + + template <typename S, typename E> + inline + const mln_site(S)& + site_iterator_base_<S, E>::to_site() const + { + mln_precondition(exact(*this).is_valid()); // FIXME: OK? + return internal::to_site(p_); + } + + template <typename S, typename E> + inline + const mln_psite(S)& + site_iterator_base_<S, E>::unproxy() const + { + return p_; + } + + template <typename S, typename E> + inline + const S*& + site_iterator_base_<S, E>::target_() + { + return this->p_.target(); } #endif // ! MLN_INCLUDE_ONLY Index: mln/core/box_piter.hh --- mln/core/box_piter.hh (revision 1985) +++ mln/core/box_piter.hh (working copy) @@ -47,14 +47,16 @@ * \see mln::box_ */ template <typename P> - class box_fwd_piter_ : public internal::site_iterator_base_< P, box_fwd_piter_<P> > + class box_fwd_piter_ : public internal::site_iterator_base_< box_<P>, + box_fwd_piter_<P> > { typedef box_fwd_piter_<P> self_; - typedef internal::site_iterator_base_< P, self_ > super_; + typedef internal::site_iterator_base_< box_<P>, self_ > super_; + public: // Make definitions from super class available. - enum { dim = super_::dim }; + enum { dim = P::dim }; /*! \brief Constructor. * @@ -62,30 +64,25 @@ */ box_fwd_piter_(const box_<P>& b); - /// Conversion to point. - operator P() const; - - /// Reference to the corresponding point. - const P& to_point() const; - - /// Give the i-th coordinate. - mln_coord(P) operator[](unsigned i) const; - /// 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 start_(); /// Go to the next point. void next_(); + /// Give the site set target address. + const box_<P>*& target_(); + private: - const box_<P>& b_; - P p_, nop_; + + using super_::p_; + const box_<P>* b_; }; @@ -97,14 +94,16 @@ * \see mln::box_ */ template <typename P> - class box_bkd_piter_ : public internal::site_iterator_base_< P, box_bkd_piter_<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_< P, self_ > super_; + typedef internal::site_iterator_base_< box_<P>, self_ > super_; + public: // Make definitions from super class available. - enum { dim = super_::dim }; + enum { dim = P::dim }; /*! \brief Constructor. * @@ -112,83 +111,25 @@ */ box_bkd_piter_(const box_<P>& b); - /// Conversion to point. - operator P() const; - - /// Reference to the corresponding point. - const P& to_point() const; - - /// Give the i-th coordinate. - mln_coord(P) operator[](unsigned i) const; - /// 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 start_(); /// Go to the next point. void next_(); - private: - const box_<P>& b_; - P p_, nop_; - }; - - - /*! \brief A iterator on points of bounds of a boxes 2d. - * - * The parameter \c P is the type of points. - * - * \see mln::box_ - * - * \todo change it to n dimensions - */ - - template <typename P> - class box_bounds_piter_ : public internal::site_iterator_base_< P, box_bounds_piter_<P> > - { - typedef box_bounds_piter_<P> self_; - typedef internal::site_iterator_base_< P, self_ > super_; - public: - - // Make definitions from super class available. - enum { dim = super_::dim }; - - /*! \brief Constructor. - * - * \param[in] b A box. - */ - box_bounds_piter_(const box_<P>& b); - - /// Conversion to point. - operator P() const; - - /// Reference to the corresponding point. - const P& to_point() const; - - /// Give the i-th coordinate. - mln_coord(P) operator[](unsigned i) const; - - /// 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_(); + /// Give the site set target address. + const box_<P>*& target_(); private: - const box_<P>& b_; - P p_, nop_; - unsigned step_; + + using super_::p_; + const box_<P>* b_; }; @@ -202,59 +143,32 @@ template <typename P> inline box_fwd_piter_<P>::box_fwd_piter_(const box_<P>& b) - : b_(b) - { - nop_ = b_.pmax(); - ++nop_[0]; - invalidate(); - } - - template <typename P> - inline - box_fwd_piter_<P>::operator P() const - { - return p_; - } - - template <typename P> - inline - const P& - box_fwd_piter_<P>::to_point() const - { - return p_; - } - - template <typename P> - inline - mln_coord(P) - box_fwd_piter_<P>::operator[](unsigned i) const { - assert(i < dim); - return p_[i]; + change_target(b); } template <typename P> inline bool - box_fwd_piter_<P>::is_valid() const + box_fwd_piter_<P>::is_valid_() const { - return p_ != nop_; + return p_[0] != b_->pmax()[0] + 1; } template <typename P> inline void - box_fwd_piter_<P>::invalidate() + box_fwd_piter_<P>::invalidate_() { - p_ = nop_; + p_[0] = b_->pmax()[0] + 1; } template <typename P> inline void - box_fwd_piter_<P>::start() + box_fwd_piter_<P>::start_() { - p_ = b_.pmin(); + p_ = b_->pmin(); } template <typename P> @@ -263,77 +177,57 @@ 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] == b_->pmax()[i]) + p_[i] = b_->pmin()[i]; else { ++p_[i]; break; } - if (p_ == b_.pmin()) - p_ = nop_; + if (p_ == b_->pmin()) + invalidate_(); } - - // box_bkd_piter_<P> - template <typename P> inline - box_bkd_piter_<P>::box_bkd_piter_(const box_<P>& b) - : b_(b) + const box_<P>*& + box_fwd_piter_<P>::target_() { - nop_ = b_.pmin(); - --nop_[0]; - invalidate(); - } - - template <typename P> - inline - box_bkd_piter_<P>::operator P() const - { - return p_; + return b_; } - template <typename P> - inline - const P& - box_bkd_piter_<P>::to_point() const - { - return p_; - } + // box_bkd_piter_<P> template <typename P> inline - mln_coord(P) - box_bkd_piter_<P>::operator[](unsigned i) const + box_bkd_piter_<P>::box_bkd_piter_(const box_<P>& b) { - assert(i < dim); - return p_[i]; + change_target(&b); } template <typename P> inline bool - box_bkd_piter_<P>::is_valid() const + box_bkd_piter_<P>::is_valid_() const { - return p_ != nop_; + return p_[0] != b_->pmin()[0] - 1; } template <typename P> inline void - box_bkd_piter_<P>::invalidate() + box_bkd_piter_<P>::invalidate_() { - p_ = nop_; + p_[0] = b_->pmin()[0] - 1; } template <typename P> inline void - box_bkd_piter_<P>::start() + box_bkd_piter_<P>::start_() { - p_ = b_.pmax(); + p_ = b_->pmax(); } template <typename P> @@ -342,99 +236,23 @@ 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] == b_->pmin()[i]) + p_[i] = b_->pmax()[i]; else { --p_[i]; break; } - if (p_ == b_.pmax()) - p_ = nop_; - } - - - // box_bounds_piter_<P> - - template <typename P> - inline - box_bounds_piter_<P>::box_bounds_piter_(const box_<P>& b) - : b_(b) - { - nop_ = b_.pmax(); - ++nop_[0]; - invalidate(); - } - - template <typename P> - inline - box_bounds_piter_<P>::operator P() const - { - return p_; - } - - template <typename P> - inline - const P& - box_bounds_piter_<P>::to_point() const - { - return p_; + if (p_ == b_->pmax()) + invalidate_(); } template <typename P> inline - mln_coord(P) - box_bounds_piter_<P>::operator[](unsigned i) const + const box_<P>*& + box_bkd_piter_<P>::target_() { - assert(i < dim); - return p_[i]; - } - - template <typename P> - inline - bool - box_bounds_piter_<P>::is_valid() const - { - return p_ != nop_; - } - - template <typename P> - inline - void - box_bounds_piter_<P>::invalidate() - { - p_ = nop_; - } - - template <typename P> - inline - void - box_bounds_piter_<P>::start() - { - p_ = b_.pmin(); - step_ = 1; - } - - template <typename P> - inline - void - box_bounds_piter_<P>::next_() - { - if (step_ <= 2) - p_[step_ - 1]++; - if (step_ > 2) - p_[step_ - 3]--; - - if (step_ > 2) - if (p_[step_ - 3] == b_.pmin()[step_ - 3]) - step_++; - - if (step_ <= 2) - if (p_[step_ - 1] == b_.pmax()[step_ - 1]) - step_++; - - if (step_ == 5) - invalidate(); + return b_; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/p_array_piter.hh --- mln/core/p_array_piter.hh (revision 1985) +++ mln/core/p_array_piter.hh (working copy) @@ -38,15 +38,18 @@ namespace mln { - /// \brief Forward iterator on points of a p_array<P>. + /// \brief Forward iterator on sites of a p_array<P>. template <typename P> class p_array_fwd_piter_ : - public internal::site_iterator_base_< p_array_psite<P>, + public internal::site_iterator_base_< p_array<P>, p_array_fwd_piter_<P> > { typedef p_array_fwd_piter_<P> self; - typedef internal::site_iterator_base_<p_array_psite<P>, self> super; + typedef internal::site_iterator_base_<p_array<P>, self> super; + + protected: + using super::p_; public: @@ -56,101 +59,68 @@ /// Constructor. p_array_fwd_piter_(const p_array<P>& arr); - /// Change of site set target. - void change_target(const p_array<P>& arr); - /// Test if the iterator is valid. - bool is_valid() const; + bool is_valid_() const; /// Invalidate the iterator. - void invalidate(); + void invalidate_(); /// Start an iteration. - void start(); + void start_(); /// Go to the next point. void next_(); - /// Return the subject. - const p_array_psite<P>& unproxy() const; + /// Return the current index. + int index() const; + }; + - // As a Site_Proxy: + template <typename P, typename A> + int index_of_in(const p_array_fwd_piter_<P>& p, const A& arr); - typedef typename super::site site; - const site& to_site() const; - /// Return the current index. - int index() const; + + /// \brief Backward iterator on sites of a p_array<P>. + template <typename P> + class p_array_bkd_piter_ + : + public internal::site_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_; - p_array_psite<P> p_; - }; + public: + /// Constructor with no argument. + p_array_bkd_piter_(); - template <typename P, typename A> - int index_of_in(const p_array_fwd_piter_<P>& p, const A& arr) - { - return index_of_in(p.unproxy(), arr); - } + /// Constructor. + p_array_bkd_piter_(const p_array<P>& arr); + + /// Test if the iterator is valid. + bool is_valid_() const; + + /// Invalidate the iterator. + void invalidate_(); + + /// Start an iteration. + void start_(); + + /// Go to the next point. + void next_(); + /// Return the current index. + int index() const; + }; -// /// \brief Backward iterator on points of a p_array<P>. -// template <typename P> -// struct p_array_bkd_piter_ -// : public internal::site_iterator_base_< P, p_array_bkd_piter_<P> > -// { -// typedef p_array_bkd_piter_<P> self_; -// typedef internal::site_iterator_base_< P, self_ > super_; -// public: -// /// The associated psite type. -// typedef P psite; - -// /// The associated point type. -// typedef mln_point(P) point; - -// enum { dim = super_::dim }; - -// /// Coordinate associated type. -// template <typename S> -// p_array_bkd_piter_(const Site_Set<S>& s); - -// /// Reference of the corresponding psite. -// const psite& to_psite() const; - -// /// Reference of the corresponding point. -// const point& to_point() const; - -// /// Read-only access to the \p i-th coordinate. -// mln_coord(point) operator[](unsigned i) const; - -// /// Test if the iterator is valid. -// bool is_valid() const; - -// /// Invalidate the iterator. -// void invalidate(); - -// /// Start an iteration. -// void start(); - -// /// Go to the next point. -// void next_(); - -// /// Convert the iterator into a psite. -// operator psite() const; - -// protected: -// const std::vector<P>& vect_; -// /* FIXME: See the comment on p_array_fwd_piter_<P>::i_ above. We -// could turn this `int' into an `unsigned'. Then, -// - setting the value of i_ to -1 (== UINT_MAX) in invalidate(), -// - and having valid() test whether i_ is strictly smaller than -// vect_.size() -// should work in both iterators (fwd and bkd). */ -// int i_; -// psite p_; -// }; + template <typename P, typename A> + int index_of_in(const p_array_bkd_piter_<P>& p, const A& arr); # ifndef MLN_INCLUDE_ONLY @@ -169,160 +139,125 @@ inline p_array_fwd_piter_<P>::p_array_fwd_piter_(const p_array<P>& arr) { - change_target(arr); + this->change_target(arr); } template <typename P> inline - void - p_array_fwd_piter_<P>::change_target(const p_array<P>& arr) + bool + p_array_fwd_piter_<P>::is_valid_() const { - p_.change_target(arr); - invalidate(); + mln_invariant(p_.index() >= 0); + return p_.index() < int(p_.target()->nsites()); } template <typename P> inline - bool - p_array_fwd_piter_<P>::is_valid() const + void + p_array_fwd_piter_<P>::invalidate_() { - return p_.target() != 0 && p_.index() < int(p_.target()->nsites()); + p_.index() = int(p_.target()->nsites()); } template <typename P> inline void - p_array_fwd_piter_<P>::invalidate() + p_array_fwd_piter_<P>::start_() { - if (p_.target() != 0) - p_.index() = p_.target()->nsites(); + p_.index() = 0; } template <typename P> inline void - p_array_fwd_piter_<P>::start() + p_array_fwd_piter_<P>::next_() { - mln_precondition(p_.target() != 0); - p_.index() = 0; + ++p_.index(); + } + + template <typename P> + inline + int + p_array_fwd_piter_<P>::index() const + { + return p_.index(); + } + + + /*------------------------. + | p_array_bkd_piter_<P>. | + `------------------------*/ + + template <typename P> + inline + p_array_bkd_piter_<P>::p_array_bkd_piter_() + { + } + + template <typename P> + inline + p_array_bkd_piter_<P>::p_array_bkd_piter_(const p_array<P>& arr) + { + this->change_target(arr); + } + + template <typename P> + inline + bool + p_array_bkd_piter_<P>::is_valid_() const + { + mln_invariant(p_.index() < int(p_.target()->nsites())); + return p_.index() >= 0; } template <typename P> inline void - p_array_fwd_piter_<P>::next_() + p_array_bkd_piter_<P>::invalidate_() { - ++p_.index(); + p_.index() = -1; } template <typename P> inline - const p_array_psite<P>& - p_array_fwd_piter_<P>::unproxy() const + void + p_array_bkd_piter_<P>::start_() { - return p_; + p_.index() = int(p_.target()->nsites()) - 1; } template <typename P> inline - const typename p_array_fwd_piter_<P>::site& - p_array_fwd_piter_<P>::to_site() const + void + p_array_bkd_piter_<P>::next_() { - mln_precondition(p_.target() != 0); - return p_.to_site(); + --p_.index(); } template <typename P> inline int - p_array_fwd_piter_<P>::index() const + p_array_bkd_piter_<P>::index() const { - mln_precondition(p_.target() != 0); return p_.index(); } - /*------------------------. - | p_array_bkd_piter_<P>. | - `------------------------*/ -// template <typename P> -// template <typename S> -// inline -// p_array_bkd_piter_<P>::p_array_bkd_piter_(const Site_Set<S>& s) -// : vect_(exact(s).vect()) -// { -// invalidate(); -// } - -// template <typename P> -// inline -// const P& -// p_array_bkd_piter_<P>::to_psite() const -// { -// return p_; -// } - -// template <typename P> -// inline -// const mln_point(P)& -// p_array_bkd_piter_<P>::to_point() const -// { -// return p_.to_point(); -// } - -// template <typename P> -// inline -// mln_coord(mln_point_(P)) -// p_array_bkd_piter_<P>::operator[](unsigned i) const -// { -// mln_precondition(i < dim); -// mln_precondition(is_valid()); -// return p_.to_point()[i]; -// } - -// template <typename P> -// inline -// bool -// p_array_bkd_piter_<P>::is_valid() const -// { -// return i_ >= 0; -// } - -// template <typename P> -// inline -// void -// p_array_bkd_piter_<P>::invalidate() -// { -// i_ = -1; -// } - -// template <typename P> -// inline -// void -// p_array_bkd_piter_<P>::start() -// { -// i_ = vect_.size() - 1; -// if (is_valid()) -// p_ = vect_[i_]; -// } - -// template <typename P> -// inline -// void -// p_array_bkd_piter_<P>::next_() -// { -// --i_; -// if (is_valid()) -// p_ = vect_[i_]; -// } - -// template <typename P> -// inline -// p_array_bkd_piter_<P>::operator P() const -// { -// mln_precondition(is_valid()); -// return p_; -// } + // Procedure. + + template <typename P, typename A> + int + index_of_in(const p_array_fwd_piter_<P>& p, const A& arr) + { + return index_of_in(p.unproxy(), arr); + } + + template <typename P, typename A> + int + index_of_in(const p_array_bkd_piter_<P>& p, const A& arr) + { + return index_of_in(p.unproxy(), arr); + } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/point2d.hh --- mln/core/point2d.hh (revision 1985) +++ mln/core/point2d.hh (working copy) @@ -61,6 +61,11 @@ { return internal::force_exact<const E>(*this).to_site().col(); } + C operator[](unsigned i) const + { + mln_precondition(i < 2); + return internal::force_exact<const E>(*this).to_site()[i]; + } }; Index: mln/core/concept/site_proxy.hh --- mln/core/concept/site_proxy.hh (revision 1985) +++ mln/core/concept/site_proxy.hh (working copy) @@ -107,6 +107,12 @@ }; + // Access to site reference. + + template <typename P> + const typename site_from<P>::ret& + to_site(const Object<P>& p); + } // end of namespace internal @@ -160,6 +166,39 @@ m2 = 0; } + namespace internal + { + + // Access to site reference. + + namespace deep + { + + template <typename P> + const typename site_from<P>::ret& + to_site(const Site_Proxy<P>& p) + { + return exact(p).to_site(); + } + + template <typename P> + const typename site_from<P>::ret& + to_site(const Object<P>& p) + { + return exact(p); + } + + } // end of namespace internal::deep + + template <typename P> + const typename site_from<P>::ret& + to_site(const Object<P>& p) + { + return deep::to_site(exact(p)); + } + + } // end of namespace mln::internal + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/site_iterator.hh --- mln/core/concept/site_iterator.hh (revision 1985) +++ mln/core/concept/site_iterator.hh (working copy) @@ -55,10 +55,11 @@ struct Site_Iterator : public Site_Proxy<E> { /* - bool is_valid() const; - void invalidate(); - void start(); + bool is_valid_() const; + void invalidate_(); + void start_(); void next_(); + const ..& target_() const; */ /*! \brief Go to the next element. @@ -71,6 +72,15 @@ */ void next(); // final + // FIXME: Doc!!! + bool is_valid() const; + void invalidate(); + void start(); + + /// Change of site set target. + template <typename T> + void change_target(const T& the); + protected: Site_Iterator(); }; @@ -80,8 +90,9 @@ # ifndef MLN_INCLUDE_ONLY template <typename E> + inline void - Site_Iterator<E>::next() // final + Site_Iterator<E>::next() { mln_precondition(exact(this)->is_valid()); exact(this)->next_(); @@ -89,13 +100,55 @@ template <typename E> inline + bool + Site_Iterator<E>::is_valid() const + { + E *const this_ = const_cast<E*const>(exact(this)); // Unconst. + if (this_->target_() == 0) + return false; + return exact(this)->is_valid_(); + } + + template <typename E> + inline + void + Site_Iterator<E>::invalidate() + { + if (exact(this)->target_() == 0) + return; // No-op. + exact(this)->invalidate_(); + } + + template <typename E> + inline + void + Site_Iterator<E>::start() + { + mln_precondition(exact(this)->target_() != 0); + exact(this)->start_(); + } + + 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() { - bool (E::*m1)() const = & E::is_valid; + bool m0 = (& E::target_) == (& E::target_); // FIXME: Find a better test. + m0 = 0; + bool (E::*m1)() const = & E::is_valid_; m1 = 0; - void (E::*m2)() = & E::invalidate; + void (E::*m2)() = & E::invalidate_; m2 = 0; - void (E::*m3)() = & E::start; + void (E::*m3)() = & E::start_; m3 = 0; void (E::*m4)() = & E::next_; m4 = 0; Index: mln/core/p_array.hh --- mln/core/p_array.hh (revision 1985) +++ mln/core/p_array.hh (working copy) @@ -83,7 +83,7 @@ const p_array<P>* target() const; - void change_target(const p_array<P>& arr); + const p_array<P>*& target(); private: @@ -136,7 +136,7 @@ typedef p_array_fwd_piter_<P> fwd_piter; /// Backward Site_Iterator associated type. - typedef p_array_fwd_piter_<P> bkd_piter; // HOT: FIXME + typedef p_array_bkd_piter_<P> bkd_piter; /// Constructor. p_array(); @@ -357,10 +357,10 @@ template <typename P> inline - void - p_array_psite<P>::change_target(const p_array<P>& arr) + const p_array<P>*& + p_array_psite<P>::target() { - arr_ = & arr; + return arr_; } template <typename P>
participants (1)
-
Thierry Geraud