Commit 1a052ebb authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Handle fwd iterations on p_array.

	* tests/core/p_array.cc: Add iteration test.
	* mln/core/internal/site_iterator_base.hh: New; based upon...
	* mln/core/internal/pseudo_site_base.hh: ...this.
	* mln/core/internal/pseudo_site_base.hh
	(subject, q_subject): New; factor those definitions.
	* mln/core/p_array_piter.hh (p_array_fwd_piter_): Update.
	(p_array_bkd_piter_): Deactivate.
	* mln/core/p_array.hh
	(p_array): Change into constant proxy; move defs into guards.
	(to_site): Delete mutable version.
	(change_target): New.
	* mln/core/concept/site_iterator.hh (operator site): Remove;
	that was obsolete code.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008@1972 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 260fc4a3
2008-05-26 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Handle fwd iterations on p_array.
* tests/core/p_array.cc: Add iteration test.
* mln/core/internal/site_iterator_base.hh: New; based upon...
* mln/core/internal/pseudo_site_base.hh: ...this.
* mln/core/internal/pseudo_site_base.hh
(subject, q_subject): New; factor those definitions.
* mln/core/p_array_piter.hh (p_array_fwd_piter_): Update.
(p_array_bkd_piter_): Deactivate.
* mln/core/p_array.hh
(p_array): Change into constant proxy; move defs into guards.
(to_site): Delete mutable version.
(change_target): New.
* mln/core/concept/site_iterator.hh (operator site): Remove;
that was obsolete code.
2008-05-23 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add the basics for pseudo sites; test on p_array.
......
......@@ -71,18 +71,6 @@ namespace mln
*/
void next(); // final
using Site_Proxy<E>::site;
/*! \brief Go to the next element.
*
* \warning This is a final method; iterator classes should not
* re-defined this method. The actual "next" operation has to be
* defined through the \em next_ method.
*
* \pre The iterator is valid.
*/
operator site() const;
protected:
Site_Iterator();
};
......@@ -99,14 +87,6 @@ namespace mln
exact(this)->next_();
}
template <typename E>
inline
Site_Iterator<E>::operator site() const
{
mln_precondition(exact(this)->is_valid());
return exact(this)->to_site();
}
template <typename E>
inline
Site_Iterator<E>::Site_Iterator()
......
......@@ -59,6 +59,12 @@ namespace mln
// The associated site type.
typedef typename internal::site_from<P>::ret site;
// The associated subject type (as a Proxy).
typedef P subject;
// The associated q_subject type (as a Proxy).
typedef const P& q_subject;
protected:
pseudo_site_base_();
};
......
// 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_ITERATOR_BASE_HH
# define MLN_CORE_INTERNAL_SITE_ITERATOR_BASE_HH
/*! \file mln/core/internal/site_iterator_base.hh
*
* \brief Base class to factor code for site iterator classes.
*/
# include <mln/core/concept/site_iterator.hh>
namespace mln
{
namespace internal
{
/*! \internal A base class for site iterators.
*
* Parameter \c P is FIXME: a point site type.
*/
template <typename P, typename E>
struct site_iterator_base_ : Site_Iterator<E>,
proxy_impl<P, E>,
site_impl< false, // Constant access to site / subject.
typename site_from<P>::ret,
E >
{
// The associated site type.
typedef typename internal::site_from<P>::ret site;
// The associated subject type (as a Proxy).
typedef P subject;
// The associated q_subject type (as a Proxy).
typedef const P& q_subject;
/*! \brief Conversion towards the site it designates.
*
* \warning This is a final method; iterator classes should not
* re-defined this method.
*
* \pre The iterator is valid.
*/
operator site() const;
protected:
site_iterator_base_();
};
#ifndef MLN_INCLUDE_ONLY
template <typename P, typename E>
inline
site_iterator_base_<P, E>::site_iterator_base_()
{
}
template <typename P, typename E>
inline
site_iterator_base_<P, E>::operator site() const
{
typedef proxy_impl<P, E> super;
mln_precondition(exact(this)->is_valid());
return this->super::operator site();
}
#endif // ! MLN_INCLUDE_ONLY
} // end of namespace internal
} // end of namespace mln
#endif // ! MLN_CORE_INTERNAL_SITE_ITERATOR_BASE_HH
......@@ -49,10 +49,10 @@ namespace mln
template <typename P> struct p_array_bkd_piter_;
// HOT...
// p_array_psite<P>
template <typename P>
class p_array_psite : public internal::pseudo_site_base_< true, // Mutable.
class p_array_psite : public internal::pseudo_site_base_< false, // Not mutable.
P,
p_array_psite<P> >
{
......@@ -63,59 +63,33 @@ namespace mln
// As a Proxy:
typedef P subject;
typedef const P& q_subject;
q_subject unproxy() const;
P& unproxy();
const P& unproxy() const;
// As a Site_Proxy:
typedef typename super::site site;
const site& to_site() const
{
const site* s;
internal::get_adr(s, *this);
return *s;
}
site& to_site()
{
site* s;
internal::get_adr(s, *this);
return *s;
}
const site& to_site() const;
// As Itself.
p_array_psite()
: arr_(0),
i_(0)
{
}
p_array_psite();
p_array_psite(p_array<P>& arr, unsigned i)
: arr_(&arr),
i_(int(i))
{
}
p_array_psite(const p_array<P>& arr, int i);
int index() const
{
return i_;
}
int index() const;
const p_array<P>* target() const
{
return arr_;
}
int& index();
void print() const
{
std::cout << i_ << "-th site of " << arr_ << " => site " << to_site() << std::endl;
}
const p_array<P>* target() const;
void change_target(const p_array<P>& arr);
void print() const;
p_array<P>* arr_; // FIXME: Or const!
private:
const p_array<P>* arr_;
int i_;
};
......@@ -159,7 +133,7 @@ namespace mln
typedef p_array_fwd_piter_<P> fwd_piter;
/// Backward Point_Iterator associated type.
typedef p_array_bkd_piter_<P> bkd_piter;
typedef p_array_fwd_piter_<P> bkd_piter; // HOT: FIXME
/// Constructor.
p_array();
......@@ -235,7 +209,7 @@ namespace mln
p_array<P>::has(const psite& p) const
{
mln_precondition(p.target() == this); // FIXME: Refine.
if (p.index() < 0 || p.index() >= vect_.size())
if (p.index() < 0 || p.index() >= int(vect_.size()))
return false;
site s_ = (*this)[p.index()];
mln_invariant(p.to_site() == s_);
......@@ -308,17 +282,74 @@ namespace mln
template <typename P>
inline
const P&
p_array_psite<P>::unproxy() const
p_array_psite<P>::p_array_psite()
: arr_(0),
i_(0)
{
mln_precondition(arr_ != 0);
return (*arr_)[i_];
}
template <typename P>
inline
P&
p_array_psite<P>::unproxy()
p_array_psite<P>::p_array_psite(const p_array<P>& arr, int i)
: arr_(&arr),
i_(i)
{
}
template <typename P>
inline
const typename p_array_psite<P>::site&
p_array_psite<P>::to_site() const
{
const site* s;
internal::get_adr(s, *this);
return *s;
}
template <typename P>
inline
int
p_array_psite<P>::index() const
{
return i_;
}
template <typename P>
inline
int&
p_array_psite<P>::index()
{
return i_;
}
template <typename P>
inline
const p_array<P>*
p_array_psite<P>::target() const
{
return arr_;
}
template <typename P>
inline
void
p_array_psite<P>::change_target(const p_array<P>& arr)
{
arr_ = & arr;
}
template <typename P>
inline
void
p_array_psite<P>::print() const
{
std::cout << i_ << "-th site of " << arr_ << " => site " << to_site() << std::endl;
}
template <typename P>
inline
const P&
p_array_psite<P>::unproxy() const
{
mln_precondition(arr_ != 0);
return (*arr_)[i_];
......
......@@ -32,6 +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>
namespace mln
......@@ -39,32 +40,24 @@ namespace mln
/// \brief Forward iterator on points of a p_array<P>.
template <typename P>
struct p_array_fwd_piter_
: public internal::point_iterator_base_< P, p_array_fwd_piter_<P> >
class p_array_fwd_piter_
:
public internal::site_iterator_base_< p_array_psite<P>,
p_array_fwd_piter_<P> >
{
typedef p_array_fwd_piter_<P> self_;
typedef internal::point_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 };
typedef p_array_fwd_piter_<P> self;
typedef internal::site_iterator_base_<p_array_psite<P>, self> super;
/// Coordinate associated type.
template <typename S>
p_array_fwd_piter_(const Site_Set<S>& s);
public:
/// Reference of the corresponding psite.
const psite& to_psite() const;
/// Constructor with no argument.
p_array_fwd_piter_();
/// Reference of the corresponding point.
const point& to_point() const;
/// Constructor.
p_array_fwd_piter_(const p_array<P>& arr);
/// Read-only access to the \p i-th coordinate.
mln_coord(point) operator[](unsigned i) const;
/// Change of site set target.
void change_target(const p_array<P>& arr);
/// Test if the iterator is valid.
bool is_valid() const;
......@@ -78,73 +71,75 @@ namespace mln
/// Go to the next point.
void next_();
/// Convert the iterator into a psite.
operator psite() const;
/// Return the subject.
const p_array_psite<P>& unproxy() const;
// As a Site_Proxy:
typedef typename super::site site;
const site& to_site() const;
protected:
const std::vector<P>& vect_;
// FIXME: Why it's unsigned in fwd iterator and signed in the bkd one ?
unsigned i_;
psite p_;
p_array_psite<P> p_;
};
/// \brief Backward iterator on points of a p_array<P>.
template <typename P>
struct p_array_bkd_piter_
: public internal::point_iterator_base_< P, p_array_bkd_piter_<P> >
{
typedef p_array_bkd_piter_<P> self_;
typedef internal::point_iterator_base_< P, self_ > super_;
public:
/// The associated psite type.
typedef P psite;
// /// \brief Backward iterator on points of a p_array<P>.
// template <typename P>
// struct p_array_bkd_piter_
// : public internal::point_iterator_base_< P, p_array_bkd_piter_<P> >
// {
// typedef p_array_bkd_piter_<P> self_;
// typedef internal::point_iterator_base_< P, self_ > super_;
// public:
// /// The associated psite type.
// typedef P psite;
/// The associated point type.
typedef mln_point(P) point;
// /// The associated point type.
// typedef mln_point(P) point;
enum { dim = super_::dim };
// enum { dim = super_::dim };
/// Coordinate associated type.
template <typename S>
p_array_bkd_piter_(const Site_Set<S>& s);
// /// 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 psite.
// const psite& to_psite() const;
/// Reference of the corresponding point.
const point& to_point() 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;
// /// 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;
// /// Test if the iterator is valid.
// bool is_valid() const;
/// Invalidate the iterator.
void invalidate();
// /// Invalidate the iterator.
// void invalidate();
/// Start an iteration.
void start();
// /// Start an iteration.
// void start();
/// Go to the next point.
void next_();
// /// Go to the next point.
// void next_();
/// Convert the iterator into a psite.
operator psite() const;
// /// 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_;
};
// 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_;
// };
......@@ -155,38 +150,25 @@ namespace mln
`------------------------*/
template <typename P>
template <typename S>
inline
p_array_fwd_piter_<P>::p_array_fwd_piter_(const Site_Set<S>& s)
: vect_(exact(s).vect())
p_array_fwd_piter_<P>::p_array_fwd_piter_()
{
invalidate();
}
template <typename P>
inline
const P&
p_array_fwd_piter_<P>::to_psite() const
p_array_fwd_piter_<P>::p_array_fwd_piter_(const p_array<P>& arr)
{
return p_;
change_target(arr);
}
template <typename P>
inline
const mln_point(P)&
p_array_fwd_piter_<P>::to_point() const
{
return p_.to_point();
}
template <typename P>
inline
mln_coord(mln_point_(P))
p_array_fwd_piter_<P>::operator[](unsigned i) const
void
p_array_fwd_piter_<P>::change_target(const p_array<P>& arr)
{
mln_precondition(i < dim);
mln_precondition(is_valid());
return p_.to_point()[i];
p_.change_target(arr);
invalidate();
}
template <typename P>
......@@ -194,7 +176,7 @@ namespace mln
bool
p_array_fwd_piter_<P>::is_valid() const
{
return i_ < vect_.size();
return p_.target() != 0 && p_.index() < int(p_.target()->nsites());
}
template <typename P>
......@@ -202,7 +184,8 @@ namespace mln
void
p_array_fwd_piter_<P>::invalidate()
{
i_ = vect_.size();
if (p_.target() != 0)
p_.index() = p_.target()->nsites();
}
template <typename P>
......@@ -210,9 +193,8 @@ namespace mln
void
p_array_fwd_piter_<P>::start()
{
i_ = 0;
if (is_valid())
p_ = vect_[i_];
mln_precondition(p_.target() != 0);
p_.index() = 0;
}
template <typename P>
......@@ -220,102 +202,108 @@ namespace mln
void
p_array_fwd_piter_<P>::next_()
{
++i_;
if (is_valid())
p_ = vect_[i_];
++p_.index();
}
template <typename P>
inline