cleanup-2008 1971: Add the basics for pseudo sites; test on p_array.
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add the basics for pseudo sites; test on p_array. * tests/core/p_array.cc: New. * doc/technical: New. * doc/technical/designs: New. * doc/technical/designs/site_psite_piter: New. * doc/technical/designs/site_psite_piter/README: New. * mln/core/macros.hh (mln_subject, mln_subject_): New. * mln/core/point.hh: New comment. * mln/core/internal/point_set_base.hh: . * mln/core/internal/pseudo_site_base.hh: New. * mln/core/p_array_bb.hh: New. * mln/core/point2d.hh (site_const_impl, site_mutable_impl): New specialization. * mln/core/p_array.hh (p_array_psite): New. (npoints): Rename as... (nsites): ...this. (bbox, bb_, bb_needs_update_, hook_): Remove. (has): Update sig with the new psite type; adapt body. * mln/core/concept/proxy.hh: New. * mln/core/concept/point_set.hh: . * mln/core/concept/site_proxy.hh: New. * mln/core/concept/pseudo_site.hh: New. * mln/core/concept/site_iterator.hh: New. doc/technical/designs/site_psite_piter/README | 39 ++++ mln/core/concept/point_set.hh | 3 mln/core/concept/proxy.hh | 233 ++++++++++++++++++++++++++ mln/core/concept/pseudo_site.hh | 86 +++++++++ mln/core/concept/site_iterator.hh | 54 +++--- mln/core/concept/site_proxy.hh | 168 ++++++++++++++++++ mln/core/internal/point_set_base.hh | 8 mln/core/internal/pseudo_site_base.hh | 82 +++++++++ mln/core/macros.hh | 6 mln/core/p_array.hh | 213 ++++++++++++++++------- mln/core/point.hh | 2 mln/core/point2d.hh | 51 +++++ tests/core/p_array.cc | 65 +++++++ 13 files changed, 920 insertions(+), 90 deletions(-) Index: tests/core/p_array.cc --- tests/core/p_array.cc (revision 0) +++ tests/core/p_array.cc (revision 0) @@ -0,0 +1,65 @@ +// 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. + +/*! \file tests/core/p_array.cc + * + * \brief Tests on mln::p_array. + */ + +#include <iterator> + +#include <mln/core/point2d.hh> +#include <mln/core/p_array.hh> + + + +int main() +{ + using namespace mln; + + typedef p_array<point2d> Arr; + + Arr pa; + pa + .append(make::point2d(6, 9)) + .append(make::point2d(4, 2)) + .append(make::point2d(4, 2)) + .append(make::point2d(5, 1)); + mln_assertion(pa.nsites() == 4); + + mlc_equal( mln_psite_(Arr)::site, point2d )::check(); + + mln_psite_(Arr) p(pa, 0); + std::cout << p.to_site() << ' ' + << p.row() << ' ' + << point2d(p) << ' ' + << std::endl; + + std::copy(pa.vect().begin(), pa.vect().end(), + std::ostream_iterator<point2d>(std::cout, " ")); + std::cout << std::endl; +} Index: doc/technical/designs/site_psite_piter/README --- doc/technical/designs/site_psite_piter/README (revision 0) +++ doc/technical/designs/site_psite_piter/README (revision 0) @@ -0,0 +1,39 @@ + + -*- outline -*- + +* design + + Object + ^ + | + Proxy + + subject + ^ + | + Site_Proxy< Site, Exact > + + site : type = Site + + op site + ^ + ______|______ + | | +Pseudo_Site Site_Iterator + ^ ^ + | | + + + + internal::psite_impl< Site, Exact > + // to be specialized... + ^ + ______________/ + / +pseudo_site_base_< Site, Exact > + + + + internal::piter_impl + + op psite, iff psite != site + ^ + ___________________/ + / + Index: mln/core/macros.hh --- mln/core/macros.hh (revision 1970) +++ mln/core/macros.hh (working copy) @@ -251,6 +251,12 @@ # define mln_site_(T) T::site /// \} +/// Shortcuts to access the subject type associated to T. +/// \{ +# define mln_subject(T) typename T::subject +# define mln_subject_(T) T::subject +/// \} + // v Index: mln/core/point.hh --- mln/core/point.hh (revision 1970) +++ mln/core/point.hh (working copy) @@ -59,6 +59,8 @@ namespace internal { + // Helper point_to_. + template <typename M, typename C> struct point_to_ { Index: mln/core/internal/point_set_base.hh --- mln/core/internal/point_set_base.hh (revision 1970) +++ mln/core/internal/point_set_base.hh (working copy) @@ -34,7 +34,10 @@ */ # include <mln/core/concept/point_set.hh> +# include <mln/core/concept/site_proxy.hh> # include <mln/core/grids.hh> +# include <mln/metal/is_a.hh> +# include <mln/metal/if.hh> namespace mln @@ -43,17 +46,16 @@ namespace internal { + /*! \internal A base class for site set classes. * \p P is a psite type. */ template <typename P, typename E> struct site_set_base_ : public Site_Set<E> { - /// PSite associated type. - typedef P psite; /// Site associated type. - typedef mln_site(P) site; + typedef typename internal::site_from<P>::ret site; protected: site_set_base_(); Index: mln/core/internal/pseudo_site_base.hh --- mln/core/internal/pseudo_site_base.hh (revision 0) +++ mln/core/internal/pseudo_site_base.hh (revision 0) @@ -0,0 +1,82 @@ +// 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_PSEUDO_SITE_BASE_HH +# define MLN_CORE_INTERNAL_PSEUDO_SITE_BASE_HH + +/*! \file mln/core/internal/pseudo_site_base.hh + * + * \brief Base class to factor code for pseudo site classes. + */ + +# include <mln/core/concept/pseudo_site.hh> + + +namespace mln +{ + + namespace internal + { + + /*! \internal A base class for pseudo sites. + * + * Parameter \c P is FIXME: a point site type. + */ + template <bool is_mutable, typename P, typename E> + struct pseudo_site_base_ : Pseudo_Site<E>, + + proxy_impl<P, E>, + + site_impl< is_mutable, + typename site_from<P>::ret, + E > + { + + // The associated site type. + typedef typename internal::site_from<P>::ret site; + + protected: + pseudo_site_base_(); + }; + + +#ifndef MLN_INCLUDE_ONLY + + template <bool is_mutable, typename P, typename E> + inline + pseudo_site_base_<is_mutable, P, E>::pseudo_site_base_() + { + } + +#endif // ! MLN_INCLUDE_ONLY + + } // end of namespace internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_PSEUDO_SITE_BASE_HH Index: mln/core/point2d.hh --- mln/core/point2d.hh (revision 1970) +++ mln/core/point2d.hh (working copy) @@ -35,11 +35,62 @@ */ # include <mln/core/point.hh> +# include <mln/core/concept/site_proxy.hh> // For site_const_impl and site_mutable_impl. +# include <mln/core/internal/force_exact.hh> namespace mln { + namespace internal + { + + // Specialization. + + template <typename C, typename E> + struct site_const_impl< point_<grid::square, C>, E > + { + // Either unproxy() or to_site() can be used below. In the + // former case, the unproxied features ind() because it is a + // point_ or another proxy to a point_. + C row() const + { + return internal::force_exact<const E>(*this).to_site().row(); + } + C col() const + { + return internal::force_exact<const E>(*this).to_site().col(); + } + }; + + + // Specialization for point_<M,C>. + + template <typename C, typename E> + struct site_mutable_impl< point_<grid::square, C>, E > : + site_const_impl < point_<grid::square, C>, E > + { + private: + typedef site_const_impl< point_<grid::square, C>, E > super; + public: + + using super::row; + using super::col; + + C& row() + { + return internal::force_exact<E>(*this).to_site().row(); + } + C& col() + { + return internal::force_exact<E>(*this).to_site().col(); + } + }; + + } // end of namespace mln::internal + + + /*! \brief Type alias for a point defined on the 2D square grid with * integer coordinates. */ Index: mln/core/p_array.hh --- mln/core/p_array.hh (revision 1970) +++ mln/core/p_array.hh (working copy) @@ -36,6 +36,7 @@ # include <vector> # include <mln/core/internal/point_set_base.hh> +# include <mln/core/internal/pseudo_site_base.hh> # include <mln/accu/bbox.hh> @@ -43,28 +44,116 @@ { // Fwd decls. + template <typename P> class p_array; template <typename P> struct p_array_fwd_piter_; template <typename P> struct p_array_bkd_piter_; - /*! \brief Point set class based on std::vector. - * - * This is a multi-set of points. - * - * \warning We have some troubles with point set comparison based on - * a call to npoints(). FIXME: Explain! + // HOT... + + template <typename P> + class p_array_psite : public internal::pseudo_site_base_< true, // Mutable. + P, + p_array_psite<P> > + { + typedef p_array_psite<P> self; + typedef internal::pseudo_site_base_<true, P, self> super; + + public: + + // As a Proxy: + + typedef P subject; + typedef const P& q_subject; + q_subject unproxy() const; + P& unproxy(); + + // 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; + } + + // As Itself. + + p_array_psite() + : arr_(0), + i_(0) + { + } + + p_array_psite(p_array<P>& arr, unsigned i) + : arr_(&arr), + i_(int(i)) + { + } + + int index() const + { + return i_; + } + + const p_array<P>* target() const + { + return arr_; + } + + void print() const + { + std::cout << i_ << "-th site of " << arr_ << " => site " << to_site() << std::endl; + } + + p_array<P>* arr_; // FIXME: Or const! + int i_; + }; + + + + + namespace trait + { + + template <typename P> + struct site_set_< p_array<P> > + { + typedef trait::site_set::nsites::known nsites; + typedef trait::site_set::bbox::unknown bbox; + typedef trait::site_set::contents::free contents; + typedef trait::site_set::arity::multiple arity; + }; + + } // end of namespace trait + + + + + /*! \brief Site set class based on std::vector. * - * \todo Make it work with P being a Point_Site. + * This is a multi-set of sites. */ template <typename P> class p_array : public internal::site_set_base_< P, p_array<P> > { + typedef internal::site_set_base_< P, p_array<P> > super; public: + /// The associated psite type. - typedef P psite; + typedef p_array_psite<P> psite; - /// The associated point type. - typedef mln_point(P) point; + /// The associated site type. + typedef typename super::site site; /// Forward Point_Iterator associated type. typedef p_array_fwd_piter_<P> fwd_piter; @@ -81,14 +170,13 @@ /// Reserve \p n cells. void reserve(std::size_t n); - /// Test is \p p belongs to this point set. + /// Test is \p p belongs to this site set. bool has(const psite& p) const; - /// Give the number of points. - std::size_t npoints() const; + // FIXME: Add an overload "has(index)". - /// Give the exact bounding box. - const box_<point>& bbox() const; + /// Give the number of sites. + std::size_t nsites() const; /// Append a point \p p. p_array<P>& append(const P& p); @@ -102,31 +190,28 @@ /// Return the corresponding std::vector of points. const std::vector<P>& vect() const; - /// Return the \p i-th point. + /// Return the \p i-th site (constant). const P& operator[](unsigned i) const; - /// Hook to data. - std::vector<P>& hook_(); + /// Return the \p i-th site (mutable). + P& operator[](unsigned i); protected: std::vector<P> vect_; - mutable accu::bbox<point> bb_; - mutable bool bb_needs_update_; - - void update_bb_() const; - // FIXME: Add invariant bb_.is_valid() <=> npoints() != 0 }; # ifndef MLN_INCLUDE_ONLY + + // p_array<P> + template <typename P> inline p_array<P>::p_array() { - bb_needs_update_ = false; } template <typename P> @@ -134,7 +219,6 @@ p_array<P>::p_array(const std::vector<P>& vect) : vect_(vect) { - bb_needs_update_ = true; } template <typename P> @@ -147,61 +231,31 @@ template <typename P> inline - std::vector<P>& - p_array<P>::hook_() - { - return vect_; - } - - template <typename P> - inline - void - p_array<P>::update_bb_() const - { - bb_.init(); - for (unsigned i = 0; i < vect_.size(); ++i) - bb_.take(vect_[i]); - bb_needs_update_ = false; - } - - template <typename P> - inline bool - p_array<P>::has(const P& p) const + p_array<P>::has(const psite& p) const { - for (unsigned i = 0; i < vect_.size(); ++i) - if (vect_[i] == p) - return true; + mln_precondition(p.target() == this); // FIXME: Refine. + if (p.index() < 0 || p.index() >= vect_.size()) return false; + site s_ = (*this)[p.index()]; + mln_invariant(p.to_site() == s_); + return true; } template <typename P> inline std::size_t - p_array<P>::npoints() const + p_array<P>::nsites() const { return vect_.size(); } template <typename P> inline - const box_<mln_point(P)>& - p_array<P>::bbox() const - { - mln_precondition(npoints() != 0); - if (bb_needs_update_) - update_bb_(); - return bb_.to_result(); - } - - template <typename P> - inline p_array<P>& p_array<P>::append(const P& p) { vect_.push_back(p); - if (! bb_needs_update_) - bb_needs_update_ = true; return *this; } @@ -212,8 +266,6 @@ { vect_.insert(vect_.end(), other.vect().begin(), other.vect().end()); - if (! bb_needs_update_) - bb_needs_update_ = true; return *this; } @@ -223,7 +275,6 @@ p_array<P>::clear() { vect_.clear(); - bb_needs_update_ = false; } template <typename P> @@ -239,10 +290,40 @@ const P& p_array<P>::operator[](unsigned i) const { - mln_precondition(i < npoints()); + mln_precondition(i < nsites()); return vect_[i]; } + template <typename P> + inline + P& + p_array<P>::operator[](unsigned i) + { + mln_precondition(i < nsites()); + return vect_[i]; + } + + + // p_array_psite<P> + + template <typename P> + inline + const P& + p_array_psite<P>::unproxy() const + { + mln_precondition(arr_ != 0); + return (*arr_)[i_]; + } + + template <typename P> + inline + P& + p_array_psite<P>::unproxy() + { + mln_precondition(arr_ != 0); + return (*arr_)[i_]; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/concept/proxy.hh --- mln/core/concept/proxy.hh (revision 0) +++ mln/core/concept/proxy.hh (revision 0) @@ -0,0 +1,233 @@ +// 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_CONCEPT_PROXY_HH +# define MLN_CORE_CONCEPT_PROXY_HH + +/*! \file mln/core/concept/proxy.hh + * + * \brief Definition of the concept of mln::Proxy. + */ + +# include <mln/core/concept/object.hh> +# include <mln/trait/all.hh> + + + +namespace mln +{ + + // Fwd decls. + template <typename E> struct Proxy; + + + /* + FIXME: Re-activate. + + namespace trait + { + + template < typename Op, typename P1, typename P2 > + struct set_binary_< Op, mln::Proxy, P1, mln::Proxy, P2 > + { + typedef mln_trait_binary(Op, mln_subject(P1), mln_subject(P2)) ret; + }; + + template < typename Op, typename P, typename O > + struct set_binary_< Op, mln::Proxy, P, mln::Object, O > + { + typedef mln_trait_binary(Op, mln_subject(P), O) ret; + }; + + template < typename Op, typename E, typename P > + struct set_binary_< Op, mln::Object, E, mln::Proxy, P > + { + typedef mln_trait_binary(Op, O, mln_subject(P)) ret; + }; + + template < typename Op, typename P > + struct set_binary_< Op, mln::Proxy, P > + { + typedef mln_trait_unary(Op, mln_subject(P)) ret; + }; + + } // end of namespace mln::trait + + */ + + + + /// Proxy category flag type. + template <> + struct Proxy<void> + { + typedef Object<void> super; + }; + + + /*! \brief Base class for implementation classes of the notion of + * "proxy". + */ + template <typename E> + struct Proxy : public Object<E> + { + typedef Proxy<void> category; + + /* + typedef subject; + typedef q_subject; + q_subject unproxy() const; + + // FIXME: + // return "const subject&"? + // overload with not-const method? + // add op subject() const? + */ + protected: + Proxy(); + }; + + + namespace internal + { + + // External way of getting an address of an object from/through a + // proxy. This is a recursive implementation since we can have a + // proxy of proxy, etc. + + // Case 1: Not found so unproxy. + + template <typename T, typename P> + void get_adr(const T *& ptr, const Proxy<P>& obj) + { + get_adr(ptr, exact(obj).unproxy()); + } + + template <typename T, typename P> + void get_adr( T *& ptr, Proxy<P>& obj) + { + get_adr(ptr, exact(obj).unproxy()); + } + + // Case 2: Found. (Note that T can also be a Proxy.) + + template <typename T> + void get_adr(const T *& ptr, const Object<T>& obj) + { + ptr = & exact(obj); + } + + template <typename T> + void get_adr( T *& ptr, Object<T>& obj) + { + ptr = & exact(obj); + } + + // Case 3: Fail to found! + + template <typename T, typename O> + void get_adr(const T *& ptr, const Object<O>& obj); + + template <typename T, typename O> + void get_adr( T *& ptr, Object<O>& obj) + { + return 0; + } + + + // A proxy should convert towards its subject. And, if we have a + // proxy of proxy, it should also convert towards its subject of + // subject, and so on. It leads to a recursive implementation + // where conversions are automatically obtained through + // inheritance. + // + // E is a Proxy type; Subject is its subject type. + + template <typename Subject, typename E> struct proxy_impl; + + template <typename Subject, typename E, bool rec = true> + struct helper_proxy_impl : proxy_impl< mln_subject(Subject), E > // Rec. + {}; + + template <typename Subject, typename E> + struct helper_proxy_impl< Subject, E, false > // Stop rec. + {}; + + template <typename Subject, typename E> + struct proxy_impl : helper_proxy_impl< Subject, E, + mlc_is_a(Subject, Proxy)::value > + { + operator Subject() const + { + const Subject* adr; + get_adr(adr, mln::internal::force_exact<const E>(*this)); + return *adr; + } + }; + + + } // end of namespace mln::internal + + + // FIXME:... + +// template <typename L, typename R> +// bool operator==(const Proxy<L>& lhs, const Proxy<R>& rhs); + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p); + + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + inline + Proxy<E>::Proxy() + { + typedef mln_subject(E) subject; + typedef typename E::q_subject q_subject; + + q_subject (E::*m)() const = & E::unproxy; + m = 0; + } + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const Proxy<P>& p) + { + return ostr << exact(p).unproxy(); + } + + // FIXME: Code operators... + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_PROXY_HH Index: mln/core/concept/point_set.hh --- mln/core/concept/point_set.hh (revision 1970) +++ mln/core/concept/point_set.hh (working copy) @@ -39,6 +39,7 @@ # include <mln/core/concept/point_iterator.hh> # include <mln/trait/site_sets.hh> # include <mln/metal/not_equal.hh> +# include <mln/metal/is_a.hh> namespace mln @@ -147,6 +148,8 @@ mlc_not_equal( mln_trait_site_set_bbox(E), mln::trait::undef )::check(); mlc_not_equal( mln_trait_site_set_contents(E), mln::trait::undef )::check(); mlc_not_equal( mln_trait_site_set_arity(E), mln::trait::undef )::check(); + // FIXME: also test something like + // mlc_is_a( mln_trait_site_set_nsites(E), mln::trait::site_set::nsites::any )::check(); // Check associated types. typedef mln_site(E) site; Index: mln/core/concept/site_proxy.hh --- mln/core/concept/site_proxy.hh (revision 0) +++ mln/core/concept/site_proxy.hh (revision 0) @@ -0,0 +1,168 @@ +// 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_CONCEPT_SITE_PROXY_HH +# define MLN_CORE_CONCEPT_SITE_PROXY_HH + +/*! \file mln/core/concept/site_proxy.hh + * + * \brief Definition of the concept of mln::Site_Proxy. + */ + +# include <mln/core/concept/proxy.hh> +# include <mln/metal/is_a.hh> + + + +namespace mln +{ + + + // Fwd decl. + template <typename E> struct Site_Proxy; + + + + namespace internal + { + // Every "Site_Proxy" class should derive from site_impl. The + // couple of classes below are provided to be specialized so that + // an effective implementation (with the interface of the + // targetted site) can equip site proxy classes. + + template <typename Site, typename E> + struct site_const_impl + { + // Default is none. + }; + + template <typename Site, typename E> + struct site_mutable_impl + { + // Default is none. + }; + + template <bool is_mutable, typename Site, typename E> + struct site_impl; // Is a selector w.r.t. to mutability. + + template <typename Site, typename E> + struct site_impl</* is_mutable = */ true, Site, E> : site_mutable_impl<Site, E> + { + }; + + template <typename Site, typename E> + struct site_impl</* is_mutable = */ false, Site, E> : site_const_impl<Site, E> + { + }; + + + + // Meta-routine to get the site type from either a site or a site + // proxy. + + template <typename P> struct site_from; + + template <typename P, bool is_proxy = true> + struct helper_site_from + { + typedef typename P::subject P_; + typedef typename site_from<P_>::ret ret; + }; + + template <typename P> + struct helper_site_from<P, false> + { + typedef P ret; + }; + + template <typename P> + struct site_from + { + enum { is_proxy = mlc_is_a(P, Site_Proxy)::value }; + typedef typename helper_site_from< P, is_proxy >::ret ret; + }; + + + + } // end of namespace internal + + + + + /// Site_Proxy category flag type. + template <> + struct Site_Proxy<void> + { + typedef Proxy<void> super; + }; + + + /*! \brief Base class for implementation classes of the notion of + * "site proxy". + * + * FIXME: Explain... + */ + template <typename E> + struct Site_Proxy : public Proxy<E> + { + typedef Site_Proxy<void> category; + + /* + typedef site; + + const site& to_site() const; + operator site() const; + + FIXME: Add if possible a mutable version of to_site(). + FIXME: Or (?) just remove this method (!) + */ + + protected: + Site_Proxy(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Site_Proxy<E>::Site_Proxy() + { + typedef mln_site(E) site; + + const site& (E::*m1)() const = & E::to_site; + m1 = 0; + + site (E::*m2)() const = & E::operator site; + m2 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_SITE_PROXY_HH Index: mln/core/concept/pseudo_site.hh --- mln/core/concept/pseudo_site.hh (revision 0) +++ mln/core/concept/pseudo_site.hh (revision 0) @@ -0,0 +1,86 @@ +// 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_CONCEPT_PSEUDO_SITE_HH +# define MLN_CORE_CONCEPT_PSEUDO_SITE_HH + +/*! \file mln/core/concept/pseudo_site.hh + * + * \brief Definition of the concept of mln::Pseudo_Site. + */ + +# include <mln/core/concept/site_proxy.hh> +# include <mln/metal/is_a.hh> + + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Pseudo_Site; + + + + /// Pseudo_Site category flag type. + template <> + struct Pseudo_Site<void> + { + typedef Site_Proxy<void> super; + }; + + + /*! \brief Base class for implementation classes of the notion of + * "pseudo site". + * + * FIXME: Explain... + */ + template <typename E> + struct Pseudo_Site : public Site_Proxy<E> + { + typedef Pseudo_Site<void> category; + + + protected: + Pseudo_Site(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Pseudo_Site<E>::Pseudo_Site() + { + // FIXME + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_PSEUDO_SITE_HH Index: mln/core/concept/site_iterator.hh --- mln/core/concept/site_iterator.hh (revision 1951) +++ mln/core/concept/site_iterator.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,17 +25,17 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_CORE_CONCEPT_POINT_ITERATOR_HH -# define MLN_CORE_CONCEPT_POINT_ITERATOR_HH +#ifndef MLN_CORE_CONCEPT_SITE_ITERATOR_HH +# define MLN_CORE_CONCEPT_SITE_ITERATOR_HH -/*! \file mln/core/concept/point_iterator.hh +/*! \file mln/core/concept/site_iterator.hh * - * \brief Definition of the concept of mln::Point_Iterator. + * \brief Definition of the concept of mln::Site_Iterator. * - * \todo Fix mln/core/concept/doc/point_iterator.hh + * \todo Fix mln/core/concept/doc/site_iterator.hh */ -# include <mln/core/concept/point_site.hh> +# include <mln/core/concept/site_proxy.hh> # include <mln/core/concept/iterator.hh> // To fetch the macros. @@ -48,19 +48,17 @@ * An iterator on points is an iterator that browse over a set of * points. * - * \see mln::doc::Point_Iterator for a complete documentation of this class + * \see mln::doc::Site_Iterator for a complete documentation of this class * contents. */ template <typename E> - struct Point_Iterator : public Point_Site<E> + struct Site_Iterator : public Site_Proxy<E> { /* - typedef psite; bool is_valid() const; void invalidate(); void start(); void next_(); - operator psite() const; */ /*! \brief Go to the next element. @@ -73,8 +71,20 @@ */ 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: - Point_Iterator(); + Site_Iterator(); }; @@ -83,22 +93,24 @@ template <typename E> void - Point_Iterator<E>::next() // final + Site_Iterator<E>::next() // final { - assert(exact(this)->is_valid()); + mln_precondition(exact(this)->is_valid()); exact(this)->next_(); } template <typename E> inline - Point_Iterator<E>::Point_Iterator() + Site_Iterator<E>::operator site() const { - typedef mln_psite(E) psite; - mln::metal::is_a<psite, Point_Site>::check(); - - psite (E::*m)() const = & E::operator psite; - m = 0; + mln_precondition(exact(this)->is_valid()); + return exact(this)->to_site(); + } + template <typename E> + inline + Site_Iterator<E>::Site_Iterator() + { bool (E::*m1)() const = & E::is_valid; m1 = 0; void (E::*m2)() = & E::invalidate; @@ -114,4 +126,4 @@ } // end of namespace mln -#endif // ! MLN_CORE_CONCEPT_POINT_ITERATOR_HH +#endif // ! MLN_CORE_CONCEPT_SITE_ITERATOR_HH
participants (1)
-
Thierry Geraud