Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
November 2008
- 14 participants
 - 266 discussions
 
17 Nov '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Cleanup basic graph class and related materials.
	* mln/core/site_set/p_graph_piter.hh: Upgrade doc style.
	(operator<<): Remove; useless.
	* mln/core/site_set/p_vertices.hh
	(vertex, graph_element): New typedefs.
	(graph_t): Remove; use explicitly G instead.
	* mln/core/site_set/p_edges.hh
	(edge, graph_element): New typedefs.
	(graph_t): Remove; use explicitly G instead.
	* mln/util/graph.hh: Layout.
	* mln/util/internal/graph_base.hh (graph_id): Fix return type.
	That avoids a warning at compile-time.
	* mln/core/concept/graph.hh: Update.
	* mln/util/internal/graph_iter.hh: Layout.
	* mln/util/internal/graph_edge.hh: Upgrade doc style.
	(operator<<): Fix missing const.
	(edge::edge): Prefer invalidate over id_ set to 0.
	(FIXME): New.
	(invalidate): Set id_ to unsigned max value; less error-prone.
	(graph_t): Use instead explicit...
	(G): ...parameter type.
	* mln/util/internal/graph_edge_psite.hh: Upgrade doc style.
	(target_t, edge_t): Use instead the explicit...
	(p_edges, util::edge): ...types.
	* mln/util/internal/graph_vertex.hh
	(vertex::vertex): Prefer invalidate over id_ set to 0.
	(FIXME): New.
	(invalidate): Set id_ to unsigned max value; less error-prone.
	(graph_t): Use instead explicit...
	(G): ...parameter type.
	Fix doc.
	* mln/util/internal/graph_psite_base.hh: Fix doc.
	(V, P): Remove these useless parameters, now deduce from S.
	(v_): Rename this attribute as...
	(elt_): ...this; more explicit name.
	(target): Prefer to use the explicit...
	(S): ...type.
	(t_): Rename as...
	(s_): ...this; consistent with other classes.
	(q_subject): Remove; obsolete.
	(to_site): Remove; inherited.
	(operator<<): Remove; useless.
	(operator graph_element): New conversion operator.
	(site_set, graph, subj_): Fix missing precondition.
	* mln/util/internal/graph_vertex_psite.hh: Fix doc.
	(target_t, vertex_t): Prefer to use explicit...
	(p_vertices, util::vertex): ...types.
	* mln/util/internal/graph_iter_base.hh
	(P): Rename this parameter as...
	(Elt): ...this; more explicit.
	(invalidate): Fix missing postcondition.
	(next): Fix missing precondition.
 core/concept/graph.hh               |    2 
 core/site_set/p_edges.hh            |   28 +++--
 core/site_set/p_graph_piter.hh      |   34 ++----
 core/site_set/p_vertices.hh         |   43 +++++---
 util/graph.hh                       |   12 +-
 util/internal/graph_base.hh         |    6 -
 util/internal/graph_edge.hh         |   50 ++++-----
 util/internal/graph_edge_psite.hh   |   53 +++------
 util/internal/graph_iter.hh         |    6 -
 util/internal/graph_iter_base.hh    |   59 +++++------
 util/internal/graph_psite_base.hh   |  193 +++++++++++++++++-------------------
 util/internal/graph_vertex.hh       |   41 ++++---
 util/internal/graph_vertex_psite.hh |   48 ++++----
 13 files changed, 291 insertions(+), 284 deletions(-)
Index: mln/core/site_set/p_graph_piter.hh
--- mln/core/site_set/p_graph_piter.hh	(revision 2886)
+++ mln/core/site_set/p_graph_piter.hh	(working copy)
@@ -30,15 +30,17 @@
 # define MLN_CORE_SITE_SET_P_GRAPH_PITER_HH
 
 /// \file mln/core/site_set/p_graph_piter.hh
-/// \brief Definition of point iterator on graph-based point set.
+///
+/// Definition of point iterator on graph-based point set.
 
 # include <mln/core/internal/site_set_iterator_base.hh>
-//# include <mln/core/site_set/p_graph.hh>
-//# include <mln/core/image/graph_psite.hh>
+
+
 
 namespace mln
 {
-  // Fwd decls.
+
+  // Forward declaration.
   template <typename S, typename I> class graph_psite;
 
 
@@ -46,7 +48,7 @@
   | p_graph_piter<S,I>.  |
   `------------------------*/
 
-  /// \brief Generic iterator on point sites of a mln::S.
+  /// Generic iterator on point sites of a mln::S.
   template <typename S, typename I>
   class p_graph_piter
     : public internal::site_set_iterator_base< S,
@@ -57,7 +59,8 @@
     typedef I iter;
 
   public:
-    /// Construction and assignment.
+
+    /// Constructors.
     /// \{
     p_graph_piter();
     p_graph_piter(const S& pv);
@@ -77,10 +80,12 @@
     /// \}
 
   private:
+
     /// Update the psite corresponding to this iterator.
     void update_();
 
   private:
+
     /// The psite corresponding to this iterator.
     using super_::p_;
 
@@ -89,11 +94,6 @@
   };
 
 
-  /// Print an mln::p_graph_piter<S,I>.
-  template <typename S, typename I>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_graph_piter<S,I>& p);
 
 
 # ifndef MLN_INCLUDE_ONLY
@@ -164,19 +164,9 @@
     p_.update_id(iter_.id());
   }
 
-
-
-  template <typename S, typename I>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_graph_piter<S,I>& p)
-  {
-    return ostr << p.unproxy_();
-  }
-
 # endif // ! MLN_INCLUDE_ONLY
 
-} // end of mln
+} // end of namespace mln
 
 
 #endif // ! MLN_CORE_SITE_SET_P_GRAPH_PITER_HH
Index: mln/core/site_set/p_vertices.hh
--- mln/core/site_set/p_vertices.hh	(revision 2886)
+++ mln/core/site_set/p_vertices.hh	(working copy)
@@ -29,7 +29,8 @@
 # define MLN_CORE_SITE_SET_P_VERTICES_HH
 
   /// \file mln/core/site_set/p_vertices.hh
-  /// \brief Definition of a point set based on a graph.
+///
+/// Definition of a point set based on a graph.
 
 # include <mln/core/internal/site_set_base.hh>
 # include <mln/core/site_set/p_graph_piter.hh>
@@ -41,11 +42,14 @@
   //# include <mln/core/image/graph_psite.hh>
   //# include <mln/core/site_set/p_vertices_piter.hh>
 
+
 namespace mln
 {
+
   // Forward declaration.
   template <typename G, typename F> struct p_vertices;
 
+
   namespace trait
   {
     template <typename G, typename F>
@@ -60,33 +64,41 @@
   } // end of namespace mln::trait
 
 
+
   template <typename G, typename F>
   class p_vertices
-    : public internal::site_set_base_< typename F::result, p_vertices<G, F> >
+    : public internal::site_set_base_< mln_result(F), p_vertices<G, F> >
   {
-    typedef util::vertex<G> vertex_t;
 
     typedef p_vertices<G, F> self_;
-    typedef internal::site_set_base_< typename F::result, self_ > super_;
+    typedef internal::site_set_base_< mln_result(F), self_ > super_;
 
   public:
 
-    /// Type of the graph this site set is based on.
-    typedef G graph_t;
+    /// Type of graph vertex.
+    typedef util::vertex<G> vertex;
 
-    /// \brief Construct a graph psite set from a graph of points.
-    /// \{
+
+    /// Type of graph element this site set focuses on.
+    typedef util::vertex<G> graph_element;
+
+
+    /// Constructor without argument.
     p_vertices();
 
+    /// Construct a graph psite set from a graph of points.
     /// \param gr The graph upon which the graph psite set is built.
     /// \param f the function which maps a vertex to a site.
-    p_vertices(const graph_t& gr, const F& f);
+    p_vertices(const G& gr, const F& f);
     /// \}
 
+
     /// Associated types.
     /// \{
+
     /// Element associated type.
     typedef mln_site(super_) element;
+
     /// Point_Site associated type.
     typedef internal::vertex_psite<G, F> psite;
 
@@ -98,8 +110,10 @@
 
     /// Site_Iterator associated type.
     typedef fwd_piter piter;
+
     /// \}
 
+
     /// \brief Return The number of points (sites) of the set, i.e.,
     /// the number of \em vertices.
     ///
@@ -109,8 +123,9 @@
     /// Return The number of vertices in the graph.
     unsigned nvertices() const;
 
-    /// Is this site set valid?
+    /// Test this site set validity.
     bool is_valid() const;
+
     /// Invalidate this site set.
     void invalidate();
 
@@ -134,13 +149,13 @@
     /// Accessors.
     /// \{
     /// Return the graph associated to this site set (const version)
-    const graph_t& graph() const;
+    const G& graph() const;
     /// Return the association function.
     const F& function() const;
     /// \}
 
   private:
-    mlc_const(graph_t)* g_;
+    const G* g_;
     F f_;
   };
 
@@ -182,7 +197,7 @@
 
   template <typename G, typename F>
   inline
-  p_vertices<G, F>::p_vertices(const graph_t& g, const F& f)
+  p_vertices<G, F>::p_vertices(const G& g, const F& f)
     : g_ (&g), f_(f)
   {
   }
@@ -282,7 +297,7 @@
 
   template <typename G, typename F>
   inline
-  const typename p_vertices<G, F>::graph_t&
+  const G&
   p_vertices<G, F>::graph() const
   {
     mln_precondition(is_valid());
Index: mln/core/site_set/p_edges.hh
--- mln/core/site_set/p_edges.hh	(revision 2886)
+++ mln/core/site_set/p_edges.hh	(working copy)
@@ -58,27 +58,32 @@
 
   template <typename G, typename F>
   class p_edges
-    : public internal::site_set_base_< typename F::result, p_edges<G, F> >
+    : public internal::site_set_base_< mln_result(F), p_edges<G, F> >
   {
-    typedef util::edge<G> edge_t;
 
     typedef p_edges<G, F> self_;
-    typedef internal::site_set_base_< typename F::result, self_ > super_;
+    typedef internal::site_set_base_< mln_result(F), self_ > super_;
 
   public:
-    /// Type of the graph this site set is based on.
-    typedef G graph_t;
 
-    /// \brief Construct a graph edge psite set from a graph and a function.
+    /// Type of graph edge.
+    typedef util::edge<G> edge;
+
+    /// Type of graph element this site set focuses on.
+    typedef util::edge<G> graph_element;
+
+
+    /// Construct a graph edge psite set from a graph and a function.
     ///
     /// \param gr The graph upon which the graph edge psite set is built.
     /// \param f the function mapping edges and sites.
-    p_edges(const graph_t& gr, const F& f);
+    p_edges(const G& gr, const F& f);
 
     /// Associated types.
     /// \{
     /// Element associated type.
     typedef mln_site(super_) element;
+
     /// Point_Site associated type.
     typedef internal::edge_psite<G, F> psite;
 
@@ -117,13 +122,14 @@
     /// Accessors.
     /// \{
     /// Return the graph associated to this site set
-    const graph_t& graph() const;
+    const G& graph() const;
     /// Return the mapping function.
     const F& function() const;
     /// \}
 
   private:
-    mlc_const(graph_t)* g_;
+
+    const G* g_;
     F f_;
   };
 
@@ -155,7 +161,7 @@
 
   template <typename G, typename F>
   inline
-  p_edges<G, F>::p_edges(const graph_t& g, const F& f)
+  p_edges<G, F>::p_edges(const G& g, const F& f)
     : g_ (&g), f_(f)
   {
   }
@@ -223,7 +229,7 @@
 
   template <typename G, typename F>
   inline
-  const typename p_edges<G, F>::graph_t&
+  const G&
   p_edges<G, F>::graph() const
   {
     mln_precondition(is_valid());
Index: mln/core/concept/graph.hh
--- mln/core/concept/graph.hh	(revision 2886)
+++ mln/core/concept/graph.hh	(working copy)
@@ -109,7 +109,7 @@
     //typedef mln_bkd_piter(E) bkd_piter;
 
     // Check methods
-    const void * const(E::*m1)() const = & E::graph_id;
+    const void* (E::*m1)() const = & E::graph_id;
     m1 = 0;
     unsigned (E::*m2)(unsigned id_e, unsigned id_v) const = & E::v_other;
     m2 = 0;
Index: mln/util/graph.hh
--- mln/util/graph.hh	(revision 2886)
+++ mln/util/graph.hh	(working copy)
@@ -30,19 +30,21 @@
 # define MLN_UTIL_GRAPH_HH
 
 /// \file mln/util/graph.hh
-/// Definitions of undirected graphs.
+///
+/// Definition of a basic undirected graph.
 
 # include <mln/util/internal/graph_base.hh>
 # include <mln/util/internal/graph_iter.hh>
 # include <mln/util/internal/graph_nbh_iter.hh>
 # include <mln/util/ord_pair.hh>
 
+
 namespace mln
 {
 
   namespace util
   {
-    /// Fwd declaration.
+    /// Forward declaration.
     class graph;
   }
 
@@ -134,6 +136,8 @@
 
       graph();
 
+
+
       /// Vertex oriented.
       /// \{
       /// Shortcuts factoring the insertion of vertices and edges.
@@ -173,7 +177,6 @@
 
 
 
-
       /// Edge oriented.
       /// \{
       /// Add an edge.
@@ -219,6 +222,9 @@
 
 } // end of namespace mln
 
+
+
+
 # ifndef MLN_INCLUDE_ONLY
 
 namespace mln
Index: mln/util/internal/graph_iter.hh
--- mln/util/internal/graph_iter.hh	(revision 2886)
+++ mln/util/internal/graph_iter.hh	(working copy)
@@ -148,6 +148,8 @@
 	friend class graph_iter_base<G, util::edge<G>, edge_bkd_iterator<G> >;
     };
 
+
+
 # ifndef MLN_INCLUDE_ONLY
 
     /*--------------------`
@@ -290,9 +292,9 @@
 
 # endif // !MLN_INCLUDE_ONLY
 
-  } // End of namespace mln::internal
+  } // end of namespace mln::internal
 
-} // End of namespace mln
+} // end of namespace mln
 
 #endif // !MLN_UTIL_INTERNAL_GRAPH_ITER_HH
 
Index: mln/util/internal/graph_edge.hh
--- mln/util/internal/graph_edge.hh	(revision 2886)
+++ mln/util/internal/graph_edge.hh	(working copy)
@@ -28,11 +28,12 @@
 #ifndef MLN_UTIL_INTERNAL_GRAPH_EDGE_HH
 # define MLN_UTIL_INTERNAL_GRAPH_EDGE_HH
 
+/// \file mln/util/internal/graph_edge.hh
+///
+/// Definition of a graph edge.
+
 # include <mln/util/internal/graph_edge_impl.hh>
 
-/*! \file mln/util/internal/graph_edge.hh
- * \brief Definition of a graph edge.
- */
 
 namespace mln
 {
@@ -44,22 +45,23 @@
     | Edge.  |
     `-------*/
 
-    /// \brief Edge of a graph \p G.
+    /// Edge of a graph \p G.
     template <typename G>
     class edge : public internal::edge_impl_<G>
     {
-      typedef mlc_unconst(G) graph_t;
-
       public:
+
+      /// Graph associated type.
+      typedef G graph_t;
+
 	/// Constructors
 	/// \{
 	edge();
-	explicit edge(const graph_t& g);
-        edge(const graph_t& g, unsigned id);
+	explicit edge(const G& g);
+        edge(const G& g, unsigned id);
 	/// \}
 
 
-
         /// Misc.
 	/// \{
 	/// Return whether is points to a known edge.
@@ -74,14 +76,13 @@
 	void update_id(unsigned id);
 
 	/// Return a reference to the graph holding this edge.
-        const graph_t& graph() const;
+        const G& graph() const;
 
 	/// Set g_ with \p g;
-	void change_graph(const graph_t& g);
+	void change_graph(const G& g);
 	/// \}
 
 
-
         /// Vertex and edges oriented.
 	/// \{
 	/// Return the vertex id of this edge which is different from \p id_v.
@@ -105,13 +106,13 @@
 	/// \}
 
       private:
-	graph_t g_;
+	G g_;
 	unsigned id_;
     };
 
     template <typename G>
     std::ostream&
-    operator<<(std::ostream& ostr, edge<G>& p);
+    operator<<(std::ostream& ostr, const edge<G>& p);
 
     template <typename G>
     bool
@@ -174,23 +175,24 @@
     template <typename G>
     inline
     edge<G>::edge()
-      : id_(0)
     {
+      invalidate();
     }
 
     template <typename G>
     inline
-    edge<G>::edge(const graph_t& g)
-      : g_(g), id_(g.e_nmax())
+    edge<G>::edge(const G& g)
+      : g_(g)
     {
+      invalidate();
     }
 
     template <typename G>
     inline
-    edge<G>::edge(const graph_t& g, unsigned id)
+    edge<G>::edge(const G& g, unsigned id)
       : g_(g), id_(id)
     {
-      mln_precondition(g.has_e(id));
+      mln_precondition(/* FIXME: g_.is_valid() && */ g.has_e(id));
     }
 
     template <typename G>
@@ -211,7 +213,7 @@
 
     template <typename G>
     inline
-    const typename edge<G>::graph_t&
+    const typename edge<G>::G&
     edge<G>::graph() const
     {
       return g_;
@@ -220,7 +222,7 @@
     template <typename G>
     inline
     void
-    edge<G>::change_graph(const graph_t& g)
+    edge<G>::change_graph(const G& g)
     {
       g_ = g;
     }
@@ -230,7 +232,7 @@
     bool
     edge<G>::is_valid() const
     {
-      return g_.has_e(id_);
+      return /* FIXME: g_.is_valid() && */ g_.has_e(id_);
     }
 
     template <typename G>
@@ -238,7 +240,7 @@
     void
     edge<G>::invalidate()
     {
-      id_ = g_.e_nmax();
+      id_ = mln_max(unsigned);
     }
 
 
@@ -289,7 +291,7 @@
 
     template <typename G>
     std::ostream&
-    operator<<(std::ostream& ostr, edge<G>& p)
+    operator<<(std::ostream& ostr, const edge<G>& p)
     {
       return ostr << p.id();
     }
Index: mln/util/internal/graph_edge_psite.hh
--- mln/util/internal/graph_edge_psite.hh	(revision 2886)
+++ mln/util/internal/graph_edge_psite.hh	(working copy)
@@ -28,67 +28,56 @@
 #ifndef MLN_UTIL_INTERNAL_GRAPH_EDGE_PSITE_HH
 # define MLN_UTIL_INTERNAL_GRAPH_EDGE_PSITE_HH
 
-# include <mln/core/concept/pseudo_site.hh>
+/// \file mln/util/internal/graph_edge_psite.hh
+///
+/// Implementation of p_edges psite.
+
 # include <mln/util/internal/graph_psite_base.hh>
 # include <mln/util/internal/graph_edge.hh>
 
+
 namespace mln
 {
 
+  // Forward declaration.
   template <typename G, typename F> class p_edges;
 
-} // end of namespace mln
-
-/// \file mln/util/internal/graph_edge_psite.hh
-/// \brief Implementation of p_edges psite.
-
-namespace mln
-{
 
     namespace internal
     {
 
+
       template <typename G, typename F>
       class edge_psite :
-	public graph_psite_base<util::edge<G>, typename F::result,
-				p_edges<G, F>,
+      public graph_psite_base< p_edges<G,F>,
 				edge_psite<G, F> >
       {
 	typedef edge_psite<G, F> self_;
-	typedef p_edges<G, F> target_t;
-        typedef graph_psite_base<util::edge<G>, typename F::result, target_t, self_> super_;
-	typedef util::edge<G> edge_t;
+      typedef graph_psite_base<p_edges<G,F>, self_> super_;
 
       public:
-	/// Associated Types
-	/// \{
-	/// Site type, the return type of the mapping function \p F here.
-        typedef typename F::result site;
-	/// \}
 
 	/// Constructors
 	/// \{
         edge_psite();
-        edge_psite(const target_t& t);
-        edge_psite(const target_t& t, unsigned);
+      edge_psite(const p_edges<G,F>& s);
+      edge_psite(const p_edges<G,F>& s, unsigned);
 	/// \}
 
 	/// Accessors
 	/// \{
 	/// Return the underlying edge.
-        const edge_t& e() const;
+      const util::edge<G>& e() const;
 	/// \}
-
-      protected:
-	/// The underlying edge (inherited).
-	using super_::v_;
      };
 
-    } // end of namespace internal
+
+  } // end of namespace mln::internal
 
 } // end of namespace mln
 
 
+
 # ifndef MLN_INCLUDE_ONLY
 
 namespace mln
@@ -105,24 +94,24 @@
 
       template <typename G, typename F>
       inline
-      edge_psite<G, F>::edge_psite(const target_t& t)
-	: super_(t)
+    edge_psite<G, F>::edge_psite(const p_edges<G,F>& s)
+      : super_(s)
       {
       }
 
       template <typename G, typename F>
       inline
-      edge_psite<G, F>::edge_psite(const target_t& t, unsigned id)
-	: super_(t, id)
+    edge_psite<G, F>::edge_psite(const p_edges<G,F>& s, unsigned id)
+      : super_(s, id)
       {
       }
 
       template <typename G, typename F>
       inline
-      const typename edge_psite<G, F>::edge_t&
+    const util::edge<G>&
       edge_psite<G, F>::e() const
       {
-        return v_;
+      return this->v_;
       }
 
     } // end of namespace internal
Index: mln/util/internal/graph_base.hh
--- mln/util/internal/graph_base.hh	(revision 2886)
+++ mln/util/internal/graph_base.hh	(working copy)
@@ -83,7 +83,7 @@
 	/// Misc. methods
 	/// \{
 	/// Returns the graph id, the "this" pointer.
-	const void * const graph_id() const;
+	const void* graph_id() const;
 	/// \}
 
 	/// Vertex oriented methods
@@ -158,10 +158,10 @@
 
       template<typename E>
       inline
-      const void * const
+      const void*
       graph_base<E>::graph_id() const
       {
-	return static_cast<const void * const>(data_.ptr_);
+	return static_cast<const void*>(data_.ptr_);
       }
 
       /*-------------------------.
Index: mln/util/internal/graph_vertex.hh
--- mln/util/internal/graph_vertex.hh	(revision 2886)
+++ mln/util/internal/graph_vertex.hh	(working copy)
@@ -31,7 +31,10 @@
 # include <mln/util/internal/graph_vertex_impl.hh>
 
 /// \file   mln/util/internal/graph_vertex.hh
-/// \brief  Implementation of a graph vertex.
+///
+/// Implementation of a graph vertex.
+
+
 
 namespace mln
 {
@@ -39,19 +42,20 @@
   namespace util
   {
 
-    /// \brief Vertex of a graph \p G.
+    /// Vertex of a graph \p G.
     template<typename G>
     class vertex : public internal::vertex_impl_<G>
     {
-      typedef mlc_unconst(G) graph_t;
-
       public:
 
+      /// Graph associated type.
+      typedef G graph_t;
+      
 	/// Constructors.
 	/// \{
 	vertex();
-	explicit vertex(const graph_t& g);
-        vertex(const graph_t& g, unsigned id);
+	explicit vertex(const G& g);
+        vertex(const G& g, unsigned id);
 	/// \}
 
         /// Check whether the vertex is still part of the graph.
@@ -78,17 +82,17 @@
 	/// Change the parent graph of that vertex.
 	void change_graph(const G& g);
 
-	/// Update vertex id.
+	/// Update the vertex id.
 	void update_id(unsigned id);
 
 	/// Returns the graph pointer this vertex belongs to.
-	const graph_t&  graph() const;
+	const G& graph() const;
 
-	/// Returns vertex id.
+	/// Returns the vertex id.
 	unsigned id() const;
 
       protected:
-        graph_t g_;
+        G g_;
         unsigned id_;
     };
 
@@ -173,23 +177,24 @@
     template <typename G>
     inline
     vertex<G>::vertex()
-      : id_(0)
     {
+      invalidate();
     }
 
     template <typename G>
     inline
-    vertex<G>::vertex(const graph_t& g)
-      : g_(g), id_(g_.v_nmax())
+    vertex<G>::vertex(const G& g)
+      : g_(g)
     {
+      invalidate();
     }
 
     template<typename G>
     inline
-    vertex<G>::vertex(const graph_t& g, unsigned id)
+    vertex<G>::vertex(const G& g, unsigned id)
       : g_(g), id_(id)
     {
-      mln_precondition(g_.has_v(id));
+      mln_precondition(/* FIXME: g_.is_valid() && */ g_.has_v(id));
     }
 
     template<typename G>
@@ -197,7 +202,7 @@
     bool
     vertex<G>::is_valid() const
     {
-      return g_.has_v(id_);
+      return /* FIXME: g_.is_valid() && */ g_.has_v(id_);
     }
 
     template<typename G>
@@ -205,7 +210,7 @@
     void
     vertex<G>::invalidate()
     {
-      id_ = g_.v_nmax();
+      id_ = mln_max(unsigned);
     }
 
 
@@ -274,7 +279,7 @@
 
     template<typename G>
     inline
-    const typename vertex<G>::graph_t&
+    const typename vertex<G>::G&
     vertex<G>::graph() const
     {
       return g_;
Index: mln/util/internal/graph_psite_base.hh
--- mln/util/internal/graph_psite_base.hh	(revision 2886)
+++ mln/util/internal/graph_psite_base.hh	(working copy)
@@ -28,6 +28,10 @@
 #ifndef MLN_UTIL_INTERNAL_GRAPH_PSITE_BASE_HH
 # define MLN_UTIL_INTERNAL_GRAPH_PSITE_BASE_HH
 
+/// \file mln/util/internal/graph_psite_base.hh
+///
+/// Base implementation for graph based psites.
+
 # include <mln/core/concept/pseudo_site.hh>
 
 namespace mln
@@ -37,8 +41,6 @@
 
 } // end of namespace mln
 
-/// \file mln/util/internal/graph_psite_base.hh
-/// \brief Base implementation for graph based psites.
 
 namespace mln
 {
@@ -46,41 +48,43 @@
     namespace internal
     {
 
-      template <typename V, typename P, typename S, typename E>
-      class graph_psite_base : public mln::Pseudo_Site<E>,
-	  public internal::proxy_impl<const P&, E>
+      template <typename S, typename E>
+      class graph_psite_base : public internal::pseudo_site_base_< const mln_site(S)&,
+								   E >
       {
-        typedef Pseudo_Site< graph_psite_base<V, P, S, E> > super;
-	typedef typename S::graph_t graph_t;
+        typedef Pseudo_Site< graph_psite_base<S,E> > super;
 
         public:
-	/// Associated types.
-	/// \{
-        typedef P site;
+
+	// This associated type is important to know that this particular
+	// pseudo site knows the site set it refers to.
 	typedef S target;
-	/// \}
+
+	// As a Proxy:
+	const mln_site(S)& subj_();
+
 
 	/// Setters.
 	/// \{
 	/// Change the targe site set.
-        void change_target(const target& new_target);
+        void change_target(const S& new_target);
 	/// Update the underlying element's id.
 	/// This element can be an edge, a vertex...
-	void update_id(unsigned v_id);
+	void update_id(unsigned elt_id);
 	/// \}
 
 	/// Getters.
 	/// \{
 	/// Return the target (the site set).
-        const target* target_() const; // Hook to the target.
+        const S* target_() const; // Hook to the target.
 
 	/// Return the site set (the target).
-        const target& site_set() const;
+        const S& site_set() const;
 
 	/// Return the graph associated to the target of this psite.
-	const graph_t& graph() const;
+	const typename S::graph_t& graph() const;
 
-	/// Return the graph associated to the target of this psite.
+	/// Return the id of the graph element designated by this psite.
 	unsigned id() const;
 
 	/// \}
@@ -90,38 +94,30 @@
 	/// Invalidate this psite.
 	void invalidate();
 
-	/// Pseudo site Interface
-	/// \{
-	/// Subject type.
-	typedef const site& q_subject;
-	/// Return the subject.
-        const site& subj_();
-	/// Return the underlying site.
-	const site& to_site() const;
-	/// \}
+	/// Conversion towards the graph element (vertex or edge).
+	operator const typename S::graph_element&() const;
 
       protected:
+
 	/// Constructors.
+
 	/// \{
         graph_psite_base();
 	/// \p t A site set.
 	/// \sa p_vertices, p_edges.
-        graph_psite_base(const target& t);
+        graph_psite_base(const S& s);
 	/// \p t A site set.
 	/// \sa p_vertices, p_edges.
 	/// \p id The id of the element associated to this psite.
-        graph_psite_base(const target& t, unsigned id);
+        graph_psite_base(const S& , unsigned id);
 	/// \}
 
-	mlc_const(target)* t_;
-        V v_;
+	const S* s_;
+        typename S::graph_element elt_;
      };
 
-    template <typename V, typename P, typename S, typename E>
-    std::ostream&
-    operator<<(std::ostream& ostr, graph_psite_base<V, P, S, E>& p);
 
-    /// Comparison of two mln::graph_psite_base<V, P, S, E> instances.
+    /// Comparison of two mln::graph_psite_base<S,E> instances.
     /// \{
     /* FIXME: Shouldn't those comparisons be part of a much general
        mechanism?  */
@@ -130,17 +126,17 @@
     ///
     /// \pre Arguments \a lhs and \a rhs must belong to the same
     /// mln::p_vertices.
-    template <typename V, typename P, typename S, typename E>
+    template <typename S, typename E>
     bool
-    operator==(const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs);
+    operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
 
     /// \brief Is \a lhs not equal to \a rhs?
     ///
     /// \pre Arguments \a lhs and \a rhs must belong to the same
     /// mln::p_vertices.
-    template <typename V, typename P, typename S, typename E>
+    template <typename S, typename E>
     bool
-    operator!=(const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs);
+    operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
 
     /// \brief Is \a lhs ``less'' than \a rhs?
     ///
@@ -148,9 +144,9 @@
     ///
     /// \pre Arguments \a lhs and \a rhs must belong to the same
     /// mln::p_vertices.
-    template <typename V, typename P, typename S, typename E>
+    template <typename S, typename E>
     bool
-    operator< (const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs);
+    operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
     /// \}
 
   } // end of namespace internal
@@ -158,6 +154,7 @@
 } // end of namespace mln
 
 
+
 # ifndef MLN_INCLUDE_ONLY
 
 namespace mln
@@ -166,143 +163,137 @@
     namespace internal
     {
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
-      graph_psite_base<V, P, S, E>::graph_psite_base()
-	: t_(0)
+      graph_psite_base<S,E>::graph_psite_base()
+	: s_(0)
       {
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
-      graph_psite_base<V, P, S, E>::graph_psite_base(const target& t)
-        : t_(0)
+      graph_psite_base<S,E>::graph_psite_base(const S& s)
       {
-        change_target(t);
+        change_target(s);
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
-      graph_psite_base<V, P, S, E>::graph_psite_base(const target& t, unsigned id)
-        : t_(0)
+      graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
       {
-	change_target(t);
+	change_target(s);
 	update_id(id);
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
       void
-      graph_psite_base<V, P, S, E>::change_target(const target& new_target)
+      graph_psite_base<S,E>::change_target(const S& new_target)
       {
-        t_ = &new_target;
-	v_.change_graph(new_target.graph());
+        s_ = & new_target;
+	elt_.change_graph(new_target.graph());
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
       void
-      graph_psite_base<V, P, S, E>::update_id(unsigned id)
+      graph_psite_base<S,E>::update_id(unsigned id)
       {
-	v_.update_id(id);
+	elt_.update_id(id);
       }
 
-      template <typename v, typename p, typename s, typename e>
+      template <typename S, typename E>
       inline
-      const typename graph_psite_base<v, p, s, e>::target*
-      graph_psite_base<v, p, s, e>::target_() const
+      const S*
+      graph_psite_base<S,E>::target_() const
       {
-        return t_;
+        return s_;
       }
 
-      template <typename v, typename p, typename s, typename e>
+      template <typename S, typename E>
       inline
-      const typename graph_psite_base<v, p, s, e>::target&
-      graph_psite_base<v, p, s, e>::site_set() const
+      const S&
+      graph_psite_base<S,E>::site_set() const
       {
-        return *t_;
+	mln_precondition(s_ != 0);
+        return *s_;
       }
 
-      template <typename v, typename p, typename s, typename e>
+      template <typename S, typename E>
       inline
-      const typename graph_psite_base<v, p, s, e>::graph_t&
-      graph_psite_base<v, p, s, e>::graph() const
+      const typename S::graph_t&
+      graph_psite_base<S,E>::graph() const
       {
-        return t_->graph();
+	mln_precondition(s_ != 0);
+        return s_->graph();
       }
 
-      template <typename v, typename p, typename s, typename e>
+      template <typename S, typename E>
       inline
       unsigned
-      graph_psite_base<v, p, s, e>::id() const
+      graph_psite_base<S,E>::id() const
       {
-        return v_.id();
+        return elt_.id();
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
       bool
-      graph_psite_base<V, P, S, E>::is_valid() const
+      graph_psite_base<S,E>::is_valid() const
       {
-	return t_ != 0 && t_->is_valid() && v_.is_valid();
+	return s_ != 0 && s_->is_valid() && elt_.is_valid();
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
       void
-      graph_psite_base<V, P, S, E>::invalidate()
+      graph_psite_base<S,E>::invalidate()
       {
-	t_ = 0;
-	v_.invalidate();
+	s_ = 0;
+	elt_.invalidate();
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
-      const typename graph_psite_base<V, P, S, E>::site&
-      graph_psite_base<V, P, S, E>::subj_()
+      const mln_site(S)&
+      graph_psite_base<S,E>::subj_()
       {
-        return to_site();
+	mln_precondition(s_ != 0);
+        return s_->function()(elt_.id());
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       inline
-      const typename graph_psite_base<V, P, S, E>::site&
-      graph_psite_base<V, P, S, E>::to_site() const
+      graph_psite_base<S,E>::operator const typename S::graph_element&() const
       {
-        return t_->function()(v_.id());
+	mln_precondition(is_valid());
+	return elt_;
       }
 
 
-      template <typename V, typename P, typename S, typename E>
-      std::ostream&
-      operator<<(std::ostream& ostr, graph_psite_base<V, P, S, E>& p)
-      {
-	return ostr << p.unproxy_();
-      }
-
       /*--------------.
       | Comparisons.  |
       `--------------*/
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       bool
-      operator==(const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs)
+      operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs)
       {
 	mln_assertion(lhs.target_() == rhs.target_());
 	return lhs.id() == rhs.id();
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       bool
-      operator!=(const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs)
+      operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs)
       {
 	mln_assertion(lhs.target_() == rhs.target_());
 	return lhs.id() != rhs.id();
       }
 
-      template <typename V, typename P, typename S, typename E>
+      template <typename S, typename E>
       bool
-      operator< (const graph_psite_base<V, P, S, E>& lhs, const graph_psite_base<V, P, S, E>& rhs)
+      operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs)
       {
 	mln_assertion(lhs.target_() == rhs.target_());
 	return lhs.id() < rhs.id();
Index: mln/util/internal/graph_vertex_psite.hh
--- mln/util/internal/graph_vertex_psite.hh	(revision 2886)
+++ mln/util/internal/graph_vertex_psite.hh	(working copy)
@@ -28,55 +28,51 @@
 #ifndef MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH
 # define MLN_UTIL_INTERNAL_GRAPH_VERTEX_PSITE_HH
 
+/// \file mln/util/internal/graph_vertex_psite.hh
+///
+/// Implementation of p_vertices psite.
+
 # include <mln/core/concept/pseudo_site.hh>
 # include <mln/util/internal/graph_psite_base.hh>
 # include <mln/util/internal/graph_vertex.hh>
 
+
 namespace mln
 {
 
+  // Forward declaration.
   template <typename G, typename F> class p_vertices;
 
-} // end of namespace mln
-
-/// \file mln/util/internal/graph_vertex_psite.hh
-/// \brief Implementation of p_vertices psite.
-
-namespace mln
-{
 
     namespace internal
     {
 
+
       template <typename G, typename F>
       class vertex_psite :
-	public graph_psite_base<util::vertex<G>, typename F::result,
-				p_vertices<G, F>,
+      public graph_psite_base< p_vertices<G,F>,
 				vertex_psite<G, F> >
       {
 	typedef vertex_psite<G, F> self_;
-	typedef p_vertices<G, F> target_t;
-        typedef graph_psite_base<util::vertex<G>, typename F::result, target_t, self_> super_;
-	typedef util::vertex<G> vertex_t;
+      typedef graph_psite_base<p_vertices<G,F>, self_> super_;
 
       public:
-        typedef typename F::result site;
 
         vertex_psite();
-        vertex_psite(const target_t& t);
-        vertex_psite(const target_t& t, unsigned id);
+      vertex_psite(const p_vertices<G,F>& s);
+      vertex_psite(const p_vertices<G,F>& s, unsigned id);
 
-        const vertex_t& v() const;
-
-      protected:
-	using super_::v_;
+      const util::vertex<G>& v() const;
      };
 
-    } // end of namespace internal
+
+  } // end of namespace mln::internal
 
 } // end of namespace mln
 
 
+
+
 # ifndef MLN_INCLUDE_ONLY
 
 namespace mln
@@ -93,24 +89,24 @@
 
       template <typename G, typename F>
       inline
-      vertex_psite<G, F>::vertex_psite(const target_t& t)
-	: super_(t)
+      vertex_psite<G, F>::vertex_psite(const p_vertices<G,F>& s)
+	: super_(s)
       {
       }
 
       template <typename G, typename F>
       inline
-      vertex_psite<G, F>::vertex_psite(const target_t& t, unsigned i)
-	: super_(t, i)
+      vertex_psite<G, F>::vertex_psite(const p_vertices<G,F>& s, unsigned i)
+	: super_(s, i)
       {
       }
 
       template <typename G, typename F>
       inline
-      const typename vertex_psite<G, F>::vertex_t&
+      const util::vertex<G>&
       vertex_psite<G, F>::v() const
       {
-        return v_;
+        return this->v_;
       }
 
     } // end of namespace internal
Index: mln/util/internal/graph_iter_base.hh
--- mln/util/internal/graph_iter_base.hh	(revision 2886)
+++ mln/util/internal/graph_iter_base.hh	(working copy)
@@ -28,12 +28,17 @@
 #ifndef MLN_UTIL_INTERNAL_GRAPH_ITER_BASE_HH
 # define MLN_UTIL_INTERNAL_GRAPH_ITER_BASE_HH
 
+/// \file mln/util/internal/graph_iter_base.hh
+///
+/// Base implementation for graph iterators.
+///
+/// \todo Have special types for ids (vertex_id) to disambiguate the
+/// conversion op.
+
 # include <mln/core/concept/iterator.hh>
 # include <mln/core/concept/proxy.hh>
 # include <mln/util/internal/graph_edge.hh>
 
-/// \file   mln/util/internal/graph_iter_base.hh
-/// \brief  Base implementation for graph iterators.
 
 namespace mln
 {
@@ -41,10 +46,10 @@
   namespace internal
   {
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     class graph_iter_base
       : public Proxy< E >,
-	public internal::proxy_impl< const P&, E >
+	public internal::proxy_impl< const Elt&, E >
     {
       public:
 	/// Iterator interface
@@ -67,80 +72,80 @@
 	operator unsigned() const;
 	/// \}
 
-	/// Proxy.
-	/// \{
 	/// Proxy subject
-	const P& subj_();
-	/// \}
+	const Elt& subj_();
 
       protected:
 	graph_iter_base(const G& g);
 
-	P p_;
+	Elt p_;
     };
 
 
+
 # ifndef MLN_INCLUDE_ONLY
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
-    graph_iter_base<G, P, E>::graph_iter_base(const G& g)
-      : p_(P(g))
+    graph_iter_base<G, Elt, E>::graph_iter_base(const G& g)
+      : p_(Elt(g))
     {
       invalidate();
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
     bool
-    graph_iter_base<G, P, E>::is_valid() const
+    graph_iter_base<G, Elt, E>::is_valid() const
     {
       return p_.is_valid();
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
     void
-    graph_iter_base<G, P, E>::invalidate()
+    graph_iter_base<G, Elt, E>::invalidate()
     {
       p_.invalidate();
+      mln_postcondition(! is_valid());
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
     void
-    graph_iter_base<G, P, E>::start()
+    graph_iter_base<G, Elt, E>::start()
     {
       p_.update_id(exact(this)->start_id_());
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
     void
-    graph_iter_base<G, P, E>::next()
+    graph_iter_base<G, Elt, E>::next()
     {
+      mln_precondition(is_valid());
       p_.update_id(exact(this)->next_id_());
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
     unsigned
-    graph_iter_base<G, P, E>::index() const
+    graph_iter_base<G, Elt, E>::index() const
     {
       return p_.id();
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
-    graph_iter_base<G, P, E>::operator unsigned() const
+    graph_iter_base<G, Elt, E>::operator unsigned() const
     {
       return p_.id();
     }
 
-    template <typename G, typename P, typename E>
+    template <typename G, typename Elt, typename E>
     inline
-    const P&
-    graph_iter_base<G, P, E>::subj_()
+    const Elt&
+    graph_iter_base<G, Elt, E>::subj_()
     {
       return p_;
     }
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    17 Nov '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Use unmeta and handle accu object when needed.
	* mln/level/compute.hh,
	* mln/accu/compute.hh,
	* mln/morpho/elementary/like_ero_fun.hh,
	* mln/labeling/compute.hh: Use unmeta.
	* mln/accu/transform_directional.hh,
	* mln/accu/transform_diagonal.hh,
	* mln/accu/transform_snake.hh: Handle the accu object.
	(FIXME): Remove.
	* mln/accu/transform_stop.hh: Layout.
 accu/compute.hh                   |    7 +++---
 accu/transform_diagonal.hh        |   44 +++++++++++++++-----------------------
 accu/transform_directional.hh     |   20 ++++++++---------
 accu/transform_snake.hh           |   26 ++++++++++++----------
 labeling/compute.hh               |   16 ++++++++-----
 level/compute.hh                  |    8 ++++--
 morpho/elementary/like_ero_fun.hh |   12 +++++-----
 7 files changed, 67 insertions(+), 66 deletions(-)
Index: mln/level/compute.hh
--- mln/level/compute.hh	(revision 2885)
+++ mln/level/compute.hh	(working copy)
@@ -94,10 +94,12 @@
     template <typename A, typename I>
     inline
     mln_accu_with(A, mln_value(I))::result
-    compute(const Meta_Accumulator<A>&, const Image<I>& input)
+    compute(const Meta_Accumulator<A>& a, const Image<I>& input)
     {
-      mln_accu_with(A, mln_value(I)) accu;
-      return level::compute(accu, input); // Call the previous version.
+      typedef mln_accu_with(A, mln_value(I)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_value(I)());
+
+      return level::compute(a_, input); // Call the previous version.
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: mln/accu/transform_directional.hh
--- mln/accu/transform_directional.hh	(revision 2885)
+++ mln/accu/transform_directional.hh	(working copy)
@@ -58,14 +58,14 @@
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_result(A))
-    transform_directional(const Accumulator<A>&,
+    transform_directional(const Accumulator<A>& a,
 			  const Image<I>& input, const Window<W>& win,
 			  unsigned dir);
 
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    transform_directional(const Meta_Accumulator<A>&,
+    transform_directional(const Meta_Accumulator<A>& a,
 			  const Image<I>& input, const Window<W>& win,
 			  unsigned dir);
 
@@ -135,10 +135,10 @@
 	q_l,
 	  q_r;
 
-	directional_functor(const I& input, const W& win, int dir)
+	directional_functor(const I& input, const W& win, const A& a, int dir)
 	  : input(input),
 	    win(win),
-	    accu(),
+	    accu(a),
 	    dir(dir),
 	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
 	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
@@ -202,10 +202,10 @@
 
 	mln_qixter(const I, window2d) q_l, q_r;
 
-	directional_fastest_functor(const I& input, const W& win, unsigned dir)
+	directional_fastest_functor(const I& input, const W& win, const A& a, unsigned dir)
 	  : input(input),
 	    win(win),
-	    accu(),
+	    accu(a),
 	    dir(dir),
 	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
 	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
@@ -254,12 +254,12 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_directional_dispatch(trait::image::speed::any,
-				     const Accumulator<A>& /* FIXME a */,
+				     const Accumulator<A>& a,
 				     const Image<I>& input, const Window<W>& win,
 				     unsigned dir)
       {
 	typedef directional_functor<I, W, A> F;
-	F f(exact(input), exact(win), dir); // FIXME: Pass a to f.
+	F f(exact(input), exact(win), exact(a), dir);
 	canvas::browsing::directional(f);
 	return f.output;
       }
@@ -268,12 +268,12 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_directional_dispatch(trait::image::speed::fastest,
-				     const Accumulator<A>& /* FIXME a*/,
+				     const Accumulator<A>& a,
 				     const Image<I>& input, const Window<W>& win,
 				     unsigned dir)
       {
 	typedef directional_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win), dir); // FIXME: Pass a to f.
+	F f(exact(input), exact(win), exact(a), dir);
 	canvas::browsing::directional(f);
 	return f.output;
       }
Index: mln/accu/transform_diagonal.hh
--- mln/accu/transform_diagonal.hh	(revision 2885)
+++ mln/accu/transform_diagonal.hh	(working copy)
@@ -62,13 +62,13 @@
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_result(A))
-    transform_diagonal(const Accumulator<A>&,
+    transform_diagonal(const Accumulator<A>& a,
 		       const Image<I>& input, const Window<W>& win);
 
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    transform_diagonal(const Meta_Accumulator<A>&,
+    transform_diagonal(const Meta_Accumulator<A>& a,
 		       const Image<I>& input, const Window<W>& win);
 
 
@@ -114,17 +114,15 @@
 
 	mln_psite(I) p;
 	enum { dim = I::site::dim };
-	unsigned dir;
 
 	window2d win_left, win_right;
 
 	mln_qiter(window2d) q_l, q_r;
 
-	diagonal_functor(const I& input, const W& win)
+	diagonal_functor(const I& input, const W& win, const A& a)
 	  : input(input),
 	    win(win),
-	    accu(),
-	    dir(dir),
+	    accu(a),
 	    win_left(win::shift(win, dpsite(1, -1)) - win),
 	    win_right(win - win::shift(win, dpsite(1, -1))),
 	    q_l(win_left, p),
@@ -178,17 +176,15 @@
 
 	mln_psite(I) p;
 	enum { dim = I::site::dim };
-	unsigned dir;
 
 	window2d win_left, win_right;
 
 	mln_qiter(window2d) q_l, q_r;
 
-	backdiagonal_functor(const I& input, const W& win)
+	backdiagonal_functor(const I& input, const W& win, const A& a)
 	  : input(input),
 	    win(win),
-	    accu(),
-	    dir(dir),
+	    accu(a),
 	    win_left(win::shift(win, dpsite(-1, -1)) - win),
 	    win_right(win - win::shift(win, dpsite(-1, -1))),
 	    q_l(win_left, p),
@@ -245,17 +241,15 @@
 
 	mln_psite(I) p;
 	enum { dim = I::site::dim };
-	unsigned dir;
 
 	window2d win_left, win_right;
 
 	mln_qixter(const I, window2d) q_l, q_r;
 
-	diagonal_fastest_functor(const I& input, const W& win)
+	diagonal_fastest_functor(const I& input, const W& win, const A& a)
 	  : input(input),
 	    win(win),
-	    accu(),
-	    dir(dir),
+	    accu(a),
 	    win_left(win::shift(win, dpsite(1, -1)) - win),
 	    win_right(win - win::shift(win, dpsite(1, -1))),
 	    q_l(input, win_left, p),
@@ -308,17 +302,15 @@
 
 	mln_psite(I) p;
 	enum { dim = I::site::dim };
-	unsigned dir;
 
 	window2d win_left, win_right;
 
 	mln_qixter(const I, window2d) q_l, q_r;
 
-	backdiagonal_fastest_functor(const I& input, const W& win)
+	backdiagonal_fastest_functor(const I& input, const W& win, const A& a)
 	  : input(input),
 	    win(win),
-	    accu(),
-	    dir(dir),
+	    accu(a),
 	    win_left(win::shift(win, dpsite(-1, -1)) - win),
 	    win_right(win - win::shift(win, dpsite(-1, -1))),
 	    q_l(input, win_left, p),
@@ -366,11 +358,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_diagonal_dispatch(trait::image::speed::any,
-				  const Accumulator<A>& /* FIXME a */,
+				  const Accumulator<A>& a,
 				  const Image<I>& input, const win::diag2d& win)
       {
 	typedef diagonal_functor<I, win::diag2d, A> F;
-	F f(exact(input), win); // FIXME: Pass a to f.
+	F f(exact(input), win, exact(a));
 	canvas::browsing::diagonal2d(f);
 	return f.output;
       }
@@ -379,11 +371,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_diagonal_dispatch(trait::image::speed::any,
-				  const Accumulator<A>& /* FIXME a */,
+				  const Accumulator<A>& a,
 				  const Image<I>& input, const win::backdiag2d& win)
       {
 	typedef backdiagonal_functor<I, win::backdiag2d, A> F;
-	F f(exact(input), win); // FIXME: Pass a to f.
+	F f(exact(input), win, exact(a));
 	canvas::browsing::backdiagonal2d(f);
 	return f.output;
       }
@@ -392,11 +384,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_diagonal_dispatch(trait::image::speed::fastest,
-				  const Accumulator<A>& /* FIXME a*/,
+				  const Accumulator<A>& a,
 				  const Image<I>& input, const win::diag2d& win)
       {
 	typedef diagonal_fastest_functor<I, win::diag2d, A> F;
-	F f(exact(input), win); // FIXME: Pass a to f.
+	F f(exact(input), win, exact(a));
 	canvas::browsing::diagonal2d(f);
 	return f.output;
       }
@@ -405,11 +397,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_diagonal_dispatch(trait::image::speed::fastest,
-				  const Accumulator<A>& /* FIXME a*/,
+				  const Accumulator<A>& a,
 				  const Image<I>& input, const win::backdiag2d& win)
       {
 	typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
-	F f(exact(input), win); // FIXME: Pass a to f.
+	F f(exact(input), win, exact(a));
 	canvas::browsing::backdiagonal2d(f);
 	return f.output;
       }
Index: mln/accu/transform_stop.hh
Index: mln/accu/transform_snake.hh
--- mln/accu/transform_snake.hh	(revision 2885)
+++ mln/accu/transform_snake.hh	(working copy)
@@ -60,12 +60,12 @@
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_result(A))
-    transform_snake(const Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+    transform_snake(const Accumulator<A>& a, const Image<I>& input, const Window<W>& win);
 
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    transform_snake(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+    transform_snake(const Meta_Accumulator<A>& a, const Image<I>& input, const Window<W>& win);
 
 
 
@@ -101,9 +101,10 @@
 
 	const I& input;
 	const W& win;
-	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
+	mln_ch_value(I, mln_result(A)) output;
+
 	mln_psite(I) p;
 
 	window2d
@@ -129,10 +130,10 @@
 	std::vector<move_fun> moves;
 	std::vector<dpsite> dps;
 
-	transform_snake_functor(const Image<I>& input, const Window<W>& win)
+	transform_snake_functor(const Image<I>& input, const Window<W>& win, const Accumulator<A>& a)
 	  : input(exact(input)),
 	    win(exact(win)),
-	    accu(),
+	    accu(exact(a)),
 
 	    win_left_fwd(win::shift(win, mln::left) - win),
 	    win_right_fwd(win - win::shift(win, mln::left)),
@@ -253,9 +254,10 @@
 
 	const I& input;
 	const W& win;
-	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
+	mln_ch_value(I, mln_result(A)) output;
+
 	mln_psite(I) p;
 
 	window2d
@@ -282,10 +284,10 @@
 	std::vector<move_fun> moves;
 	std::vector<dpsite> dps;
 
-	transform_snake_fastest_functor(const I& input, const W& win)
+	transform_snake_fastest_functor(const I& input, const W& win, const A& a)
 	  : input(input),
 	    win(win),
-	    accu(),
+	    accu(a),
 
 	    win_left_fwd(win::shift(win, mln::left) - win),
 	    win_right_fwd(win - win::shift(win, mln::left)),
@@ -394,11 +396,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_snake_dispatch(trait::image::speed::any,
-			const Accumulator<A>& /* FIXME a */,
+			const Accumulator<A>& a,
 			const Image<I>& input, const Window<W>& win)
       {
 	typedef transform_snake_functor<I, W, A> F;
-	F f(exact(input), exact(win));  // FIXME: Pass a to f.
+	F f(exact(input), exact(win), exact(a));
 	canvas::browsing::snake_generic(f);
 	return f.output;
       }
@@ -407,11 +409,11 @@
       inline
       mln_ch_value(I, mln_result(A))
       transform_snake_dispatch(trait::image::speed::fastest,
-			       const Accumulator<A>& /* FIXME a*/,
+			       const Accumulator<A>& a,
 			       const Image<I>& input, const Window<W>& win)
       {
 	typedef transform_snake_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win));  // FIXME: Pass a to f.
+	F f(exact(input), exact(win), exact(a));
 	canvas::browsing::snake_generic(f);
 	return f.output;
       }
Index: mln/accu/compute.hh
--- mln/accu/compute.hh	(revision 2885)
+++ mln/accu/compute.hh	(working copy)
@@ -142,15 +142,16 @@
     template <typename A, typename I>
     inline
     mln_accu_with(A, util::pix<I>)::result
-    compute(const Meta_Accumulator<A>&, const Image<I>& input)
+    compute(const Meta_Accumulator<A>& a, const Image<I>& input)
     {
       trace::entering("accu::compute");
 
       mln_precondition(exact(input).has_data());
 
       typedef mln_accu_with(A, util::pix<I>) A_;
-      A_ a;
-      mln_result(A_) output = internal::compute_dispatch(a, input);
+      A_ a_ = accu::unmeta(exact(a), util::pix<I>());
+
+      mln_result(A_) output = internal::compute_dispatch(a_, input);
 
       trace::exiting("accu::compute");
       return output;
Index: mln/morpho/elementary/like_ero_fun.hh
--- mln/morpho/elementary/like_ero_fun.hh	(revision 2885)
+++ mln/morpho/elementary/like_ero_fun.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -48,7 +48,7 @@
       template <typename A, typename F,
 		typename I, typename N>
       mln_concrete(I)
-      like_ero_fun(const Meta_Accumulator<A>&, const F& f,
+      like_ero_fun(const Meta_Accumulator<A>& a, const F& f,
 		   const Image<I>& input, const Neighborhood<N>& nbh);
 
 
@@ -79,7 +79,7 @@
 	  template <typename A, typename F,
 		    typename I, typename N>
 	  mln_concrete(I)
-	  like_ero_fun(const Meta_Accumulator<A>&, const F& f,
+	  like_ero_fun(const Meta_Accumulator<A>& a_, const F& f,
 		       const Image<I>& input_, const Neighborhood<N>& nbh_)
 	  {
 	    trace::entering("morpho::elementary::impl::generic::like_ero_fun");
@@ -87,7 +87,7 @@
 	    const I& input = exact(input_);
 	    const N& nbh   = exact(nbh_);
 
-	    mln_accu_with(A, mln_value(I)) a;
+	    mln_accu_with(A, mln_value(I)) a = accu::unmeta(exact(a_), mln_value(I)());
 	    extension::adjust_fill(input, nbh, a);
 
 	    mln_concrete(I) output;
@@ -113,7 +113,7 @@
 	template <typename A, typename F,
 		  typename I, typename N>
 	mln_concrete(I)
-	like_ero_fun_fastest(const Meta_Accumulator<A>&, const F& f,
+	like_ero_fun_fastest(const Meta_Accumulator<A>& a_, const F& f,
 			     const Image<I>& input_, const Neighborhood<N>& nbh_)
 	{
 	  trace::entering("morpho::elementary::impl::like_ero_fun_fastest");
@@ -121,7 +121,7 @@
 	  const I& input = exact(input_);
 	  const N& nbh   = exact(nbh_);
 
-	  mln_accu_with(A, mln_value(I)) a;
+	  mln_accu_with(A, mln_value(I)) a = accu::unmeta(exact(a_), mln_value(I)());
 	  extension::adjust_fill(input, nbh, a);
 
 	  mln_concrete(I) output;
Index: mln/labeling/compute.hh
--- mln/labeling/compute.hh	(revision 2885)
+++ mln/labeling/compute.hh	(working copy)
@@ -150,12 +150,14 @@
     template <typename A, typename I, typename J>
     inline
     util::array<mln_accu_with(A, mln_value(I))::result>
-    compute(const Meta_Accumulator<A>&,
+    compute(const Meta_Accumulator<A>& a,
 	    const Image<I>& input,
 	    const Image<J>& label, mln_value(J) nlabels)
     {
-      mln_accu_with(A, mln_value(I)) accu;
-      return compute(accu, input, label, nlabels);
+      typedef mln_accu_with(A, mln_value(I)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_value(I)());
+
+      return compute(a_, input, label, nlabels);
     }
 
 
@@ -190,11 +192,13 @@
     template <typename A, typename J>
     inline
     util::array<mln_accu_with(A, mln_psite(J))::result>
-    compute(const Meta_Accumulator<A>&,
+    compute(const Meta_Accumulator<A>& a,
 	    const Image<J>& label, mln_value(J) nlabels)
     {
-      mln_accu_with(A, mln_psite(J)) accu;
-      return compute(accu, label, nlabels);
+      typedef mln_accu_with(A, mln_psite(J)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_psite(J)());
+
+      return compute(a_, label, nlabels);
     }
 
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* mln/core/concept/graph.hh: does not force add_* methods.
	* mln/util/dual_graph.hh: new class.
	* mln/util/graph.hh: cleanup comments
	* mln/util/internal/graph_edge.hh: add missing operator<<.
	* mln/util/internal/graph_nbh_iter_base.hh,
	* mln/util/internal/graph_iter_base.hh: add operator unsigned().
	* tests/util/Makefile.am,
	* tests/util/dual_graph.cc: Add a new test.
---
 milena/ChangeLog                                |   18 ++
 milena/mln/core/concept/graph.hh                |    2 -
 milena/mln/util/{graph.hh => dual_graph.hh}     |  243 +++++++++++------------
 milena/mln/util/graph.hh                        |   14 +-
 milena/mln/util/internal/graph_edge.hh          |   19 ++-
 milena/mln/util/internal/graph_iter_base.hh     |   11 +
 milena/mln/util/internal/graph_nbh_iter_base.hh |   10 +
 milena/tests/util/Makefile.am                   |    2 +
 milena/tests/util/dual_graph.cc                 |  164 +++++++++++++++
 9 files changed, 338 insertions(+), 145 deletions(-)
 copy milena/mln/util/{graph.hh => dual_graph.hh} (58%)
 create mode 100644 milena/tests/util/dual_graph.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index c947990..809f727 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,21 @@
+2008-11-17 Guillaume Lazzara <guillaume.lazzara(a)lrde.epita.fr>
+
+	Introduce a dual graph class.
+
+	* mln/core/concept/graph.hh: does not force add_* methods.
+
+	* mln/util/dual_graph.hh: new class.
+
+	* mln/util/graph.hh: cleanup comments
+
+	* mln/util/internal/graph_edge.hh: add missing operator<<.
+
+	* mln/util/internal/graph_nbh_iter_base.hh,
+	* mln/util/internal/graph_iter_base.hh: add operator unsigned().
+
+	* tests/util/Makefile.am,
+	* tests/util/dual_graph.cc: Add a new test.
+
 2008-11-14  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
 
 	Factor code for erosion on lines.
diff --git a/milena/mln/core/concept/graph.hh b/milena/mln/core/concept/graph.hh
index c98d9e5..e89acc2 100644
--- a/milena/mln/core/concept/graph.hh
+++ b/milena/mln/core/concept/graph.hh
@@ -113,8 +113,6 @@ namespace mln
     m1 = 0;
     unsigned (E::*m2)(unsigned id_e, unsigned id_v) const = & E::v_other;
     m2 = 0;
-    unsigned (E::*m3)() = & E::add_vertex;
-    m3 = 0;
     size_t (E::*m4)() const = & E::v_nmax;
     m4 = 0;
     bool (E::*m5)(unsigned id_v) const = & E::has_v;
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/dual_graph.hh
similarity index 58%
copy from milena/mln/util/graph.hh
copy to milena/mln/util/dual_graph.hh
index dfcbc23..3533e7c 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/dual_graph.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory
 // (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
@@ -26,10 +26,10 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_UTIL_GRAPH_HH
-# define MLN_UTIL_GRAPH_HH
+#ifndef MLN_UTIL_DUAL_GRAPH_HH
+# define MLN_UTIL_DUAL_GRAPH_HH
 
-/// \file mln/util/graph.hh
+/// \file mln/util/dual_graph.hh
 /// Definitions of undirected graphs.
 
 # include <mln/util/internal/graph_base.hh>
@@ -43,7 +43,8 @@ namespace mln
   namespace util
   {
     /// Fwd declaration.
-    class graph;
+    template <typename G>
+    class dual_graph;
   }
 
 
@@ -51,23 +52,22 @@ namespace mln
   {
 
     /// Data structure for \c mln::image2d<T>.
-    template <>
-    struct data<util::graph>
+    template <typename G>
+    struct data< util::dual_graph<G> >
     {
-      typedef util::graph G;
+
       typedef std::vector<std::vector<unsigned> > vertices_t;
       typedef std::vector<util::ord_pair<unsigned> > edges_t;
-      typedef std::set<util::ord_pair<unsigned> > edges_set_t;
 
       data();
+      data(const G& g);
       ~data();
 
+      G g_;
       /// The vertices.
       vertices_t vertices_;
       /// The edges.
       edges_t edges_;
-      /// An index of the set of edges, for fast-access purpose.
-      edges_set_t edges_set_;
     };
 
   } // end of namespace mln::internal
@@ -76,14 +76,18 @@ namespace mln
   namespace util
   {
 
-    /// \brief Undirected graph.
-    class graph : public internal::graph_base<graph>
+    /// Undirected dual graph of a graph of type \tparam G.
+    template <typename G>
+    class dual_graph : public internal::graph_base< dual_graph<G> >
     {
       /// The super class.
-      typedef internal::graph_base<graph> super;
+      typedef internal::graph_base< dual_graph<G> > super;
 
-      using super::vertex_data_t;
-      using super::edge_data_t;
+      typedef typename super::vertex_t vertex_t;
+      typedef typename super::edge_t edge_t;
+
+      typedef typename super::vertex_data_t vertex_data_t;
+      typedef typename super::edge_data_t edge_data_t;
 
     public:
       /// The type of the set of vertices.
@@ -91,71 +95,46 @@ namespace mln
 
       /// The type of the set of edges.
       typedef std::vector<edge_data_t> edges_t;
-      /// A set to test the presence of a given edge.
-      typedef std::set<edge_data_t> edges_set_t;
 
       /// Iterator types
       /// \{
       /// Vertex iterators
       /// \{
-      typedef mln::internal::vertex_fwd_iterator<graph> vertex_fwd_iter;
-      typedef mln::internal::vertex_bkd_iterator<graph> vertex_bkd_iter;
+      typedef mln::internal::vertex_fwd_iterator< dual_graph<G> >
+	vertex_fwd_iter;
+      typedef mln::internal::vertex_bkd_iterator< dual_graph<G> >
+	vertex_bkd_iter;
       typedef vertex_fwd_iter vertex_iter;
-      /// \}
 
-      /// Vertex centered edge iterators
-      /// \{
-      typedef mln::internal::vertex_nbh_edge_fwd_iterator<graph> vertex_nbh_edge_fwd_iter;
-      typedef mln::internal::vertex_nbh_edge_bkd_iterator<graph> vertex_nbh_edge_bkd_iter;
-      typedef vertex_nbh_edge_fwd_iter vertex_nbh_edge_iter;
-      /// \}
-
-      /// Vertex centered vertex iterators
-      /// \{
-      typedef mln::internal::vertex_nbh_vertex_fwd_iterator<graph> vertex_nbh_vertex_fwd_iter;
-      typedef mln::internal::vertex_nbh_vertex_bkd_iterator<graph> vertex_nbh_vertex_bkd_iter;
-      typedef vertex_nbh_vertex_fwd_iter vertex_nbh_vertex_iter;
-      /// \}
-
-      /// Edge iterators
-      /// \{
-      typedef mln::internal::edge_fwd_iterator<graph> edge_fwd_iter;
-      typedef mln::internal::edge_bkd_iterator<graph> edge_bkd_iter;
+      typedef mln::internal::edge_fwd_iterator< dual_graph<G> >
+	edge_fwd_iter;
+      typedef mln::internal::edge_bkd_iterator< dual_graph<G> >
+	edge_bkd_iter;
       typedef edge_fwd_iter edge_iter;
-      /// \}
 
-      /// Edge centered edge iterators.
-      /// \{
-      typedef mln::internal::edge_nbh_edge_fwd_iterator<graph> edge_nbh_edge_fwd_iter;
-      typedef mln::internal::edge_nbh_edge_bkd_iterator<graph> edge_nbh_edge_bkd_iter;
-      typedef edge_nbh_edge_fwd_iter edge_nbh_edge_iter;
       /// \}
       /// \}
 
-      graph();
+      dual_graph();
+      dual_graph(const G& g);
 
       /// Vertex oriented.
       /// \{
       /// Shortcuts factoring the insertion of vertices and edges.
       /// \{
-      /// \brief Add a vertex.
-      ///
-      /// \return The id of the new vertex.
-      unsigned add_vertex();
-
       /// Return the vertex whose id is \a v.
       /// \{
       vertex_t vertex(unsigned id_v) const;
       /// \}
 
-      /// \brief Return the number of vertices in the graph.
+      /// Return the number of vertices in the graph.
       size_t v_nmax() const;
 
       /// Check whether a vertex id \p id_v exists in the graph.
       bool has_v(unsigned id_v) const;
       /// Check whether an edge \p v exists in the graph.
-      template <typename G>
-      bool has_v(const util::vertex<G>& v) const;
+      template <typename G2>
+      bool has_v(const util::vertex<G2>& v) const;
 
 
       /// Return the number of adjacent edges of vertex \p id_v.
@@ -176,23 +155,17 @@ namespace mln
 
       /// Edge oriented.
       /// \{
-      /// \brief Add an edge.
-      ///
-      /// \return The id of the new edge if it does not exist yet;
-      /// otherwise, return <tt>mln_max(unsigned)</tt>.
-      unsigned add_edge(unsigned id_v1, unsigned id_v2);
-
       /// Return the edge whose id is \a e.
       edge_t edge(unsigned e) const;
 
-      /// \brief Return the number of edges in the graph.
+      /// Return the number of edges in the graph.
       size_t e_nmax() const;
 
       /// Return whether \p id_e is in the graph.
       bool has_e(unsigned id_e) const;
       /// Return whether \p e is in the graph.
-      template <typename G>
-      bool has_e(const util::edge<G>& e) const;
+      template <typename G2>
+      bool has_e(const util::edge<G2>& e) const;
 
 
       /// Return the first vertex associated to the edge \p id_e.
@@ -213,6 +186,8 @@ namespace mln
       bool is_subgraph_of(const G2& g) const;
       /// \}
 
+    protected:
+      using super::data_;
     };
 
   } // end of namespace mln::util
@@ -227,13 +202,32 @@ namespace mln
   namespace internal
   {
 
+    template <typename G>
     inline
-    data<util::graph>::data()
+    data< util::dual_graph<G> >::data()
     {
     }
 
+    template <typename G>
     inline
-    data<util::graph>::~data()
+    data< util::dual_graph<G> >::data(const G& g)
+    {
+      g_ = g;
+      vertices_.resize(g.e_nmax());
+      mln_edge_iter(G) e(g);
+      mln_edge_nbh_edge_iter(G) ne(e);
+
+      for_all(e)
+	for_all(ne)
+	{
+	  vertices_[e].push_back(edges_.size());
+	  edges_.push_back(util::ord_pair<unsigned>(e, ne));
+	}
+    }
+
+    template <typename G>
+    inline
+    data< util::dual_graph<G> >::~data()
     {
     }
 
@@ -242,69 +236,73 @@ namespace mln
   namespace util
   {
 
+    template <typename G>
     inline
-    graph::graph()
+    dual_graph<G>::dual_graph()
     {
-      this->data_ = new mln::internal::data<util::graph>();
+      this->data_ = new mln::internal::data< util::dual_graph<G> >();
     }
 
-    /*---------------.
-    | Vertex related |
-    `---------------*/
-
+    template <typename G>
     inline
-    unsigned
-    graph::add_vertex()
+    dual_graph<G>::dual_graph(const G& g)
     {
-      /* FIXME: This is not thread-proof (these two lines should
-         form an atomic section).  */
-      data_->vertices_.resize(data_->vertices_.size() + 1);
-
-      return v_nmax() - 1;
+      this->data_ = new mln::internal::data< util::dual_graph<G> >(g);
     }
 
+    /*---------------.
+    | Vertex related |
+    `---------------*/
+
+    template <typename G>
     inline
-    graph::vertex_t
-    graph::vertex(unsigned id_v) const
+    typename dual_graph<G>::vertex_t
+    dual_graph<G>::vertex(unsigned id_v) const
     {
       mln_assertion(has_v(id_v));
       return vertex_t(*this, id_v);
     }
 
 
+    template <typename G>
     inline
     size_t
-    graph::v_nmax() const
+    dual_graph<G>::v_nmax() const
     {
-      return data_->vertices_.size();
+      return data_->g_.e_nmax();
     }
 
+    template <typename G>
     inline
     bool
-    graph::has_v(unsigned id_v) const
+    dual_graph<G>::has_v(unsigned id_v) const
     {
-      return id_v < data_->vertices_.size();
+      return data_->g_.has_e(id_v);
     }
 
     template <typename G>
+    template <typename G2>
     inline
     bool
-    graph::has_v(const util::vertex<G>& v) const
+    dual_graph<G>::has_v(const util::vertex<G2>& v) const
     {
+      //FIXME: not sure...
       return v.graph().is_subgraph_of(*this) && has_v(v.id());
     }
 
+    template <typename G>
     inline
     size_t
-    graph::v_nmax_nbh_edges(unsigned id_v) const
+    dual_graph<G>::v_nmax_nbh_edges(unsigned id_v) const
     {
       mln_precondition(has_v(id_v));
-      return data_->vertices_[id_v].size();
+      return data_->g_.e_nmax_nbh_edges(id_v);
     }
 
+    template <typename G>
     inline
     unsigned
-    graph::v_ith_nbh_edge(unsigned id_v, unsigned i) const
+    dual_graph<G>::v_ith_nbh_edge(unsigned id_v, unsigned i) const
     {
       mln_precondition(has_v(id_v));
       if (i >= v_nmax_nbh_edges(id_v))
@@ -312,22 +310,24 @@ namespace mln
       return data_->vertices_[id_v][i];
     }
 
+    template <typename G>
     inline
     size_t
-    graph::v_nmax_nbh_vertices(unsigned id_v) const
+    dual_graph<G>::v_nmax_nbh_vertices(unsigned id_v) const
     {
       mln_precondition(has_v(id_v));
       return v_nmax_nbh_edges(id_v);
     }
 
+    template <typename G>
     inline
     unsigned
-    graph::v_ith_nbh_vertex(unsigned id_v, unsigned i) const
+    dual_graph<G>::v_ith_nbh_vertex(unsigned id_v, unsigned i) const
     {
       mln_precondition(has_v(id_v));
 
-      unsigned id_e = v_ith_nbh_edge(id_v, i);
-      return v_other(id_e, id_v);
+      unsigned id_e = this->v_ith_nbh_edge(id_v, i);
+      return this->v_other(id_e, id_v);
      }
 
 
@@ -335,91 +335,71 @@ namespace mln
     | Edges related |
     `---------------*/
 
+    template <typename G>
     inline
-    unsigned
-    graph::add_edge(unsigned id_v1, unsigned id_v2)
-    {
-      // Does this edge already exist in the graph?
-      edge_data_t edge(id_v1, id_v2);
-      if (data_->edges_set_.find(edge) != data_->edges_set_.end ())
-        {
-          // Return the erroneous value.
-          return mln_max(unsigned);
-        }
-      else
-        {
-          // Otherwise insert it into the graph.
-          /* FIXME: This is not thread-proof (these two lines should
-             form an atomic section).  */
-          data_->edges_.push_back(edge);
-          unsigned id = data_->edges_.size() - 1;
-
-          // Update the set of edges.
-          data_->edges_set_.insert(edge);
-          data_->vertices_[edge.first()].push_back(id);
-          data_->vertices_[edge.second()].push_back(id);
-
-          return id;
-        }
-    }
-
-    inline
-    graph::edge_t
-    graph::edge(unsigned e) const
+    typename dual_graph<G>::edge_t
+    dual_graph<G>::edge(unsigned e) const
     {
       mln_assertion(e < e_nmax());
       return edge_t(*this, e);
     }
 
+    template <typename G>
     inline
     size_t
-    graph::e_nmax() const
+    dual_graph<G>::e_nmax() const
     {
       return data_->edges_.size();
     }
 
+    template <typename G>
     inline
     bool
-    graph::has_e(unsigned id_e) const
+    dual_graph<G>::has_e(unsigned id_e) const
     {
       return id_e < data_->edges_.size();
     }
 
     template <typename G>
+    template <typename G2>
     inline
     bool
-    graph::has_e(const util::edge<G>& e) const
+    dual_graph<G>::has_e(const util::edge<G2>& e) const
     {
       return e.graph().is_subgraph_of(*this) && has_e(e.id());
     }
 
+    template <typename G>
     inline
     unsigned
-    graph::v1(unsigned id_e) const
+    dual_graph<G>::v1(unsigned id_e) const
     {
       mln_precondition(has_e(id_e));
       return data_->edges_[id_e].first();
     }
 
+    template <typename G>
     inline
     unsigned
-    graph::v2(unsigned id_e) const
+    dual_graph<G>::v2(unsigned id_e) const
     {
       mln_precondition(has_e(id_e));
       return data_->edges_[id_e].second();
     }
 
+    template <typename G>
     inline
     size_t
-    graph::e_nmax_nbh_edges(unsigned id_e) const
+    dual_graph<G>::e_nmax_nbh_edges(unsigned id_e) const
     {
       mln_precondition(has_e(id_e));
       return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e));
     }
 
+    template <typename G>
     inline
     unsigned
-    graph::e_ith_nbh_edge(unsigned id_e, unsigned i) const
+    dual_graph<G>::e_ith_nbh_edge(unsigned id_e, unsigned i) const
     {
       mln_precondition(has_e(id_e));
       if (i >= e_nmax_nbh_edges(id_e))
@@ -432,10 +412,11 @@ namespace mln
     }
 
 
+    template <typename G>
     template <typename G2>
     inline
     bool
-    graph::is_subgraph_of(const G2& g) const
+    dual_graph<G>::is_subgraph_of(const G2& g) const
     {
       return g.graph_id() == this->graph_id();
     }
@@ -447,4 +428,4 @@ namespace mln
 # endif // ! MLN_INCLUDE_ONLY
 
 
-#endif // ! MLN_UTIL_GRAPH_HH
+#endif // ! MLN_UTIL_DUAL_GRAPH_HH
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh
index dfcbc23..30b19bd 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/graph.hh
@@ -76,14 +76,14 @@ namespace mln
   namespace util
   {
 
-    /// \brief Undirected graph.
+    /// Undirected graph.
     class graph : public internal::graph_base<graph>
     {
       /// The super class.
       typedef internal::graph_base<graph> super;
 
-      using super::vertex_data_t;
-      using super::edge_data_t;
+      typedef super::vertex_data_t vertex_data_t;
+      typedef super::edge_data_t edge_data_t;
 
     public:
       /// The type of the set of vertices.
@@ -138,7 +138,7 @@ namespace mln
       /// \{
       /// Shortcuts factoring the insertion of vertices and edges.
       /// \{
-      /// \brief Add a vertex.
+      /// Add a vertex.
       ///
       /// \return The id of the new vertex.
       unsigned add_vertex();
@@ -148,7 +148,7 @@ namespace mln
       vertex_t vertex(unsigned id_v) const;
       /// \}
 
-      /// \brief Return the number of vertices in the graph.
+      /// Return the number of vertices in the graph.
       size_t v_nmax() const;
 
       /// Check whether a vertex id \p id_v exists in the graph.
@@ -176,7 +176,7 @@ namespace mln
 
       /// Edge oriented.
       /// \{
-      /// \brief Add an edge.
+      /// Add an edge.
       ///
       /// \return The id of the new edge if it does not exist yet;
       /// otherwise, return <tt>mln_max(unsigned)</tt>.
@@ -185,7 +185,7 @@ namespace mln
       /// Return the edge whose id is \a e.
       edge_t edge(unsigned e) const;
 
-      /// \brief Return the number of edges in the graph.
+      /// Return the number of edges in the graph.
       size_t e_nmax() const;
 
       /// Return whether \p id_e is in the graph.
diff --git a/milena/mln/util/internal/graph_edge.hh b/milena/mln/util/internal/graph_edge.hh
index 06e39d4..bab22d8 100644
--- a/milena/mln/util/internal/graph_edge.hh
+++ b/milena/mln/util/internal/graph_edge.hh
@@ -110,12 +110,16 @@ namespace mln
     };
 
     template <typename G>
+    std::ostream&
+    operator<<(std::ostream& ostr, edge<G>& p);
+
+    template <typename G>
     bool
-    operator==(const util::edge<G>& lhs, const util::edge<G>& rhs);
+    operator==(const edge<G>& lhs, const edge<G>& rhs);
 
     template <typename G>
     bool
-    operator< (const util::edge<G>& lhs, const util::edge<G>& rhs);
+    operator< (const edge<G>& lhs, const edge<G>& rhs);
 
   } // End of namespace mln::util
 
@@ -283,12 +287,17 @@ namespace mln
       return g_.e_ith_nbh_edge(id_, i);
     }
 
-
+    template <typename G>
+    std::ostream&
+    operator<<(std::ostream& ostr, edge<G>& p)
+    {
+      return ostr << p.id();
+    }
 
     template <typename G>
     inline
     bool
-    operator==(const util::edge<G>& lhs, const util::edge<G>& rhs)
+    operator==(const edge<G>& lhs, const edge<G>& rhs)
     {
       return lhs.pair_vertex_ == rhs.pair_vertex_;
     }
@@ -296,7 +305,7 @@ namespace mln
     template <typename G>
     inline
     bool
-    operator< (const util::edge<G>& lhs, const util::edge<G>& rhs)
+    operator< (const edge<G>& lhs, const edge<G>& rhs)
     {
       return lhs.pair_vertex_ < rhs.pair_vertex_;
     }
diff --git a/milena/mln/util/internal/graph_iter_base.hh b/milena/mln/util/internal/graph_iter_base.hh
index a901192..96777af 100644
--- a/milena/mln/util/internal/graph_iter_base.hh
+++ b/milena/mln/util/internal/graph_iter_base.hh
@@ -62,6 +62,9 @@ namespace mln
 
 	/// Return current index
 	unsigned index() const;
+
+	/// Conversion operator. Returns the element id.
+	operator unsigned() const;
 	/// \}
 
 	/// Proxy.
@@ -76,6 +79,7 @@ namespace mln
 	P p_;
     };
 
+
 # ifndef MLN_INCLUDE_ONLY
 
     template <typename G, typename P, typename E>
@@ -128,6 +132,13 @@ namespace mln
 
     template <typename G, typename P, typename E>
     inline
+    graph_iter_base<G, P, E>::operator unsigned() const
+    {
+      return p_.id();
+    }
+
+    template <typename G, typename P, typename E>
+    inline
     const P&
     graph_iter_base<G, P, E>::subj_()
     {
diff --git a/milena/mln/util/internal/graph_nbh_iter_base.hh b/milena/mln/util/internal/graph_nbh_iter_base.hh
index 14950a1..f6f02ea 100644
--- a/milena/mln/util/internal/graph_nbh_iter_base.hh
+++ b/milena/mln/util/internal/graph_nbh_iter_base.hh
@@ -61,6 +61,9 @@ namespace mln
 
 	/// Return current index
 	unsigned index() const;
+
+	/// Conversion operator. Returns the element ID.
+	operator unsigned() const;
 	/// \}
 
 	/// Proxy.
@@ -145,6 +148,13 @@ namespace mln
 
     template <typename G, typename C, typename P, typename E>
     inline
+    nbh_iterator_base<G, C, P, E>::operator unsigned() const
+    {
+      return p_.id();
+    }
+
+    template <typename G, typename C, typename P, typename E>
+    inline
     const P&
     nbh_iterator_base<G, C, P, E>::subj_()
     {
diff --git a/milena/tests/util/Makefile.am b/milena/tests/util/Makefile.am
index d0fe4be..fcfb902 100644
--- a/milena/tests/util/Makefile.am
+++ b/milena/tests/util/Makefile.am
@@ -6,6 +6,7 @@ include $(top_srcdir)/milena/tests/tests.mk
 check_PROGRAMS =				\
   branch_iter					\
   branch_iter_ind				\
+  dual_graph 					\
   eat						\
   graph						\
   lazy_set					\
@@ -19,6 +20,7 @@ check_PROGRAMS =				\
 
 branch_iter_SOURCES = branch_iter.cc
 branch_iter_ind_SOURCES = branch_iter_ind.cc
+dual_graph_SOURCES = dual_graph.cc
 eat_SOURCES = eat.cc
 graph_SOURCES = graph.cc
 lazy_set_SOURCES = lazy_set.cc
diff --git a/milena/tests/util/dual_graph.cc b/milena/tests/util/dual_graph.cc
new file mode 100644
index 0000000..ff8c8ad
--- /dev/null
+++ b/milena/tests/util/dual_graph.cc
@@ -0,0 +1,164 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file   tests/util/dual_graph.cc
+/// test of mln::util::dual_graph
+
+#include <mln/util/graph.hh>
+#include <mln/util/dual_graph.hh>
+#include <iostream>
+
+int main ()
+{
+  using namespace mln;
+
+  util::graph g;
+
+  g.add_vertex (); // 0
+  g.add_vertex (); // 1
+  g.add_vertex (); // 2
+  g.add_vertex (); // 3
+  g.add_vertex (); // 4
+  g.add_vertex (); // 5
+  g.add_edge (0, 1);
+  g.add_edge (1, 0); // Not inserted twice
+  g.add_edge (0, 2);
+  g.add_edge (3, 4);
+  g.add_edge (4, 5);
+  g.add_edge (5, 4); // Not inserted twice
+  g.add_edge (5, 3);
+  g.add_edge (2, 1);
+
+  typedef util::dual_graph<util::graph> DG;
+  DG dg(g);
+
+  // Vertex iter and edge iter
+  {
+    unsigned i = 0;
+    mln_vertex_fwd_iter_(DG) v(dg);
+    for_all(v)
+      std::cout << v.index() << std::endl;
+//      mln_assertion(i++ == v.index());
+    //mln_assertion(i != 0);
+
+    i = 0;
+    mln_edge_fwd_iter_(util::graph) e(g);
+    for_all(e)
+      std::cout << e << std::endl;
+//      mln_assertion(i++ == e.index());
+//    mln_assertion(i != 0);*/
+  }
+/*  {
+    unsigned i = g.v_nmax() - 1;
+    mln_vertex_bkd_iter_(util::graph) v(g);
+    for_all(v)
+      mln_assertion(i-- == v.index());
+    mln_assertion(i != g.v_nmax() - 1);
+
+    i = g.e_nmax() - 1;
+    mln_edge_bkd_iter_(util::graph) e(g);
+    for_all(e)
+      mln_assertion(i-- == e.index());
+    mln_assertion(i != g.e_nmax() - 1);
+  }
+
+  // vertex iter + Edge nbh iter
+  {
+    mln_vertex_fwd_iter_(util::graph) v(g);
+    mln_vertex_nbh_edge_fwd_iter_(util::graph) n(v);
+    for_all(v)
+    {
+      unsigned i = 0;
+      for_all(n)
+	mln_assertion(i++ == n.index());
+      mln_assertion(i != 0);
+    }
+  }
+  {
+    mln_vertex_bkd_iter_(util::graph) v(g);
+    mln_vertex_nbh_edge_bkd_iter_(util::graph) e(v);
+    for_all(v)
+    {
+      unsigned i = v.nmax_nbh_edges();
+      for_all(e)
+	mln_assertion(--i == e.index());
+      mln_assertion((v.nmax_nbh_edges() == 0 && i == 0) || i != v.nmax_nbh_edges());
+    }
+  }
+
+  {
+    mln_edge_fwd_iter_(util::graph) e(g);
+    mln_edge_nbh_edge_fwd_iter_(util::graph) n(e);
+    for_all(e)
+    {
+      unsigned i = 0;
+      for_all(n)
+	++i;
+      // we check i == e.nmax_nbh_edges() - 2 since e is it's own neighboor and the
+      // iterator skip it.
+      mln_assertion((i == 0 && e.nmax_nbh_edges() < 2) || i == e.nmax_nbh_edges() - 2);
+    }
+  }
+  {
+    mln_edge_bkd_iter_(util::graph) e(g);
+    mln_edge_nbh_edge_bkd_iter_(util::graph) n(e);
+    for_all(e)
+    {
+      //std::cout << "== e.id() = " << e.id() << std::endl;
+      unsigned i = e.nmax_nbh_edges();
+      for_all(n)
+	--i;
+      // we check i == e.nmax_nbh_edges() - 2 since e is it's own neighboor and the
+      // iterator skip it.
+      mln_assertion((i == e.nmax_nbh_edges() && e.nmax_nbh_edges() < 2) || i == 2);
+
+    }
+  }
+
+  {
+    mln_vertex_fwd_iter_(util::graph) v(g);
+    mln_vertex_nbh_vertex_fwd_iter_(util::graph) n(v);
+    for_all(v)
+    {
+      unsigned i = 0;
+      for_all(n)
+	++i;
+      mln_assertion(i == v.nmax_nbh_vertices());
+    }
+  }
+  {
+    mln_vertex_bkd_iter_(util::graph) v(g);
+    mln_vertex_nbh_vertex_bkd_iter_(util::graph) n(v);
+    for_all(v)
+    {
+      unsigned i = v.nmax_nbh_vertices();
+      for_all(n)
+	--i;
+      mln_assertion(i == 0);
+    }
+  }*/
+}
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Factor code for erosion on lines.
	* mln/accu/transform_directional.hh (include): Layout.
	(output): Fix typedef.
	* mln/accu/transform_diagonal.hh: Likewise.
	Fix declaration signature.
	* tests/accu/transform_directional.cc: New.
	* tests/accu/transform_diagonal.cc: New.
	* mln/accu/all.hh: Update.
	* mln/morpho/erosion.spe.hh
	(erosion_dispatch_wrt_win): Handle the case win.size == 1.
	Remove useless qualif morpho::.
	(erosion_dispatch_wrt_win): Factor code for hline2d and vline2d
	into...
	(erosion_dispatch_line): ...this new overloaded routine.
	(erosion_dispatch_diagonal): Remove check on kind::logic cause it
	also works on this case. 
	To be consistent:
	* mln/accu/snake_2d.hh: Rename as...
	* mln/accu/transform_snake.hh: ...this.
	* mln/morpho/erosion.spe.hh (erosion_arbitrary_2d): Update.
	* mln/morpho/includes.hh: Update.
	* tests/accu/snake_2d.cc: Rename as...
	* tests/accu/transform_snake.cc: ...this.
	* tests/accu/Makefile.am: Update.
 mln/accu/all.hh                     |    5 +-
 mln/accu/transform_diagonal.hh      |   15 +++---
 mln/accu/transform_directional.hh   |    5 +-
 mln/accu/transform_snake.hh         |   64 ++++++++++++++--------------
 mln/morpho/erosion.spe.hh           |   82 +++++++-----------------------------
 mln/morpho/includes.hh              |    3 -
 tests/accu/Makefile.am              |    8 ++-
 tests/accu/transform_diagonal.cc    |   23 +++++++---
 tests/accu/transform_directional.cc |   12 +++--
 tests/accu/transform_snake.cc       |    8 +--
 10 files changed, 98 insertions(+), 127 deletions(-)
Index: tests/accu/transform_snake.cc
--- tests/accu/transform_snake.cc	(revision 2882)
+++ tests/accu/transform_snake.cc	(working copy)
@@ -25,12 +25,12 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/// \file tests/accu/snake_2d.cc
+/// \file tests/accu/transform_snake.cc
 ///
-/// Tests on mln::accu::snake_2d.
+/// Tests on mln::accu::transform_snake.
 
 #include <mln/core/image/image2d.hh>
-#include <mln/accu/snake_2d.hh>
+#include <mln/accu/transform_snake.hh>
 #include <mln/accu/count.hh>
 #include <mln/win/rectangle2d.hh>
 #include <mln/pw/all.hh>
@@ -45,7 +45,7 @@
   win::rectangle2d rec(3, 3);
 
   image2d<unsigned>
-    out = accu::snake_2d(accu::meta::count(), ima, rec),
+    out = accu::transform_snake(accu::meta::count(), ima, rec),
     ref(ima.domain());
 
   mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
Property changes on: tests/accu/transform_snake.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: tests/accu/transform_diagonal.cc
--- tests/accu/transform_diagonal.cc	(revision 2882)
+++ tests/accu/transform_diagonal.cc	(working copy)
@@ -25,14 +25,13 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/// \file tests/accu/snake_2d.cc
+/// \file tests/accu/transform_diagonal.cc
 ///
-/// Tests on mln::accu::snake_2d.
+/// Tests on mln::accu::transform_diagonal.
 
 #include <mln/core/image/image2d.hh>
-#include <mln/accu/snake_2d.hh>
+#include <mln/accu/transform_diagonal.hh>
 #include <mln/accu/count.hh>
-#include <mln/win/rectangle2d.hh>
 #include <mln/pw/all.hh>
 #include <mln/level/compare.hh>
 
@@ -42,11 +41,21 @@
   using namespace mln;
 
   image2d<int> ima(4, 5);
-  win::rectangle2d rec(3, 3);
 
+  {
+    win::diag2d w(3);
   image2d<unsigned>
-    out = accu::snake_2d(accu::meta::count(), ima, rec),
+      out = accu::transform_diagonal(accu::meta::count(), ima, w),
     ref(ima.domain());
+    mln_assertion(out == (pw::cst(w.size()) | ima.domain()));
+  }
+
+  {
+    win::backdiag2d w(3);
+    image2d<unsigned>
+      out = accu::transform_diagonal(accu::meta::count(), ima, w),
+      ref(ima.domain());
+    mln_assertion(out == (pw::cst(w.size()) | ima.domain()));
+  }
 
-  mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
 }
Property changes on: tests/accu/transform_diagonal.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: tests/accu/Makefile.am
--- tests/accu/Makefile.am	(revision 2882)
+++ tests/accu/Makefile.am	(working copy)
@@ -19,8 +19,10 @@
   nil						\
   pair						\
   rank						\
-  snake_2d					\
   transform					\
+  transform_diagonal				\
+  transform_directional				\
+  transform_snake				\
   tuple
 
 all_accus_SOURCES = all_accus.cc
@@ -39,8 +41,10 @@
 nil_SOURCES = nil.cc
 pair_SOURCES = pair.cc
 rank_SOURCES = rank.cc
-snake_2d_SOURCES = snake_2d.cc
 transform_SOURCES = transform.cc
+transform_diagonal_SOURCES = transform_diagonal.cc
+transform_directional_SOURCES = transform_directional.cc
+transform_snake_SOURCES = transform_snake.cc
 tuple_SOURCES = tuple.cc
 
 TESTS = $(check_PROGRAMS)
Index: tests/accu/transform_directional.cc
--- tests/accu/transform_directional.cc	(revision 2882)
+++ tests/accu/transform_directional.cc	(working copy)
@@ -25,12 +25,12 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/// \file tests/accu/snake_2d.cc
+/// \file tests/accu/transform_directional.cc
 ///
-/// Tests on mln::accu::snake_2d.
+/// Tests on mln::accu::transform_directional.
 
 #include <mln/core/image/image2d.hh>
-#include <mln/accu/snake_2d.hh>
+#include <mln/accu/transform_directional.hh>
 #include <mln/accu/count.hh>
 #include <mln/win/rectangle2d.hh>
 #include <mln/pw/all.hh>
@@ -44,9 +44,11 @@
   image2d<int> ima(4, 5);
   win::rectangle2d rec(3, 3);
 
+  for (unsigned dir = 0; dir < 2; ++dir)
+  {
   image2d<unsigned>
-    out = accu::snake_2d(accu::meta::count(), ima, rec),
+      out = accu::transform_directional(accu::meta::count(), ima, rec, dir),
     ref(ima.domain());
-
   mln_assertion(out == (pw::cst(rec.size()) | ima.domain()));
 }
+}
Property changes on: tests/accu/transform_directional.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/accu/transform_directional.hh
--- mln/accu/transform_directional.hh	(revision 2882)
+++ mln/accu/transform_directional.hh	(working copy)
@@ -40,6 +40,7 @@
 #include <mln/core/concept/image.hh>
 #include <mln/core/concept/meta_accumulator.hh>
 #include <mln/core/alias/window2d.hh>
+# include <mln/win/diff.hh>
 #include <mln/win/shift.hh>
 #include <mln/geom/delta.hh>
 #include <mln/literal/zero.hh>
@@ -119,7 +120,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 	enum { dim = I::site::dim };
 
@@ -190,7 +191,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
Index: mln/accu/all.hh
--- mln/accu/all.hh	(revision 2882)
+++ mln/accu/all.hh	(working copy)
@@ -80,9 +80,12 @@
 // Routines.
 
 # include <mln/accu/convolve.hh>
-# include <mln/accu/snake_2d.hh>
 # include <mln/accu/transform.hh>
 # include <mln/accu/transform_stop.hh>
 
+# include <mln/accu/transform_directional.hh>
+# include <mln/accu/transform_diagonal.hh>
+# include <mln/accu/transform_snake.hh>
+
 
 #endif // ! MLN_ACCU_ALL_HH
Index: mln/accu/transform_diagonal.hh
--- mln/accu/transform_diagonal.hh	(revision 2882)
+++ mln/accu/transform_diagonal.hh	(working copy)
@@ -40,6 +40,7 @@
 #include <mln/core/concept/image.hh>
 #include <mln/core/concept/meta_accumulator.hh>
 #include <mln/core/alias/window2d.hh>
+#include <mln/win/diff.hh>
 #include <mln/win/shift.hh>
 #include <mln/geom/delta.hh>
 #include <mln/extension/adjust.hh>
@@ -62,15 +63,13 @@
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_result(A))
     transform_diagonal(const Accumulator<A>&,
-		       const Image<I>& input, const Window<W>& win,
-		       unsigned dir);
+		       const Image<I>& input, const Window<W>& win);
 
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
     transform_diagonal(const Meta_Accumulator<A>&,
-		       const Image<I>& input, const Window<W>& win,
-		       unsigned dir);
+		       const Image<I>& input, const Window<W>& win);
 
 
 
@@ -110,7 +109,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
@@ -174,7 +173,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
@@ -241,7 +240,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
@@ -304,7 +303,7 @@
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
Index: mln/accu/transform_snake.hh
--- mln/accu/transform_snake.hh	(revision 2882)
+++ mln/accu/transform_snake.hh	(working copy)
@@ -25,15 +25,13 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_ACCU_SNAKE_2D_HH
-# define MLN_ACCU_SNAKE_2D_HH
+#ifndef MLN_ACCU_TRANSFORM_SNAKE_HH
+# define MLN_ACCU_TRANSFORM_SNAKE_HH
 
-/// \file mln/accu/snake_2d.hh
+/// \file mln/accu/transform_snake.hh
 ///
 /// Run an accumulator in a snake-like browsing.
 ///
-/// \todo Rename as transform_snake_2d.
-///
 /// \todo Make it n-D.
 ///
 /// \todo Split dispatch and impl.
@@ -47,6 +45,8 @@
 #include <mln/win/shift.hh>
 #include <mln/geom/delta.hh>
 #include <mln/extension/adjust.hh>
+
+# include <mln/canvas/browsing/snake_fwd.hh>
 #include <mln/canvas/browsing/snake_generic.hh>
 
 
@@ -60,12 +60,12 @@
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_result(A))
-    snake_2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+    transform_snake(const Accumulator<A>&, const Image<I>& input, const Window<W>& win);
 
 
     template <typename A, typename I, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    snake_2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win);
+    transform_snake(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win);
 
 
 
@@ -76,7 +76,7 @@
 
 
       template <typename I, typename W>
-      void snake_2d_tests(const Image<I>& input_, const Window<W>& win_)
+      void transform_snake_tests(const Image<I>& input_, const Window<W>& win_)
       {
 	const I& input = exact(input_);
 	const W& win   = exact(win_);
@@ -93,9 +93,9 @@
       // Functor.
 
       template <typename I, typename W, typename A>
-      struct snake_2d_functor
+      struct transform_snake_functor
       {
-	typedef snake_2d_functor<I,W, A> self;
+	typedef transform_snake_functor<I,W, A> self;
 	typedef void (self::*move_fun)();
 	typedef mln_deduce(I, psite, delta) dpsite;
 
@@ -129,7 +129,7 @@
 	std::vector<move_fun> moves;
 	std::vector<dpsite> dps;
 
-	snake_2d_functor(const Image<I>& input, const Window<W>& win)
+	transform_snake_functor(const Image<I>& input, const Window<W>& win)
 	  : input(exact(input)),
 	    win(exact(win)),
 	    accu(),
@@ -245,15 +245,15 @@
       // Functor (fastest version).
 
       template <typename I, typename W, typename A>
-      struct snake_2d_fastest_functor
+      struct transform_snake_fastest_functor
       {
-	typedef snake_2d_fastest_functor<I,W,A> self;
+	typedef transform_snake_fastest_functor<I,W,A> self;
 	typedef void (self::*move_fun)();
 	typedef mln_deduce(I, psite, delta) dpsite;
 
 	const I& input;
 	const W& win;
-	mln_concrete(I) output;
+	mln_ch_value(I, mln_result(A)) output;
 	A accu;
 
 	mln_psite(I) p;
@@ -282,7 +282,7 @@
 	std::vector<move_fun> moves;
 	std::vector<dpsite> dps;
 
-	snake_2d_fastest_functor(const I& input, const W& win)
+	transform_snake_fastest_functor(const I& input, const W& win)
 	  : input(input),
 	    win(win),
 	    accu(),
@@ -393,11 +393,11 @@
       template <typename A, typename I, typename W>
       inline
       mln_ch_value(I, mln_result(A))
-      snake_2d_dispatch(trait::image::speed::any,
+      transform_snake_dispatch(trait::image::speed::any,
 			const Accumulator<A>& /* FIXME a */,
 			const Image<I>& input, const Window<W>& win)
       {
-	typedef snake_2d_functor<I, W, A> F;
+	typedef transform_snake_functor<I, W, A> F;
 	F f(exact(input), exact(win));  // FIXME: Pass a to f.
 	canvas::browsing::snake_generic(f);
 	return f.output;
@@ -406,11 +406,11 @@
       template <typename A, typename I, typename W>
       inline
       mln_ch_value(I, mln_result(A))
-      snake_2d_dispatch(trait::image::speed::fastest,
+      transform_snake_dispatch(trait::image::speed::fastest,
 			const Accumulator<A>& /* FIXME a*/,
 			const Image<I>& input, const Window<W>& win)
       {
-	typedef snake_2d_fastest_functor<I, W, A> F;
+	typedef transform_snake_fastest_functor<I, W, A> F;
 	F f(exact(input), exact(win));  // FIXME: Pass a to f.
 	canvas::browsing::snake_generic(f);
 	return f.output;
@@ -419,10 +419,10 @@
       template <typename A, typename I, typename W>
       inline
       mln_ch_value(I, mln_result(A))
-      snake_2d_dispatch(const Accumulator<A>& a,
+      transform_snake_dispatch(const Accumulator<A>& a,
 			const Image<I>& input, const Window<W>& win)
       {
-	return snake_2d_dispatch(mln_trait_image_speed(I)(),
+	return transform_snake_dispatch(mln_trait_image_speed(I)(),
 				 a, input, win);
       }
 
@@ -434,18 +434,18 @@
     template <typename A, typename I, typename W>
     inline
     mln_ch_value(I, mln_result(A))
-    snake_2d(const Accumulator<A>& a,
+    transform_snake(const Accumulator<A>& a,
 	     const Image<I>& input, const Window<W>& win)
     {
-      trace::entering("accu::snake_2d");
+      trace::entering("accu::transform_snake");
 
-      internal::snake_2d_tests(input, win);
+      internal::transform_snake_tests(input, win);
 
       extension::adjust(input, geom::delta(win) + 1);
       mln_ch_value(I, mln_result(A)) output;
-      output = internal::snake_2d_dispatch(a, input, win);
+      output = internal::transform_snake_dispatch(a, input, win);
 
-      trace::exiting("accu::snake_2d");
+      trace::exiting("accu::transform_snake");
       return output;
     }
 
@@ -453,21 +453,21 @@
     template <typename A, typename I, typename W>
     inline
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    snake_2d(const Meta_Accumulator<A>& a,
+    transform_snake(const Meta_Accumulator<A>& a,
 	     const Image<I>& input, const Window<W>& win)
     {
-      trace::entering("accu::snake_2d");
+      trace::entering("accu::transform_snake");
 
-      internal::snake_2d_tests(input, win);
+      internal::transform_snake_tests(input, win);
 
       typedef mln_accu_with(A, mln_value(I)) A_;
       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
 
       extension::adjust(input, geom::delta(win) + 1);
       mln_ch_value(I, mln_result(A_)) output;
-      output = internal::snake_2d_dispatch(a_, input, win);
+      output = internal::transform_snake_dispatch(a_, input, win);
 
-      trace::exiting("accu::snake_2d");
+      trace::exiting("accu::transform_snake");
       return output;
     }
 
@@ -479,4 +479,4 @@
 } // end of namespace mln
 
 
-#endif // ! MLN_ACCU_SNAKE_2D_HH
+#endif // ! MLN_ACCU_TRANSFORM_SNAKE_HH
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh	(revision 2882)
+++ mln/morpho/erosion.spe.hh	(working copy)
@@ -39,18 +39,9 @@
 # include <mln/win/octagon2d.hh>
 # include <mln/win/rectangle2d.hh>
 
-# include <mln/win/shift.hh>
-# include <mln/win/diff.hh>
-
 # include <mln/accu/min_h.hh>
 # include <mln/accu/line.hh>
 
-# include <mln/canvas/browsing/snake_fwd.hh>
-# include <mln/canvas/browsing/snake_generic.hh>
-# include <mln/canvas/browsing/directional.hh>
-# include <mln/canvas/browsing/diagonal2d.hh>
-# include <mln/canvas/browsing/backdiagonal2d.hh>
-
 
 /// \file mln/morpho/erosion.spe.hh
 ///
@@ -269,7 +260,7 @@
 	A a;
 
 	extension::adjust_fill(input, geom::delta(win) + 1, a);
-	mln_concrete(I) output = accu::snake_2d(a, input, win);
+	mln_concrete(I) output = accu::transform_snake(a, input, win);
 
 	trace::exiting("morpho::impl:erosion_arbitrary_2d");
 	return output;
@@ -408,9 +399,10 @@
       mln_concrete(I)
       erosion_dispatch_wrt_win(const I& input, const win::rectangle2d& win)
       {
+	if (win.size() == 1)
+	  return clone(input);
 	if (win.size() <= 9) // FIXME: Hard-coded!
 	  return erosion_dispatch_for_generic(input, win);
-	else
 	  return impl::erosion_rectangle2d(input, win);
       }
 
@@ -420,74 +412,35 @@
       erosion_dispatch_wrt_win(const I& input, const win::octagon2d& win)
       {
 	if (win.length() < 5)
-	  return morpho::impl::erosion_arbitrary_2d(input, win);
+	  return impl::erosion_arbitrary_2d(input, win);
 	else
 	  return impl::erosion_octagon2d(input, win);
       }
 
 
-      /// Handling win::hline2d.
-      /// \{
-
-      template <typename I>
-      mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::true_,
-			       const I& input, const win::hline2d& win)
-      {
-	return impl::erosion_directional(input, win, 1);
-      }
-
-      template <typename I>
-      mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::false_,
-			       const I& input, const win::hline2d& win)
-      {
-	return erosion_dispatch_for_generic(input, win);
-      }
-
-      template <typename I>
-      mln_concrete(I)
-      erosion_dispatch_wrt_win(const I& input, const win::hline2d& win)
-      {
-	if (win.size() == 1)
-	  return clone(input);
-	else if (win.size() == 3)
-	  return erosion_dispatch_for_generic(input, win);
-	else
-	  {
-	    enum { test = mlc_is_a(mln_pset(I), Box)::value
-		   && mlc_equal(mln_trait_image_quant(I),
-				mln::trait::image::quant::low)::value };
-	    return erosion_dispatch_wrt_win(metal::bool_<test>(),
-					    input, win);
-	  }
-      }
-
-      /// \}
-
 
-      /// Handling win::vline2d.
+      /// Handling win::line(s).
       /// \{
 
-      template <typename I>
+      template <typename I, typename W>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::true_,
-			       const I& input, const win::vline2d& win)
+      erosion_dispatch_line(metal::true_,
+			    const I& input, const W& win)
       {
-	return impl::erosion_directional(input, win, 0);
+	return impl::erosion_directional(input, win, W::dir);
       }
 
-      template <typename I>
+      template <typename I, typename W>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::false_,
-			       const I& input, const win::vline2d& win)
+      erosion_dispatch_line(metal::false_,
+			    const I& input, const W& win)
       {
 	return erosion_dispatch_for_generic(input, win);
       }
 
-      template <typename I>
+      template <typename I, typename M, unsigned i, typename C>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(const I& input, const win::vline2d& win)
+      erosion_dispatch_wrt_win(const I& input, const win::line<M,i,C>& win)
       {
 	if (win.size() == 1)
 	  return clone(input);
@@ -498,7 +451,7 @@
 	    enum { test = mlc_is_a(mln_pset(I), Box)::value
 		   && mlc_equal(mln_trait_image_quant(I),
 				mln::trait::image::quant::low)::value };
-	    return erosion_dispatch_wrt_win(metal::bool_<test>(),
+	    return erosion_dispatch_line(metal::bool_<test>(),
 					    input, win);
 	  }
       }
@@ -537,9 +490,7 @@
 	  return erosion_dispatch_for_generic(input, win);
 	else
 	  {
-	    enum { test = mlc_is_not(mln_trait_image_kind(I),
-				     mln::trait::image::kind::logic)::value
-		   && mlc_is_a(mln_pset(I), Box)::value
+	    enum { test = mlc_is_a(mln_pset(I), Box)::value
 		   && mlc_equal(mln_trait_image_quant(I),
 				mln::trait::image::quant::low)::value };
 	    return erosion_dispatch_diagonal(metal::bool_<test>(),
@@ -565,6 +516,7 @@
       /// \}
 
 
+
       // The dispatch entry point.
 
       template <typename I, typename W>
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh	(revision 2882)
+++ mln/morpho/includes.hh	(working copy)
@@ -51,11 +51,12 @@
 # include <mln/accu/max_h.hh>
 # include <mln/accu/rank.hh>
 
-# include <mln/accu/snake_2d.hh>
 # include <mln/accu/transform.hh>
 # include <mln/accu/transform_stop.hh>
+
 # include <mln/accu/transform_directional.hh>
 # include <mln/accu/transform_diagonal.hh>
+# include <mln/accu/transform_snake.hh>
 
 # include <mln/fun/v2v/saturate.hh>
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            cleanup-2008 2882: Move diagonal-related code out	of erosion, then factor.
                        
                        
by Thierry Geraud 14 Nov '08
                    by Thierry Geraud 14 Nov '08
14 Nov '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Move diagonal-related code out of erosion, then factor.
	* mln/accu/transform_diagonal.hh: New file.
	* mln/morpho/erosion.spe.hh
	(erosion_diagonal2d_functor),
	(erosion_diagonal2d_fastest_functor),
	(erosion_backdiagonal2d_functor),
	(erosion_backdiagonal2d_fastest_functor): Move and rename as...
	* mln/accu/transform_diagonal.hh
	(diagonal_functor, diagonal_fastest_functor),
	(backdiagonal_functor, backdiagonal_fastest_functor): ...these.
	* mln/morpho/erosion.spe.hh (erosion_diagonal2d): Rename as...
	(erosion_diagonal_2d): ...this; it is the only impl routine.
	(erosion_backdiagonal2d),
	(erosion_diagonal2d_fastest),
	(erosion_backdiagonal2d_fastest): Remove these impl routines.
	Thanks to factorization in accu::transform_diagonal, those are
	now useless.
	(erosion_dispatch_for_diagonal2d),
	(erosion_dispatch_for_backdiagonal2d): Factor into...
	(erosion_dispatch_diagonal): ...this new dispatch routine.
	Now both diagonals are handled by the same code.
	* mln/morpho/includes.hh: Update.
	* mln/accu/transform_directional.hh
	(diff): Remove useless include.
	* mln/win/line.hh: Upgrade doc style.
	(dir): New constant.
 accu/transform_diagonal.hh    |  481 ++++++++++++++++++++++++++++++++++++++++++
 accu/transform_directional.hh |    1 
 morpho/erosion.spe.hh         |  468 +++-------------------------------------
 morpho/includes.hh            |    1 
 win/line.hh                   |   17 -
 5 files changed, 526 insertions(+), 442 deletions(-)
Index: mln/accu/transform_directional.hh
--- mln/accu/transform_directional.hh	(revision 2881)
+++ mln/accu/transform_directional.hh	(working copy)
@@ -40,7 +40,6 @@
 #include <mln/core/concept/image.hh>
 #include <mln/core/concept/meta_accumulator.hh>
 #include <mln/core/alias/window2d.hh>
-#include <mln/win/diff.hh>
 #include <mln/win/shift.hh>
 #include <mln/geom/delta.hh>
 #include <mln/literal/zero.hh>
Index: mln/accu/transform_diagonal.hh
--- mln/accu/transform_diagonal.hh	(revision 0)
+++ mln/accu/transform_diagonal.hh	(revision 0)
@@ -0,0 +1,481 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_ACCU_TRANSFORM_DIAGONAL_HH
+# define MLN_ACCU_TRANSFORM_DIAGONAL_HH
+
+/// \file mln/accu/transform_diagonal.hh
+///
+/// Run an accumulator over a diagonal.
+///
+/// \todo Split dispatch and impl.
+///
+/// \todo Pass the accumulator to the function-object.
+
+
+#include <mln/core/concept/image.hh>
+#include <mln/core/concept/meta_accumulator.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/win/shift.hh>
+#include <mln/geom/delta.hh>
+#include <mln/extension/adjust.hh>
+
+#include <mln/win/diag2d.hh>
+#include <mln/canvas/browsing/diagonal2d.hh>
+
+#include <mln/win/backdiag2d.hh>
+#include <mln/canvas/browsing/backdiagonal2d.hh>
+
+
+
+namespace mln
+{
+
+  namespace accu
+  {
+
+
+    template <typename A, typename I, typename W>
+    mln_ch_value(I, mln_result(A))
+    transform_diagonal(const Accumulator<A>&,
+		       const Image<I>& input, const Window<W>& win,
+		       unsigned dir);
+
+
+    template <typename A, typename I, typename W>
+    mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+    transform_diagonal(const Meta_Accumulator<A>&,
+		       const Image<I>& input, const Window<W>& win,
+		       unsigned dir);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace internal
+    {
+
+
+      // Tests.
+
+
+      template <typename I, typename W>
+      void transform_diagonal_tests(const Image<I>& input_, const Window<W>& win_)
+      {
+	const I& input = exact(input_);
+	const W& win   = exact(win_);
+
+	mln_precondition(input.has_data());
+	mln_precondition(! win.is_empty());
+	// mln_precondition(! win.is_valid());
+
+	(void) input;
+	(void) win;
+      }
+
+
+
+      // Functors.
+
+
+      template <typename I_, typename W, typename A>
+      struct diagonal_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+	enum { dim = I::site::dim };
+	unsigned dir;
+
+	window2d win_left, win_right;
+
+	mln_qiter(window2d) q_l, q_r;
+
+	diagonal_functor(const I& input, const W& win)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, dpsite(1, -1)) - win),
+	    win_right(win - win::shift(win, dpsite(1, -1))),
+	    q_l(win_left, p),
+	    q_r(win_right, p)
+	{
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void next()
+	{
+	  for_all(q_l)
+	    accu.untake(input(q_l));
+	  for_all(q_r)
+	    accu.take(input(q_r));
+	  output(p) = accu;
+	}
+
+
+	void init_diag()
+	{
+	  accu.init();
+	  p = p - dpsite(-1, 1);
+	  mln_qiter(W) q(win, p);
+	  for_all(q)
+	    accu.take(input(q));
+	  p = p + dpsite(-1, 1);
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+
+      template <typename I_, typename W, typename A>
+      struct backdiagonal_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+	enum { dim = I::site::dim };
+	unsigned dir;
+
+	window2d win_left, win_right;
+
+	mln_qiter(window2d) q_l, q_r;
+
+	backdiagonal_functor(const I& input, const W& win)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, dpsite(-1, -1)) - win),
+	    win_right(win - win::shift(win, dpsite(-1, -1))),
+	    q_l(win_left, p),
+	    q_r(win_right, p)
+	{
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void next()
+	{
+	  for_all(q_l)
+	    accu.untake(input(q_l));
+	  for_all(q_r)
+	    accu.take(input(q_r));
+	  output(p) = accu;
+	}
+
+
+	void init_diag()
+	{
+	  accu.init();
+	  p = p - dpsite(1, 1);
+	  mln_qiter(W) q(win, p);
+	  for_all(q)
+	    accu.take(input(q));
+	  p = p + dpsite(1, 1);
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+
+      // Functors (fastest versions).
+
+
+      template <typename I_, typename W, typename A>
+      struct diagonal_fastest_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+	enum { dim = I::site::dim };
+	unsigned dir;
+
+	window2d win_left, win_right;
+
+	mln_qixter(const I, window2d) q_l, q_r;
+
+	diagonal_fastest_functor(const I& input, const W& win)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, dpsite(1, -1)) - win),
+	    win_right(win - win::shift(win, dpsite(1, -1))),
+	    q_l(input, win_left, p),
+	    q_r(input, win_right, p)
+	{
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void next()
+	{
+	  for_all(q_l)
+	    accu.untake(q_l.val());
+	  for_all(q_r)
+	    accu.take(q_r.val());
+	  output(p) = accu;
+	}
+
+
+	void init_diag()
+	{
+	  accu.init();
+	  p = p - dpsite(-1, 1);
+	  mln_qixter(const I, W) q(input, win, p);
+	  for_all(q)
+	    accu.take(q.val());
+	  p = p + dpsite(-1, 1);
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+      template <typename I_, typename W, typename A>
+      struct backdiagonal_fastest_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+	enum { dim = I::site::dim };
+	unsigned dir;
+
+	window2d win_left, win_right;
+
+	mln_qixter(const I, window2d) q_l, q_r;
+
+	backdiagonal_fastest_functor(const I& input, const W& win)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, dpsite(-1, -1)) - win),
+	    win_right(win - win::shift(win, dpsite(-1, -1))),
+	    q_l(input, win_left, p),
+	    q_r(input, win_right, p)
+	{
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void next()
+	{
+	  for_all(q_l)
+	    accu.untake(q_l.val());
+	  for_all(q_r)
+	    accu.take(q_r.val());
+	  output(p) = accu;
+	}
+
+
+	void init_diag()
+	{
+	  accu.init();
+	  p = p - dpsite(1, 1);
+	  mln_qixter(const I, W) q(input, win, p);
+	  for_all(q)
+	    accu.take(q.val());
+	  p = p + dpsite(1, 1);
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+
+
+      // Both dispatch and implementation (hum...)
+
+      template <typename A, typename I>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_diagonal_dispatch(trait::image::speed::any,
+				  const Accumulator<A>& /* FIXME a */,
+				  const Image<I>& input, const win::diag2d& win)
+      {
+	typedef diagonal_functor<I, win::diag2d, A> F;
+	F f(exact(input), win); // FIXME: Pass a to f.
+	canvas::browsing::diagonal2d(f);
+	return f.output;
+      }
+
+      template <typename A, typename I>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_diagonal_dispatch(trait::image::speed::any,
+				  const Accumulator<A>& /* FIXME a */,
+				  const Image<I>& input, const win::backdiag2d& win)
+      {
+	typedef backdiagonal_functor<I, win::backdiag2d, A> F;
+	F f(exact(input), win); // FIXME: Pass a to f.
+	canvas::browsing::backdiagonal2d(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_diagonal_dispatch(trait::image::speed::fastest,
+				  const Accumulator<A>& /* FIXME a*/,
+				  const Image<I>& input, const win::diag2d& win)
+      {
+	typedef diagonal_fastest_functor<I, win::diag2d, A> F;
+	F f(exact(input), win); // FIXME: Pass a to f.
+	canvas::browsing::diagonal2d(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_diagonal_dispatch(trait::image::speed::fastest,
+				  const Accumulator<A>& /* FIXME a*/,
+				  const Image<I>& input, const win::backdiag2d& win)
+      {
+	typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
+	F f(exact(input), win); // FIXME: Pass a to f.
+	canvas::browsing::backdiagonal2d(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_diagonal_dispatch(const Accumulator<A>& a,
+				  const Image<I>& input, const Window<W>& win)
+      {
+	return transform_diagonal_dispatch(mln_trait_image_speed(I)(),
+					   a, input, exact(win));
+      }
+
+    } // end of namespace mln::accu::internal
+
+
+
+
+    template <typename A, typename I, typename W>
+    inline
+    mln_ch_value(I, mln_result(A))
+    transform_diagonal(const Accumulator<A>& a,
+		       const Image<I>& input, const Window<W>& win)
+    {
+      trace::entering("accu::transform_diagonal");
+
+      internal::transform_diagonal_tests(input, win);
+
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A)) output;
+      output = internal::transform_diagonal_dispatch(a, input, win);
+
+      trace::exiting("accu::transform_diagonal");
+      return output;
+    }
+
+
+    template <typename A, typename I, typename W>
+    inline
+    mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+    transform_diagonal(const Meta_Accumulator<A>& a,
+		       const Image<I>& input, const Window<W>& win)
+    {
+      trace::entering("accu::transform_diagonal");
+
+      internal::transform_diagonal_tests(input, win);
+
+      typedef mln_accu_with(A, mln_value(I)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_value(I)());
+
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A_)) output;
+      output = internal::transform_diagonal_dispatch(a_, input, win);
+
+      trace::exiting("accu::transform_diagonal");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH
Index: mln/win/line.hh
--- mln/win/line.hh	(revision 2881)
+++ mln/win/line.hh	(working copy)
@@ -73,12 +73,12 @@
     template <typename M, unsigned i, typename C>
     struct line : public internal::classical_window_base< dpoint<M, C>, line<M,i,C> >
     {
-      /*! \brief Constructor.
-       *
-       * \param[in] length Length of the line.
-       *
-       * \pre \p length is odd.
-       */
+      /// Direction.
+      enum { dir = i };
+
+      /// Constructor.
+      /// \param[in] length Length of the line.
+      /// \pre \p length is odd.
       line(unsigned length);
 	
       /// Give the line length.
@@ -87,9 +87,8 @@
       /// Give the line size, that is, its length.
       unsigned size() const;
 	
-      /*! \brief Give the maximum coordinate gap between the window
-       * center and a window point.
-       */
+      /// Give the maximum coordinate gap between the window
+      /// center and a window point.
       unsigned delta_() const;
 
       void print_(std::ostream& ostr) const;
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh	(revision 2881)
+++ mln/morpho/erosion.spe.hh	(working copy)
@@ -161,6 +161,9 @@
 
 
 
+      // Line case.
+
+
       template <typename I, typename G, unsigned Dir, typename C>
       inline
       mln_concrete(I)
@@ -210,6 +213,10 @@
       }
 
 
+
+      // Particular windows.
+
+
       template <typename I>
       inline
       mln_concrete(I)
@@ -250,7 +257,6 @@
       }
 
 
-
       template <typename I, typename W>
       inline
       mln_concrete(I)
@@ -270,7 +276,6 @@
       }
 
 
-
       template <typename I, typename W>
       inline
       mln_concrete(I)
@@ -290,350 +295,32 @@
       }
 
 
-
-      // Diagonal2d non fastest.
-      template <typename I_, typename W, typename A>
-      struct erosion_diagonal2d_functor
-      {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-	enum { dim = I::site::dim };
-	unsigned dir;
-
-	window2d win_left, win_right;
-
-	mln_qiter(window2d) q_l, q_r;
-
-	erosion_diagonal2d_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, dpsite(1, -1)) - win),
-	    win_right(win - win::shift(win, dpsite(1, -1))),
-	    q_l(win_left, p),
-	    q_r(win_right, p)
-	{
-	}
-
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	}
-
-	void next()
-	{
-	  for_all(q_l)
-	    accu.untake(input(q_l));
-	  for_all(q_r)
-	    accu.take(input(q_r));
-	  output(p) = accu;
-	}
-
-
-	void init_diag()
-	{
-	  accu.init();
-	  p = p - dpsite(-1, 1);
-	  mln_qiter(W) q(win, p);
-	  for_all(q)
-	    accu.take(input(q));
-	  p = p + dpsite(-1, 1);
-	}
-
-	void final()
-	{
-	}
-
-      };
-
-      // Backdiagonal2d non fastest.
-      template <typename I, typename W>
-      inline
-      mln_concrete(I)
-      erosion_diagonal2d(const Image<I>& input, const Window<W>& win)
-      {
-	trace::entering("morpho::impl:erosion_diagonal2d");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
-	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
-
-	typedef erosion_diagonal2d_functor<I, W, A> F;
-	F f(exact(input), exact(win));
-	canvas::browsing::diagonal2d(f);
-
-	trace::exiting("morpho::impl:erosion_diagonal2d");
-
-	return f.output;
-      }
-
-
-
-      template <typename I_, typename W, typename A>
-      struct erosion_backdiagonal2d_functor
-      {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-	enum { dim = I::site::dim };
-	unsigned dir;
-
-	window2d win_left, win_right;
-
-	mln_qiter(window2d) q_l, q_r;
-
-	erosion_backdiagonal2d_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, dpsite(-1, -1)) - win),
-	    win_right(win - win::shift(win, dpsite(-1, -1))),
-	    q_l(win_left, p),
-	    q_r(win_right, p)
-	{
-	}
-
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	}
-
-	void next()
-	{
-	  for_all(q_l)
-	    accu.untake(input(q_l));
-	  for_all(q_r)
-	    accu.take(input(q_r));
-	  output(p) = accu;
-	}
-
-
-	void init_diag()
-	{
-	  accu.init();
-	  p = p - dpsite(1, 1);
-	  mln_qiter(W) q(win, p);
-	  for_all(q)
-	    accu.take(input(q));
-	  p = p + dpsite(1, 1);
-	}
-
-	void final()
-	{
-	}
-
-      };
-
       template <typename I, typename W>
       inline
       mln_concrete(I)
-      erosion_backdiagonal2d(const Image<I>& input, const Window<W>& win)
-      {
-	trace::entering("morpho::impl:erosion_backdiagonal2d");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
-	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
-
-	typedef erosion_backdiagonal2d_functor<I, W, A> F;
-	F f(exact(input), exact(win));
-	canvas::browsing::backdiagonal2d(f);
-
-	trace::exiting("morpho::impl:erosion_backdiagonal2d");
-
-	return f.output;
-      }
-
-
-
-      // Diagonal2d fastest.
-      template <typename I_, typename W, typename A>
-      struct erosion_diagonal2d_fastest_functor
+      erosion_diagonal_2d(const Image<I>& input, const Window<W>& win)
       {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-	enum { dim = I::site::dim };
-	unsigned dir;
-
-	window2d win_left, win_right;
-
-	mln_qixter(const I, window2d) q_l, q_r;
-
-	erosion_diagonal2d_fastest_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, dpsite(1, -1)) - win),
-	    win_right(win - win::shift(win, dpsite(1, -1))),
-	    q_l(input, win_left, p),
-	    q_r(input, win_right, p)
-	{
-	}
+	trace::entering("morpho::impl:erosion_diagonal_2d");
 
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	}
-
-	void next()
-	{
-	  for_all(q_l)
-	    accu.untake(q_l.val());
-	  for_all(q_r)
-	    accu.take(q_r.val());
-	  output(p) = accu;
-	}
-
-
-	void init_diag()
-	{
-	  accu.init();
-	  p = p - dpsite(-1, 1);
-	  mln_qixter(const I, W) q(input, win, p);
-	  for_all(q)
-	    accu.take(q.val());
-	  p = p + dpsite(-1, 1);
-	}
-
-	void final()
-	{
-	}
-
-      };
-
-      template <typename I, typename W>
-      inline
-      mln_concrete(I)
-      erosion_diagonal2d_fastest(const Image<I>& input, const Window<W>& win)
-      {
-	trace::entering("morpho::impl:erosion_diagonal2d_fastest");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
+	typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
 	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
+	A a;
 
-	typedef erosion_diagonal2d_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win));
-	canvas::browsing::diagonal2d(f);
-
-	trace::exiting("morpho::impl:erosion_diagonal2d_fastest");
-
-	return f.output;
-      }
-
-
-
-      // Backdiagonal2d fastest.
-      template <typename I_, typename W, typename A>
-      struct erosion_backdiagonal2d_fastest_functor
-      {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-	enum { dim = I::site::dim };
-	unsigned dir;
-
-	window2d win_left, win_right;
-
-	mln_qixter(const I, window2d) q_l, q_r;
-
-	erosion_backdiagonal2d_fastest_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, dpsite(-1, -1)) - win),
-	    win_right(win - win::shift(win, dpsite(-1, -1))),
-	    q_l(input, win_left, p),
-	    q_r(input, win_right, p)
-	{
-	}
-
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	}
-
-	void next()
-	{
-	  for_all(q_l)
-	    accu.untake(q_l.val());
-	  for_all(q_r)
-	    accu.take(q_r.val());
-	  output(p) = accu;
-	}
-
+	extension::adjust_fill(input, geom::delta(win) + 1, a);
+	mln_concrete(I) output = accu::transform_diagonal(a, input, win);
 
-	void init_diag()
-	{
-	  accu.init();
-	  p = p - dpsite(1, 1);
-	  mln_qixter(const I, W) q(input, win, p);
-	  for_all(q)
-	    accu.take(q.val());
-	  p = p + dpsite(1, 1);
+	trace::exiting("morpho::impl:erosion_diagonal_2d");
+	return output;
 	}
 
-	void final()
-	{
-	}
 
-      };
 
-      template <typename I, typename W>
-      inline
-      mln_concrete(I)
-      erosion_backdiagonal2d_fastest(const Image<I>& input, const Window<W>& win)
-      {
-	trace::entering("morpho::impl:erosion_backdiagonal2d_fastest");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
-	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
+    } // end of namespace mln::morpho::impl
 
-	typedef erosion_backdiagonal2d_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win));
-	canvas::browsing::backdiagonal2d(f);
 
-	trace::exiting("morpho::impl:erosion_backdiagonal2d_fastest");
 
-	return f.output;
-      }
 
-    } // end of namespace mln::morpho::impl
+    // Dispatch.
 
 
     namespace internal
@@ -675,67 +362,6 @@
 
 
 
-      // dispatch for diagonal2d w.r.t. speed
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_diagonal2d(trait::image::speed::fastest,
-				      const I& input, const W& win)
-      {
-	return impl::erosion_diagonal2d_fastest(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_diagonal2d(trait::image::speed::any,
-				       const I& input, const W& win)
-      {
-	return impl::erosion_diagonal2d(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_diagonal2d(const I& input, const W& win)
-      {
-	trace::entering("morpho::erosion_dispatch_for_diagonal2d");
-	mln_concrete(I) ima =
-	  erosion_dispatch_for_diagonal2d(mln_trait_image_speed(I)(),
-					  input, win);
-	trace::exiting("morpho::erosion_dispatch_for_diagonal2d");
-	return ima;
-      }
-
-
-      // dispatch for backdiagonal2d w.r.t. speed
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_backdiagonal2d(trait::image::speed::fastest,
-				      const I& input, const W& win)
-      {
-	return impl::erosion_backdiagonal2d_fastest(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_backdiagonal2d(trait::image::speed::any,
-				       const I& input, const W& win)
-      {
-	return impl::erosion_backdiagonal2d(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_backdiagonal2d(const I& input, const W& win)
-      {
-	trace::entering("morpho::erosion_dispatch_for_backdiagonal2d");
-	mln_concrete(I) ima =
-	  erosion_dispatch_for_backdiagonal2d(mln_trait_image_speed(I)(),
-					      input, win);
-	trace::exiting("morpho::erosion_dispatch_for_backdiagonal2d");
-	return ima;
-      }
-
 
       // dispatch w.r.t. win
 
@@ -776,6 +402,8 @@
 						  input, win);
       }
 
+
+
       template <typename I>
       mln_concrete(I)
       erosion_dispatch_wrt_win(const I& input, const win::rectangle2d& win)
@@ -786,6 +414,7 @@
 	  return impl::erosion_rectangle2d(input, win);
       }
 
+
       template <typename I>
       mln_concrete(I)
       erosion_dispatch_wrt_win(const I& input, const win::octagon2d& win)
@@ -877,28 +506,30 @@
       /// \}
 
 
-      /// Handling win::diag2d.
+
+
+      /// Handling diagonals.
       /// \{
 
-      template <typename I>
+      template <typename I, typename W>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::true_,
-			       const I& input, const win::diag2d& win)
+      erosion_dispatch_diagonal(metal::true_,
+				const I& input, const W& win)
       {
-	return erosion_dispatch_for_diagonal2d(input, win);
+	return impl::erosion_diagonal_2d(input, win);
       }
 
-      template <typename I>
+      template <typename I, typename W>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::false_,
-			       const I& input, const win::diag2d& win)
+      erosion_dispatch_diagonal(metal::false_,
+				const I& input, const W& win)
       {
 	return erosion_dispatch_for_generic(input, win);
       }
 
-      template <typename I>
+      template <typename I, typename W>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(const I& input, const win::diag2d& win)
+      erosion_dispatch_diagonal(const I& input, const W& win)
       {
 	if (win.size() == 1)
 	  return clone(input);
@@ -911,51 +542,24 @@
 		   && mlc_is_a(mln_pset(I), Box)::value
 		   && mlc_equal(mln_trait_image_quant(I),
 				mln::trait::image::quant::low)::value };
-	    return erosion_dispatch_wrt_win(metal::bool_<test>(),
+	    return erosion_dispatch_diagonal(metal::bool_<test>(),
 					    input, win);
 	  }
       }
 
-      /// \}
-
-
-      /// Handling win::backdiag2d.
-      /// \{
 
       template <typename I>
       mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::true_,
-			       const I& input, const win::backdiag2d& win)
-      {
-	return erosion_dispatch_for_backdiagonal2d(input, win);
-      }
-
-      template <typename I>
-      mln_concrete(I)
-      erosion_dispatch_wrt_win(metal::false_,
-			       const I& input, const win::backdiag2d& win)
+      erosion_dispatch_wrt_win(const I& input, const win::diag2d& win)
       {
-	return erosion_dispatch_for_generic(input, win);
+	return erosion_dispatch_diagonal(input, win);
       }
 
       template <typename I>
       mln_concrete(I)
       erosion_dispatch_wrt_win(const I& input, const win::backdiag2d& win)
       {
-	if (win.size() == 1)
-	  return clone(input);
-	else if (win.size() == 3)
-	  return erosion_dispatch_for_generic(input, win);
-	else
-	  {
-	    enum { test = mlc_is_not(mln_trait_image_kind(I),
-				     mln::trait::image::kind::logic)::value
-		   && mlc_is_a(mln_pset(I), Box)::value
-		   && mlc_equal(mln_trait_image_quant(I),
-				mln::trait::image::quant::low)::value };
-	    return erosion_dispatch_wrt_win(metal::bool_<test>(),
-					    input, win);
-	  }
+	return erosion_dispatch_diagonal(input, win);
       }
 
       /// \}
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh	(revision 2881)
+++ mln/morpho/includes.hh	(working copy)
@@ -55,6 +55,7 @@
 # include <mln/accu/transform.hh>
 # include <mln/accu/transform_stop.hh>
 # include <mln/accu/transform_directional.hh>
+# include <mln/accu/transform_diagonal.hh>
 
 # include <mln/fun/v2v/saturate.hh>
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* mln/core/internal/graph_neighborhood_base.hh,
	* mln/core/image/graph_elt_neighborhood.hh,
	* mln/core/image/line_graph_elt_neighborhood.hh,
	* mln/core/internal/graph_window_base.hh,
	* mln/core/image/graph_elt_window.hh,
	* mln/core/image/line_graph_elt_window.hh: refactor.
	* mln/make/voronoi.hh,
	* mln/core/internal/line_graph_vicinity_piter.hh,
	* mln/core/image/line_graph_window_piter.hh,
	* mln/core/image/line_graph_neighborhood_piter.hh: update according
	the new graph structure.
	* mln/core/site_set/p_graph.hh,
	* mln/core/site_set/p_line_graph.hh,
	* mln/core/site_set/p_line_graph_piter.hh,
	* mln/core/image/line_graph_psite.hh: deprecated and deleted.
	* tests/core/site_set/p_vertices.cc,
	* mln/util/graph.hh,
	* mln/util/internal/graph_vertex_impl.hh,
	* mln/util/internal/graph_edge_impl.hh: fix comments.
	* mln/util/internal/graph_edge_psite.hh: fix initialization.
	* tests/core/site_set/p_edges.cc,
	* tests/core/image/graph_image.cc,
	* tests/core/image/line_graph_image.cc: fix tests.
        * mln/make/all.hh
	* mln/make/essential.hh: uncomment inclusion of voronoi.hh.
---
 milena/ChangeLog                                   |   36 ++
 milena/mln/core/image/graph_elt_neighborhood.hh    |   46 +--
 milena/mln/core/image/graph_elt_window.hh          |   96 +-----
 .../mln/core/image/line_graph_elt_neighborhood.hh  |  107 ++----
 milena/mln/core/image/line_graph_elt_window.hh     |  165 +++------
 .../core/image/line_graph_neighborhood_piter.hh    |   94 +++---
 milena/mln/core/image/line_graph_psite.hh          |  399 --------------------
 milena/mln/core/image/line_graph_window_piter.hh   |   96 +++---
 .../internal/graph_neighborhood_base.hh}           |   89 +++---
 milena/mln/core/internal/graph_window_base.hh      |  146 +++++++
 .../mln/core/internal/line_graph_vicinity_piter.hh |    9 +-
 milena/mln/core/site_set/p_graph.hh                |  396 -------------------
 milena/mln/core/site_set/p_line_graph.hh           |  360 ------------------
 milena/mln/core/site_set/p_line_graph_piter.hh     |  272 -------------
 milena/mln/make/all.hh                             |    2 +-
 milena/mln/make/essential.hh                       |    4 +-
 milena/mln/make/voronoi.hh                         |   27 +-
 milena/mln/util/graph.hh                           |    2 +-
 milena/mln/util/internal/graph_edge_impl.hh        |   11 +-
 milena/mln/util/internal/graph_edge_psite.hh       |    3 +-
 milena/mln/util/internal/graph_vertex_impl.hh      |   11 +-
 milena/tests/core/image/graph_image.cc             |   42 ++-
 milena/tests/core/image/line_graph_image.cc        |  159 ++++++---
 milena/tests/core/site_set/p_edges.cc              |   12 +-
 milena/tests/core/site_set/p_vertices.cc           |    9 +-
 25 files changed, 593 insertions(+), 2000 deletions(-)
 delete mode 100644 milena/mln/core/image/line_graph_psite.hh
 copy milena/mln/{util/internal/graph_vertex_impl.hh => core/internal/graph_neighborhood_base.hh} (50%)
 create mode 100644 milena/mln/core/internal/graph_window_base.hh
 delete mode 100644 milena/mln/core/site_set/p_graph.hh
 delete mode 100644 milena/mln/core/site_set/p_line_graph.hh
 delete mode 100644 milena/mln/core/site_set/p_line_graph_piter.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 560b8ab..20e278b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,39 @@
+2008-11-14  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Update graph related classes.
+
+	* mln/core/internal/graph_neighborhood_base.hh,
+	* mln/core/image/graph_elt_neighborhood.hh,
+	* mln/core/image/line_graph_elt_neighborhood.hh,
+	* mln/core/internal/graph_window_base.hh,
+	* mln/core/image/graph_elt_window.hh,
+	* mln/core/image/line_graph_elt_window.hh: refactor.
+
+	* mln/make/voronoi.hh,
+	* mln/core/internal/line_graph_vicinity_piter.hh,
+	* mln/core/image/line_graph_window_piter.hh,
+	* mln/core/image/line_graph_neighborhood_piter.hh: update according
+	the new graph structure.
+
+	* mln/core/site_set/p_graph.hh,
+	* mln/core/site_set/p_line_graph.hh,
+	* mln/core/site_set/p_line_graph_piter.hh,
+	* mln/core/image/line_graph_psite.hh: deprecated and deleted.
+
+	* tests/core/site_set/p_vertices.cc,
+	* mln/util/graph.hh
+	* mln/util/internal/graph_vertex_impl.hh,
+	* mln/util/internal/graph_edge_impl.hh: fix comments.
+
+	* mln/util/internal/graph_edge_psite.hh: fix initialization.
+
+	* tests/core/site_set/p_edges.cc,
+	* tests/core/image/graph_image.cc,
+	* tests/core/image/line_graph_image.cc: fix tests.
+
+        * mln/make/all.hh
+	* mln/make/essential.hh: uncomment inclusion of voronoi.hh.
+
 2008-11-14  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
 
 	Migrate generic code from morpho erosion to new files in accu.
diff --git a/milena/mln/core/image/graph_elt_neighborhood.hh b/milena/mln/core/image/graph_elt_neighborhood.hh
index ac48f6d..5b568c0 100644
--- a/milena/mln/core/image/graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/graph_elt_neighborhood.hh
@@ -30,19 +30,12 @@
 # define MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_HH
 
 /// \file mln/core/image/graph_elt_neighborhood.hh
-/// \brief Definition of the elementary ``neighborhood'' on a graph.
-
-/* FIXME: Factor those classes:
-   - mln::graph_elt_window
-   - mln::graph_elt_neighborhood
-   - mln::line_graph_elt_window
-   - mln::line_graph_elt_neighborhood.
-
-   See https://trac.lrde.org/olena/ticket/139.  */
+/// Definition of the elementary ``neighborhood'' on a graph.
 
 # include <set>
 
 # include <mln/core/concept/neighborhood.hh>
+# include <mln/core/internal/graph_neighborhood_base.hh>
 # include <mln/util/internal/graph_vertex_psite.hh>
 # include <mln/core/image/graph_neighborhood_piter.hh>
 
@@ -56,10 +49,13 @@ namespace mln
   template <typename G, typename F, typename N> class graph_neighborhood_bkd_piter;
 
 
-  /// \brief Elementary neighborhood on graph class.
+  /// Elementary neighborhood on graph class.
   template <typename G, typename F>
   class graph_elt_neighborhood
-    : public Neighborhood< graph_elt_neighborhood<G, F> >
+    : public graph_neighborhood_base<G,
+				     F,
+				     internal::vertex_psite<G, F>,
+				     graph_elt_neighborhood<G, F> >
   {
     typedef graph_elt_neighborhood<G, F> self_;
 
@@ -68,17 +64,12 @@ namespace mln
     /// \{
     /// The type of psite corresponding to the neighborhood.
     typedef internal::vertex_psite<G, F> psite;
-    /// The type of site corresponding to the neighborhood.
-    typedef mln_site(psite) site;
-    // The type of the set of neighbors (vertex ids adjacent to the
-    // reference psite).
-    typedef std::set<unsigned> sites_t;
 
-    /// \brief Site_Iterator type to browse the psites of the
+    /// Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the ordering of vertices.
     typedef graph_neighborhood_fwd_piter<G, F, self_> fwd_niter;
 
-    /// \brief Site_Iterator type to browse the psites of the
+    /// Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the reverse ordering of vertices.
     typedef graph_neighborhood_bkd_piter<G, F, self_> bkd_niter;
 
@@ -86,13 +77,6 @@ namespace mln
     typedef fwd_niter niter;
     /// \}
 
-    /// Conversions.
-    /// \{
-    /// The window type corresponding to this neighborhood.
-    typedef graph_elt_window<G, F> window;
-    /// Create a window corresponding to this neighborhood.
-    window win() const;
-    /// \}
 
     /// Services for iterators.
     /// \{
@@ -100,20 +84,16 @@ namespace mln
     template <typename Piter>
     void compute_sites_(Site_Iterator<Piter>& piter) const;
     /// \}
+
+  protected:
+    typedef graph_neighborhood_base<G, F, psite, self_> super_;
+    typedef typename super_::sites_t sites_t;
   };
 
 
 # ifndef MLN_INCLUDE_ONLY
 
   template <typename G, typename F>
-  inline
-  graph_elt_window<G, F>
-  graph_elt_neighborhood<G, F>::win() const
-  {
-    return graph_elt_window<G, F>();
-  }
-
-  template <typename G, typename F>
   template <typename Piter>
   inline
   void
diff --git a/milena/mln/core/image/graph_elt_window.hh b/milena/mln/core/image/graph_elt_window.hh
index e09b257..f71c499 100644
--- a/milena/mln/core/image/graph_elt_window.hh
+++ b/milena/mln/core/image/graph_elt_window.hh
@@ -30,17 +30,10 @@
 # define MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_HH
 
 /// \file mln/core/image/graph_elt_window.hh
-/// \brief Definition of the elementary ``window'' on a graph.
-
-/* FIXME: Factor those classes:
-   - mln::graph_elt_window
-   - mln::graph_elt_neighborhood
-   - mln::line_graph_elt_window
-   - mln::line_graph_elt_neighborhood.
-
-   See https://trac.lrde.org/olena/ticket/139.  */
+/// Definition of the elementary ``window'' on a graph.
 
 # include <mln/core/concept/window.hh>
+# include <mln/core/internal/graph_window_base.hh>
 # include <mln/util/internal/graph_vertex_psite.hh>
 # include <mln/core/image/graph_window_piter.hh>
 
@@ -68,24 +61,20 @@ namespace mln
 
   /// \brief Elementary window on graph class.
   template <typename G, typename F>
-  class graph_elt_window : public Window< graph_elt_window<G, F> >
+  class graph_elt_window : public graph_window_base<
+				    G,
+				    F,
+				    internal::vertex_psite<G, F>,
+				    graph_elt_window<G, F> >
+
   {
     typedef graph_elt_window<G, F> self_;
-    typedef mln_result(F) P;
 
   public:
     /// Associated types.
     /// \{
     /// The type of psite corresponding to the window.
     typedef internal::vertex_psite<G, F> psite;
-    /// The type of site corresponding to the window.
-    typedef mln_site(psite) site;
-    // The type of the set of window sites (vertex ids adjacent to the
-    // reference psite).
-    typedef std::set<unsigned> sites_t;
-
-    // FIXME: This is a dummy value.
-    typedef void dpsite;
 
     /// \brief Site_Iterator type to browse the psites of the window
     /// w.r.t. the ordering of vertices.
@@ -106,31 +95,9 @@ namespace mln
     void compute_sites_(Site_Iterator<Piter>& piter) const;
     /// \}
 
-    /// Interface of the concept Window.
-    /// \{
-    /// Is the window is empty?
-    bool is_empty() const;
-    /// Is the window centered?
-    bool is_centered() const;
-    /// Is the window symmetric?
-    // FIXME: We should define this more precisely.
-    bool is_symmetric() const;
-    /// Return the maximum coordinate gap between the window center
-    /// and a window point.
-    /* FIXME: This method returns a dummy value (0), since the delta
-       of a window on a graph
-
-       1. is not constant (graph vertices are not necessarily aligned on
-          a regular grid);
-
-       2. depends on the underlying graph, too.
-
-       It raises another question: should delta() be part of the
-       concept ``Window''?  */
-    unsigned delta() const;
-    /// Apply a central symmetry to the target window.
-    self_& sym();
-    /// \}
+  protected:
+    typedef graph_window_base<G, F, psite, self_> super_;
+    typedef typename super_::sites_t sites_t;
   };
 
 
@@ -154,47 +121,6 @@ namespace mln
       sites.insert(g.v_ith_nbh_vertex(central_vertex, i));
   }
 
-  template <typename G, typename F>
-  inline
-  bool
-  graph_elt_window<G, F>::is_empty() const
-  {
-    return false;
-  }
-
-  template <typename G, typename F>
-  inline
-  bool
-  graph_elt_window<G, F>::is_centered() const
-  {
-    return false;
-  }
-
-  template <typename G, typename F>
-  inline
-  bool
-  graph_elt_window<G, F>::is_symmetric() const
-  {
-    return true;
-  }
-
-  template <typename G, typename F>
-  inline
-  unsigned
-  graph_elt_window<G, F>::delta() const
-  {
-    // Dummy value (see the interface of the method above).
-    return 0;
-  }
-
-  template <typename G, typename F>
-  inline
-  graph_elt_window<G, F>&
-  graph_elt_window<G, F>::sym()
-  {
-    return *this;
-  }
-
 # endif // ! MLN_INCLUDE_ONLY
 
 } // end of namespace mln
diff --git a/milena/mln/core/image/line_graph_elt_neighborhood.hh b/milena/mln/core/image/line_graph_elt_neighborhood.hh
index 1f79084..55236f3 100644
--- a/milena/mln/core/image/line_graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/line_graph_elt_neighborhood.hh
@@ -30,27 +30,13 @@
 # define MLN_CORE_IMAGE_LINE_GRAPH_ELT_NEIGHBORHOOD_HH
 
 /// \file mln/core/image/line_graph_elt_neighborhood.hh
-/// \brief Definition of the elementary ``neighborhood'' on a line graph.
-
-/* FIXME: Have a consistent naming: we have window (without '_') but
-   point_, neighb_, etc.  */
-
-/* FIXME: Factor those classes:
-   - mln::graph_elt_window
-   - mln::graph_elt_neighborhood
-   - mln::line_graph_elt_window
-   - mln::line_graph_elt_neighborhood.
-
-   See https://trac.lrde.org/olena/ticket/139.  */
-
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
+/// Definition of the elementary ``neighborhood'' on a line graph.
 
 # include <set>
 
 # include <mln/core/concept/neighborhood.hh>
-# include <mln/core/image/line_graph_psite.hh>
+# include <mln/core/internal/graph_neighborhood_base.hh>
+# include <mln/util/internal/graph_edge_psite.hh>
 # include <mln/core/image/line_graph_neighborhood_piter.hh>
 
 # include <mln/core/image/line_graph_elt_window.hh>
@@ -58,99 +44,70 @@
 
 namespace mln
 {
-  // Fwd decls.
-  template <typename P, typename N> class line_graph_neighborhood_fwd_piter;
-  template <typename P, typename N> class line_graph_neighborhood_bkd_piter;
 
-
-  /// \brief Elementary neighborhood on line graph class.
-  template <typename P>
+  /// Elementary neighborhood on line graph class.
+  template <typename G, typename F>
   class line_graph_elt_neighborhood
-    : public Neighborhood< line_graph_elt_neighborhood<P> >
+    : public graph_neighborhood_base<G,
+				     F,
+				     internal::edge_psite<G, F>,
+				     line_graph_elt_neighborhood<G, F> >
   {
-    typedef line_graph_elt_neighborhood<P> self_;
+    typedef line_graph_elt_neighborhood<G, F> self_;
 
   public:
     /// Associated types.
     /// \{
     /// The type of psite corresponding to the neighborhood.
-    typedef line_graph_psite<P> psite;
-    /// The type of site corresponding to the neighborhood.
-    typedef mln_site(psite) site;
-    // The type of the set of neighbors (edge ids adjacent to the
-    // reference psite).
-    typedef std::set<util::edge_id> sites_t;
-
-    /// \brief Site_Iterator type to browse the psites of the
+    typedef internal::edge_psite<G, F> psite;
+
+    /// Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the ordering of edges.
-    typedef line_graph_neighborhood_fwd_piter<P, self_> fwd_niter;
+    typedef line_graph_neighborhood_fwd_piter<G, F, self_> fwd_niter;
 
-    /// \brief Site_Iterator type to browse the psites of the
+    /// Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the reverse ordering of edges.
-    typedef line_graph_neighborhood_bkd_piter<P, self_> bkd_niter;
+    typedef line_graph_neighborhood_bkd_piter<G, F, self_> bkd_niter;
 
     /// The default niter type.
     typedef fwd_niter niter;
     /// \}
 
-    /// Conversions.
-    /// \{
-    /// The window type corresponding to this neighborhood.
-    typedef line_graph_elt_window<P> window;
-    /// Create a window corresponding to this neighborhood.
-    window to_window() const;
-    /// \}
-
     /// Services for iterators.
     /// \{
     /// Compute the set of sites for this neighborhood around \a piter.
     template <typename Piter>
     void compute_sites_(Site_Iterator<Piter>& piter) const;
     /// \}
+
+  protected:
+    typedef graph_neighborhood_base<G, F, psite, self_> super_;
+    typedef typename super_::sites_t sites_t;
   };
 
 
 
 # ifndef MLN_INCLUDE_ONLY
 
-  template <typename P>
-  inline
-  line_graph_elt_window<P>
-  line_graph_elt_neighborhood<P>::to_window() const
-  {
-    return line_graph_elt_window<P>();
-  }
-
-  template <typename P>
+  template <typename G, typename F>
   template <typename Piter>
   inline
   void
-  line_graph_elt_neighborhood<P>::compute_sites_(Site_Iterator<Piter>& piter_) const
+  line_graph_elt_neighborhood<G, F>::compute_sites_(Site_Iterator<Piter>& piter_) const
   {
     Piter& piter = exact(piter_);
-    util::edge_id ref_edge_id = piter.center().edge_id();
+    unsigned central_edge = piter.center().e().id();
     sites_t& sites = piter.sites();
     sites.clear();
-    /* FIXME: Move this computation out of the neighborhood. In fact,
-       this should be a service of the graph, also proposed by the
-       p_line_graph.  */
-    // Ajacent edges connected through vertex 1.
-    util::vertex_id id1 = piter.center().first_id();
-    const util::vertex<P>& vertex1 = piter.center().site_set().gr_->vertex(id1);
-    for (std::vector<util::edge_id>::const_iterator e =
-	   vertex1.edges.begin(); e != vertex1.edges.end(); ++e)
-      // We explicitly enforce that the reference piter edge id is
-      // *not* inserted into SITES.
-      if (*e != ref_edge_id)
-	sites.insert(*e);
-    // Ajacent edges connected through vertex 2.
-    util::vertex_id id2 = piter.center().second_id();
-    const util::vertex<P>& vertex2 = piter.center().site_set().gr_->vertex(id2);
-    for (std::vector<util::edge_id>::const_iterator e =
-	   vertex2.edges.begin(); e != vertex2.edges.end(); ++e)
-      // Same remark as above.
-      if (*e != ref_edge_id)
-	sites.insert(*e);
+
+    const G& g = piter.center().site_set().graph();
+
+    for (unsigned i = 0; i < g.e_nmax_nbh_edges(central_edge); ++i)
+    {
+      unsigned n = g.e_ith_nbh_edge(central_edge, i);
+      if (n != central_edge)
+	sites.insert(g.e_ith_nbh_edge(central_edge, i));
+    }
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/line_graph_elt_window.hh b/milena/mln/core/image/line_graph_elt_window.hh
index 920ba4e..c727230 100644
--- a/milena/mln/core/image/line_graph_elt_window.hh
+++ b/milena/mln/core/image/line_graph_elt_window.hh
@@ -30,66 +30,62 @@
 # define MLN_CORE_IMAGE_LINE_GRAPH_ELT_WINDOW_HH
 
 /// \file mln/core/image/line_graph_elt_window.hh
-/// \brief Definition of the elementary ``window'' on a line graph.
-
-/* FIXME: Have a consistent naming: we have window (without '_') but
-   point_, neighb_, etc.  */
-
-/* FIXME: Factor those classes:
-   - mln::graph_elt_window
-   - mln::graph_elt_neighborhood
-   - mln::line_graph_elt_window
-   - mln::line_graph_elt_neighborhood.
-
-   See https://trac.lrde.org/olena/ticket/139.  */
-
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
+/// Definition of the elementary ``window'' on a line graph.
 
 # include <mln/core/concept/window.hh>
-# include <mln/core/image/line_graph_psite.hh>
+# include <mln/core/internal/graph_window_base.hh>
+# include <mln/util/internal/graph_edge_psite.hh>
 # include <mln/core/image/line_graph_window_piter.hh>
 
 
 namespace mln
 {
-  // Fwd decls.
-  template <typename P, typename W> class line_graph_window_fwd_piter;
-  template <typename P, typename W> class line_graph_window_bkd_piter;
+
+  /// Forward declaration
+  template <typename G, typename F> class line_graph_elt_window;
+
+  namespace trait
+  {
+
+    ///FIXME: check that!
+    template <typename G, typename F>
+    struct window_< mln::line_graph_elt_window<G, F> >
+    {
+      typedef trait::window::size::unknown       size;
+      typedef trait::window::support::irregular  support;
+      typedef trait::window::definition::varying definition;
+    };
+
+  } // end of namespace mln::trait
 
 
   /// \brief Elementary window on line graph class.
-  template <typename P>
-  class line_graph_elt_window : public Window< line_graph_elt_window<P> >
+  template <typename G, typename F>
+  class line_graph_elt_window : public graph_window_base<
+					G,
+					F,
+					internal::edge_psite<G, F>,
+					line_graph_elt_window<G, F> >
   {
-    typedef line_graph_elt_window<P> self_;
+    typedef line_graph_elt_window<G, F> self_;
 
   public:
     /// Associated types.
     /// \{
     /// The type of psite corresponding to the window.
-    typedef line_graph_psite<P> psite;
-    /// The type of site corresponding to the window.
-    typedef mln_site(psite) site;
-    // The type of the set of window sites (edge ids adjacent to the
-    // reference psite).
-    typedef std::set<util::edge_id> sites_t;
-
-    // FIXME: This is a dummy value.
-    typedef void dpsite;
+    typedef internal::edge_psite<G, F> psite;
 
-    /// \brief Site_Iterator type to browse the psites of the window
+    /// Site_Iterator type to browse the psites of the window
     /// w.r.t. the ordering of edges.
-    typedef line_graph_window_fwd_piter<P, self_> fwd_qiter;
+    typedef line_graph_window_fwd_piter<G, F, self_> fwd_qiter;
 
-    /// \brief Site_Iterator type to browse the psites of the window
+    /// Site_Iterator type to browse the psites of the window
     /// w.r.t. the reverse ordering of edges.
-    typedef line_graph_window_bkd_piter<P, self_> bkd_qiter;
+    typedef line_graph_window_bkd_piter<G, F, self_> bkd_qiter;
 
     /// The default qiter type.
     typedef fwd_qiter qiter;
-    /// \}
+
 
     /// Services for iterators.
     /// \{
@@ -98,105 +94,30 @@ namespace mln
     void compute_sites_(Site_Iterator<Piter>& piter) const;
     /// \}
 
-    /// Interface of the concept Window.
-    /// \{
-    /// Is the window is empty?
-    bool is_empty() const;
-    /// Is the window centered?
-    bool is_centered() const;
-    /// Is the window symmetric?
-    // FIXME: We should define this more precisely.
-    bool is_symmetric() const;
-    /// Return the maximum coordinate gap between the window center
-    /// and a window point.
-    /* FIXME: This method returns a dummy value (0), since the delta
-       of a window on a line_graph
-
-       1. is not constant (line graph edges are not necessarily
-          aligned on a regular grid);
-
-       2. depends on the underlying line_graph, too.
-
-       It raises another question: should delta() be part of the
-       concept ``Window''?  */
-    unsigned delta() const;
-    /// Apply a central symmetry to the target window.
-    self_& sym();
-    /// \}
+  protected:
+    typedef graph_window_base<G, F, psite, self_> super_;
+    typedef typename super_::sites_t sites_t;
   };
 
 
 # ifndef MLN_INCLUDE_ONLY
 
-  template <typename P>
+  template <typename G, typename F>
   template <typename Piter>
   inline
   void
-  line_graph_elt_window<P>::compute_sites_(Site_Iterator<Piter>& piter_) const
+  line_graph_elt_window<G, F>::compute_sites_(Site_Iterator<Piter>& piter_) const
   {
     Piter& piter = exact(piter_);
+    unsigned central_edge = piter.center().e().id();
     sites_t& sites = piter.sites();
     sites.clear();
-    /* FIXME: Move this computation out of the window. In fact,
-       this should be a service of the graph, also proposed by the
-       p_line_graph.  */
-    // Ajacent edges connected through vertex 1.
-    /* We don't need to explicitely insert the reference piter (edge
-       id) itself into SITES, since it is part of the set of edges
-       adjacent to VERTEX1 and VERTEX2, and will therefore be
-       automatically added.  */
-    util::vertex_id id1 = piter.center().first_id();
-    const util::vertex<P>& vertex1 = piter.center().site_set().gr_->vertex(id1);
-    for (std::vector<util::edge_id>::const_iterator e =
-	   vertex1.edges.begin(); e != vertex1.edges.end(); ++e)
-      sites.insert(*e);
-    // Ajacent edges connected through vertex 2.
-    util::vertex_id id2 = piter.center().second_id();
-    const util::vertex<P>& vertex2 = piter.center().site_set().gr_->vertex(id2);
-    for (std::vector<util::edge_id>::const_iterator e =
-	   vertex2.edges.begin(); e != vertex2.edges.end(); ++e)
-      sites.insert(*e);
-  }
-
-  template <typename P>
-  inline
-  bool
-  line_graph_elt_window<P>::is_empty() const
-  {
-    return false;
-  }
-
-  template <typename P>
-  inline
-  bool
-  line_graph_elt_window<P>::is_centered() const
-  {
-    return false;
-  }
-
-  template <typename P>
-  inline
-  bool
-  line_graph_elt_window<P>::is_symmetric() const
-  {
-    return true;
-  }
 
-  template <typename P>
-  inline
-  unsigned
-  line_graph_elt_window<P>::delta() const
-  {
-    // Dummy value (see the interface of the method above).
-    return 0;
-  }
+    const G& g = piter.center().site_set().graph();
 
-  template <typename P>
-  inline
-  line_graph_elt_window<P>&
-  line_graph_elt_window<P>::sym()
-  {
-    return *this;
+    sites.insert(central_edge);
+    for (unsigned i = 0; i < g.e_nmax_nbh_edges(central_edge); ++i)
+      sites.insert(g.e_ith_nbh_edge(central_edge, i));
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/line_graph_neighborhood_piter.hh b/milena/mln/core/image/line_graph_neighborhood_piter.hh
index 9a30b74..83594c7 100644
--- a/milena/mln/core/image/line_graph_neighborhood_piter.hh
+++ b/milena/mln/core/image/line_graph_neighborhood_piter.hh
@@ -34,25 +34,21 @@
 
 # include <mln/core/internal/line_graph_vicinity_piter.hh>
 
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
-
 namespace mln
 {
 
   /*------------------------------------------.
-  | line_graph_neighborhood_fwd_piter<P, N>.  |
+  | line_graph_neighborhood_fwd_piter<G, F, N>.  |
   `------------------------------------------*/
 
   /// \brief Forward iterator on line graph neighborhood.
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   class line_graph_neighborhood_fwd_piter :
-    public internal::line_graph_vicinity_piter_< P, N,
-						 line_graph_neighborhood_fwd_piter<P, N> >
+    public internal::line_graph_vicinity_piter_< mln_result(F), N,
+						 line_graph_neighborhood_fwd_piter<G, F, N> >
   {
-    typedef line_graph_neighborhood_fwd_piter<P, N> self_;
-    typedef internal::line_graph_vicinity_piter_<P, N, self_> super_;
+    typedef line_graph_neighborhood_fwd_piter<G, F, N> self_;
+    typedef internal::line_graph_vicinity_piter_<mln_result(F), N, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -90,17 +86,17 @@ namespace mln
 
 
   /*------------------------------------------.
-  | line_graph_neighborhood_bkd_piter<P, N>.  |
+  | line_graph_neighborhood_bkd_piter<G, F, N>.  |
   `------------------------------------------*/
 
   /// \brief Backward iterator on line graph neighborhood.
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   class line_graph_neighborhood_bkd_piter :
-    public internal::line_graph_vicinity_piter_< P, N,
-						 line_graph_neighborhood_bkd_piter<P, N> >
+    public internal::line_graph_vicinity_piter_< mln_result(F), N,
+						 line_graph_neighborhood_bkd_piter<G, F, N> >
   {
-    typedef line_graph_neighborhood_bkd_piter<P, N> self_;
-    typedef internal::line_graph_vicinity_piter_<P, N, self_> super_;
+    typedef line_graph_neighborhood_bkd_piter<G, F, N> self_;
+    typedef internal::line_graph_vicinity_piter_<mln_result(F), N, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -141,126 +137,126 @@ namespace mln
 # ifndef MLN_INCLUDE_ONLY
 
   /*------------------------------------------.
-  | line_graph_neighborhood_fwd_piter<P, N>.  |
+  | line_graph_neighborhood_fwd_piter<G, F, N>.  |
   `------------------------------------------*/
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
-  line_graph_neighborhood_fwd_piter<P, N>::line_graph_neighborhood_fwd_piter()
+  line_graph_neighborhood_fwd_piter<G, F, N>::line_graph_neighborhood_fwd_piter()
   {
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   template <typename Pref>
   inline
-  line_graph_neighborhood_fwd_piter<P, N>::line_graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
-									     const Pref& p_ref)
+  line_graph_neighborhood_fwd_piter<G, F, N>::line_graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
+										const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(nbh));
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   bool
-  line_graph_neighborhood_fwd_piter<P, N>::is_valid_() const
+  line_graph_neighborhood_fwd_piter<G, F, N>::is_valid_() const
   {
     return i_ != this->sites_.end();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_fwd_piter<P, N>::invalidate_()
+  line_graph_neighborhood_fwd_piter<G, F, N>::invalidate_()
   {
     i_ = this->sites_.end();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_fwd_piter<P, N>::do_start_()
+  line_graph_neighborhood_fwd_piter<G, F, N>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.begin();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_fwd_piter<P, N>::do_next_()
+  line_graph_neighborhood_fwd_piter<G, F, N>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   mln_psite(N)
-  line_graph_neighborhood_fwd_piter<P, N>::compute_p_() const
+  line_graph_neighborhood_fwd_piter<G, F, N>::compute_p_() const
   {
-    return line_graph_psite<P>(this->center().site_set(), *i_);
+    return internal::edge_psite<G, F>(this->center().site_set(), *i_);
   }
 
 
   /*------------------------------------------.
-  | line_graph_neighborhood_bkd_piter<P, N>.  |
+  | line_graph_neighborhood_bkd_piter<G, F, N>.  |
   `------------------------------------------*/
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
-  line_graph_neighborhood_bkd_piter<P, N>::line_graph_neighborhood_bkd_piter()
+  line_graph_neighborhood_bkd_piter<G, F, N>::line_graph_neighborhood_bkd_piter()
   {
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   template <typename Pref>
   inline
-  line_graph_neighborhood_bkd_piter<P, N>::line_graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
+  line_graph_neighborhood_bkd_piter<G, F, N>::line_graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
 									     const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(nbh));
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   bool
-  line_graph_neighborhood_bkd_piter<P, N>::is_valid_() const
+  line_graph_neighborhood_bkd_piter<G, F, N>::is_valid_() const
   {
     return i_ != this->sites_.rend();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_bkd_piter<P, N>::invalidate_()
+  line_graph_neighborhood_bkd_piter<G, F, N>::invalidate_()
   {
     i_ = this->sites_.rend();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_bkd_piter<P, N>::do_start_()
+  line_graph_neighborhood_bkd_piter<G, F, N>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.rbegin();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  line_graph_neighborhood_bkd_piter<P, N>::do_next_()
+  line_graph_neighborhood_bkd_piter<G, F, N>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   mln_psite(N)
-  line_graph_neighborhood_bkd_piter<P, N>::compute_p_() const
+  line_graph_neighborhood_bkd_piter<G, F, N>::compute_p_() const
   {
-    return line_graph_psite<P>(this->center().site_set(), *i_);
+    return internal::edge_psite<G, F>(this->center().site_set(), *i_);
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/line_graph_psite.hh b/milena/mln/core/image/line_graph_psite.hh
deleted file mode 100644
index 0898f30..0000000
--- a/milena/mln/core/image/line_graph_psite.hh
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CORE_IMAGE_LINE_GRAPH_PSITE_HH
-# define MLN_CORE_IMAGE_LINE_GRAPH_PSITE_HH
-
-/// \file mln/core/image/line_graph_psite.hh
-/// \brief Definition of a line graph-based psite.
-
-# include <mln/core/internal/pseudo_site_base.hh>
-
-# include <mln/util/site_pair.hh>
-# include <mln/core/site_set/p_line_graph.hh>
-
-/* FIXME: This class shares a lot with graph_psite.  Factor as much as
-   possible.  */
-
-// FIXME: Rename line_graph_psite as p_line_graph_psite, and move this
-// to core/site_set.
-
-
-namespace mln
-{
-
-  // Forward declaration.
-  template <typename P> class p_line_graph;
-  template <typename P> class line_graph_psite;
-
-
-  /// \brief Point site associated to a mln::line_graph_image.
-  ///
-  /// \arg \p P The type of the site.
-  template <typename P>
-  class line_graph_psite
-    : public internal::pseudo_site_base_< const util::site_pair<P>&,
-					  line_graph_psite<P> >
-  {
-    typedef line_graph_psite<P> self_;
-
-  public:
-    // This associated type is important to know that this particular
-    // pseudo site knows the site set it refers to.
-    typedef p_line_graph<P> target;
-
-    /// Construction and assignment.
-    /// \{
-    line_graph_psite();
-    line_graph_psite(const p_line_graph<P>& plg, util::edge_id id);
-    /// \}
-
-    /// Psite manipulators.
-    /// \{
-    /// Is this psite valid?
-    bool is_valid() const;
-    /// Invalidate this psite.
-    void invalidate();
-    /// \}
-
-    /// Site set manipulators.
-    /// \{
-    /// \brief Get the site set (shortcut for *target()).
-    /// \pre Member plg_ is non null.
-    const target& site_set() const;
-
-    /// Get a pointer to the target site_set.
-    const target* target_() const;
-    /// Set the target site_set.
-    void change_target(const target& new_target);
-    /// \}
-
-    /// Proxy manipulators.
-    /// \{
-    /// Return the site corresponding to this psite.
-    const util::site_pair<P>& subj_();
-    /// \}
-
-    /// Edge id manipulators.
-    //// \{
-    /// Return the edge id of this point site.
-    util::edge_id edge_id() const;
-    /// Set the edge id of this point site.
-    void change_edge_id(const util::edge_id& id);
-    /// Increment the edge id of this point site.
-    void inc_edge_id();
-    /// Increment the edge id of this point site.
-    void dec_edge_id();
-    /// \}
-
-    /// Accessors.
-    /// \{
-    /// Return the first associated vertex.
-    P first() const;
-    /// Return the second associated vertex.
-    P second() const;
-
-    /// Return the id of the first associated vertex.
-    // FIXME: Rename as first_vertex_id.
-    util::vertex_id first_id() const;
-    /// Return the id of the second associated vertex.
-    // FIXME: Rename as second_vertex_id.
-    util::vertex_id second_id() const;
-    /// \}
-
-  private:
-    /// Site-related members.
-    /// \{
-    /// Update the site corresponding to this psite.
-    void update_();
-    // The site corresponding to this psite.
-    util::site_pair<P> p_;
-    /// \}
-
-  private:
-    /// Graph-related members.
-    /// \{
-    /// The p_line_graph this point site belongs to.
-    const target* plg_;
-    /// The id of the edge this psite is pointing towards.
-    util::edge_id id_;
-    /// \}
-  };
-
-
-  /// Comparison of two mln::line_graph_psite<P> instances.
-  /// \{
-  /* FIXME: Shouldn't those comparisons be part of a much general
-     mechanism?  */
-
-  /// \brief Is \a lhs equal to \a rhs?
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_line_graph.
-  template <typename P>
-  bool
-  operator==(const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs);
-
-  /// \brief Is \a lhs not equal to \a rhs?
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_line_graph.
-  template <typename P>
-  bool
-  operator!=(const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs);
-
-  /// \brief Is \a lhs ``less'' than \a rhs?
-  ///
-  /// This comparison is required by algorithms sorting psites.
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_line_graph.
-  template <typename P>
-  bool
-  operator< (const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs);
-  /// \}
-
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const line_graph_psite<P>& p);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-  template <typename P>
-  inline
-  line_graph_psite<P>::line_graph_psite()
-    : plg_(0)
-  {
-  }
-
-  template <typename P>
-  inline
-  line_graph_psite<P>::line_graph_psite(const p_line_graph<P>& plg,
-					util::edge_id id)
-    // FIXME: Use change_target instead.
-    : plg_(&plg),
-      id_(id)
-  {
-    update_();
-  }
-
-  template <typename P>
-  inline
-  bool
-  line_graph_psite<P>::is_valid() const
-  {
-    /* FIXME: Instead of `plg_->gr_->nedges()', we should have
-       something like `run_->has_edge_id(id_)' (see the implementation of
-       p_run_psite.  */
-    return plg_ && id_ < plg_->gr_->nedges();
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::invalidate()
-  {
-    /* FIXME: Instead of `plg_->gr_->nedges()', we should have
-       something like `run_->has_edge_id(id_)' (see the implementation of
-       p_run_psite.  */
-    id_ = plg_->gr_->nedges();
-  }
-
-  template <typename P>
-  inline
-  const p_line_graph<P>&
-  line_graph_psite<P>::site_set() const
-  {
-    mln_precondition(target_());
-    return *target_();
-  }
-
-  template <typename P>
-  inline
-  const p_line_graph<P>*
-  line_graph_psite<P>::target_() const
-  {
-    return plg_;
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::change_target(const target& new_target)
-  {
-    plg_ = &new_target;
-    invalidate();
-  }
-
-  // FIXME: Write or extend a test to exercise this method.
-  template <typename P>
-  inline
-  const util::site_pair<P>&
-  line_graph_psite<P>::subj_()
-  {
-    return p_;
-  }
-
-  template <typename P>
-  inline
-  util::edge_id
-  line_graph_psite<P>::edge_id() const
-  {
-    return id_;
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::change_edge_id(const util::edge_id& id)
-  {
-    id_ = id;
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::inc_edge_id()
-  {
-    ++id_.to_equiv();
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::dec_edge_id()
-  {
-    --id_.to_equiv();
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  P
-  line_graph_psite<P>::first() const
-  {
-    mln_precondition(is_valid());
-    // FIXME: Too low-level.
-    return plg_->gr_->vertex_data(first_id());
-  }
-
-  template <typename P>
-  inline
-  P
-  line_graph_psite<P>::second() const
-  {
-    mln_precondition(is_valid());
-    // FIXME: Too low-level.
-    return plg_->gr_->vertex_data(second_id());
-  }
-
-  template <typename P>
-  inline
-  util::vertex_id
-  line_graph_psite<P>::first_id() const
-  {
-    mln_precondition(is_valid());
-    // FIXME: Too low-level.
-    return plg_->gr_->edge(id_).v1();
-  }
-
-  template <typename P>
-  inline
-  util::vertex_id
-  line_graph_psite<P>::second_id() const
-  {
-    mln_precondition(is_valid());
-    // FIXME: Too low-level.
-    return plg_->gr_->edge(id_).v2();
-  }
-
-  template <typename P>
-  inline
-  void
-  line_graph_psite<P>::update_()
-  {
-    mln_precondition(is_valid());
-    p_.pair_.change_both(first(), second());
-  }
-
-
-  /*--------------.
-  | Comparisons.  |
-  `--------------*/
-
-  template <typename P>
-  bool
-  operator==(const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs)
-  {
-    mln_precondition(lhs.target_() == rhs.target_());
-    return lhs.edge_id() == rhs.edge_id();
-  }
-
-  template <typename P>
-  bool
-  operator!=(const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs)
-  {
-    mln_precondition(lhs.target_() == rhs.target_());
-    return lhs.edge_id() != rhs.edge_id();
-  }
-
-  template <typename P>
-  bool
-  operator< (const line_graph_psite<P>& lhs, const line_graph_psite<P>& rhs)
-  {
-    mln_precondition(lhs.target_() == rhs.target_());
-    return lhs.edge_id() < rhs.edge_id();
-  }
-
-
-  /*------------------.
-  | Pretty-printing.  |
-  `------------------*/
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const line_graph_psite<P>& p)
-  {
-    return ostr << '(' << p.first() << " -- " << p.second() << ')';
-  }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-#endif // MLN_CORE_IMAGE_LINE_GRAPH_PSITE_HH
diff --git a/milena/mln/core/image/line_graph_window_piter.hh b/milena/mln/core/image/line_graph_window_piter.hh
index f1f7d09..3b9c00e 100644
--- a/milena/mln/core/image/line_graph_window_piter.hh
+++ b/milena/mln/core/image/line_graph_window_piter.hh
@@ -34,25 +34,21 @@
 
 # include <mln/core/internal/line_graph_vicinity_piter.hh>
 
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
-
 namespace mln
 {
 
   /*------------------------------------.
-  | line_graph_window_fwd_piter<P, W>.  |
+  | line_graph_window_fwd_piter<G, F, W>.  |
   `------------------------------------*/
 
   /// \brief Forward iterator on line graph window.
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   class line_graph_window_fwd_piter
-    : public internal::line_graph_vicinity_piter_<P, W,
-						  line_graph_window_fwd_piter<P, W> >
+    : public internal::line_graph_vicinity_piter_<mln_result(F), W,
+						  line_graph_window_fwd_piter<G, F, W> >
   {
-    typedef line_graph_window_fwd_piter<P, W> self_;
-    typedef internal::line_graph_vicinity_piter_<P, W, self_> super_;
+    typedef line_graph_window_fwd_piter<G, F, W> self_;
+    typedef internal::line_graph_vicinity_piter_<mln_result(F), W, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -85,21 +81,21 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent edges.
-    typename super_::sites_t::const_iterator i_; 
+    typename super_::sites_t::const_iterator i_;
   };
 
 
   /*------------------------------------.
-  | line_graph_window_bkd_piter<P, W>.  |
+  | line_graph_window_bkd_piter<G, F, W>.  |
   `------------------------------------*/
 
   /// \brief Backward iterator on line graph window.
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   class line_graph_window_bkd_piter
-    : public internal::line_graph_vicinity_piter_<P, W, line_graph_window_bkd_piter<P, W> >
+    : public internal::line_graph_vicinity_piter_<mln_result(F), W, line_graph_window_bkd_piter<G, F, W> >
   {
-    typedef line_graph_window_bkd_piter<P, W> self_;
-    typedef internal::line_graph_vicinity_piter_<P, W, self_> super_;
+    typedef line_graph_window_bkd_piter<G, F, W> self_;
+    typedef internal::line_graph_vicinity_piter_<mln_result(F), W, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -132,7 +128,7 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent edges.
-    typename super_::sites_t::const_reverse_iterator i_; 
+    typename super_::sites_t::const_reverse_iterator i_;
   };
 
 
@@ -140,126 +136,126 @@ namespace mln
 # ifndef MLN_INCLUDE_ONLY
 
   /*------------------------------------.
-  | line_graph_window_fwd_piter<P, W>.  |
+  | line_graph_window_fwd_piter<G, F, W>.  |
   `------------------------------------*/
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
-  line_graph_window_fwd_piter<P, W>::line_graph_window_fwd_piter()
+  line_graph_window_fwd_piter<G, F, W>::line_graph_window_fwd_piter()
   {
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   template <typename Pref>
   inline
-  line_graph_window_fwd_piter<P, W>::line_graph_window_fwd_piter(const Window<W>& win,
+  line_graph_window_fwd_piter<G, F, W>::line_graph_window_fwd_piter(const Window<W>& win,
 								 const Pref& p_ref)
      : super_(p_ref)
   {
     this->change_target(exact(win));
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   bool
-  line_graph_window_fwd_piter<P, W>::is_valid_() const
+  line_graph_window_fwd_piter<G, F, W>::is_valid_() const
   {
     return i_ != this->sites_.end();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_fwd_piter<P, W>::invalidate_()
+  line_graph_window_fwd_piter<G, F, W>::invalidate_()
   {
     i_ = this->sites_.end();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_fwd_piter<P, W>::do_start_()
+  line_graph_window_fwd_piter<G, F, W>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.begin();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_fwd_piter<P, W>::do_next_()
+  line_graph_window_fwd_piter<G, F, W>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   mln_psite(W)
-  line_graph_window_fwd_piter<P, W>::compute_p_() const
+  line_graph_window_fwd_piter<G, F, W>::compute_p_() const
   {
-    return line_graph_psite<P>(this->center().site_set(), *i_);
+    return internal::edge_psite<G, F>(this->center().site_set(), *i_);
   }
 
 
   /*------------------------------------.
-  | line_graph_window_bkd_piter<P, W>.  |
+  | line_graph_window_bkd_piter<G, F, W>.  |
   `------------------------------------*/
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
-  line_graph_window_bkd_piter<P, W>::line_graph_window_bkd_piter()
+  line_graph_window_bkd_piter<G, F, W>::line_graph_window_bkd_piter()
   {
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   template <typename Pref>
   inline
-  line_graph_window_bkd_piter<P, W>::line_graph_window_bkd_piter(const Window<W>& win,
-								 const Pref& p_ref)
+  line_graph_window_bkd_piter<G, F, W>::line_graph_window_bkd_piter(const Window<W>& win,
+								    const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(win));
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   bool
-  line_graph_window_bkd_piter<P, W>::is_valid_() const
+  line_graph_window_bkd_piter<G, F, W>::is_valid_() const
   {
     return i_ != this->sites_.rend();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_bkd_piter<P, W>::invalidate_()
+  line_graph_window_bkd_piter<G, F, W>::invalidate_()
   {
     i_ = this->sites_.rend();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_bkd_piter<P, W>::do_start_()
+  line_graph_window_bkd_piter<G, F, W>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.rbegin();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  line_graph_window_bkd_piter<P, W>::do_next_()
+  line_graph_window_bkd_piter<G, F, W>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   mln_psite(W)
-  line_graph_window_bkd_piter<P, W>::compute_p_() const
+  line_graph_window_bkd_piter<G, F, W>::compute_p_() const
   {
-    return line_graph_psite<P>(this->center().site_set(), *i_);
+    return internal::edge_psite<G, F>(this->center().site_set(), *i_);
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/util/internal/graph_vertex_impl.hh b/milena/mln/core/internal/graph_neighborhood_base.hh
similarity index 50%
copy from milena/mln/util/internal/graph_vertex_impl.hh
copy to milena/mln/core/internal/graph_neighborhood_base.hh
index 3abfaf5..0e39cce 100644
--- a/milena/mln/util/internal/graph_vertex_impl.hh
+++ b/milena/mln/core/internal/graph_neighborhood_base.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,65 +25,68 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_CORE_INTERNAL_GRAPH_VERTEX_IMPL_HH
-# define MLN_CORE_INTERNAL_GRAPH_VERTEX_IMPL_HH
-
-/*! \file mln/util/internal/graph_vertex_impl.hh
- *
- * \brief Define a couple of implementation classes to provide methods
- * to classes of generalized vertexs.
- */
-
-# include <mln/core/internal/force_exact.hh>
+#ifndef MLN_CORE_INTERNAL_GRAPH_NEIGHBORHOOD_BASE_HH
+# define MLN_CORE_INTERNAL_GRAPH_NEIGHBORHOOD_BASE_HH
 
+/// \file mln/internal/graph_neighborhood_base.hh
+///
+/// FIXME: doc
 
 namespace mln
 {
 
-  namespace util
+  template <typename G, typename F, typename P, typename E>
+  class graph_neighborhood_base : public Neighborhood< E >
   {
-
-    namespace internal
-    {
-
-      /// Implementation class to equip generalized vertex classes.
-      template <typename G>
-      class vertex_impl_
-      {
-	protected:
-	  vertex_impl_();
-      };
-
-    } // end of namespace internal
-
-  } // end of namespace util
+    typedef graph_neighborhood_base<G, F, P, E> self_;
+
+  public:
+    /// Associated types.
+    /// \{
+    /// The type of site corresponding to the neighborhood.
+    typedef mln_site(P) site;
+
+    // The type of the set of neighborhood sites (ids adjacent to the
+    // reference psite).
+    typedef std::set<unsigned> sites_t;
+    /// \}
+
+    /// Conversions.
+    /// \{
+    /// The window type corresponding to this neighborhood.
+    typedef E window;
+    /// Create a window corresponding to this neighborhood.
+    E win() const;
+    /// \}
+
+  protected:
+    graph_neighborhood_base();
+  };
 
 } // end of namespace mln
 
-#ifndef MLN_INCLUDE_ONLY
+# ifndef MLN_INCLUDE_ONLY
 
 namespace mln
 {
 
-  namespace util
+  template <typename G, typename F, typename P, typename E>
+  inline
+  graph_neighborhood_base<G, F, P, E>::graph_neighborhood_base()
   {
+  }
 
-    namespace internal
-    {
-
-    template <typename G>
-    inline
-    vertex_impl_<G>::vertex_impl_()
-    {
-    }
-
-    } // end of namespace internal
-
-  } // end of namespace util
+  template <typename G, typename F, typename P, typename E>
+  inline
+  E
+  graph_neighborhood_base<G, F, P, E>::win() const
+  {
+    return E();
+  }
 
 } // end of namespace mln
 
-#endif // ! MLN_INCLUDE_ONLY
+# endif // !MLN_INCLUDE_ONLY
 
+#endif // !MLN_CORE_INTERNAL_GRAPH_NEIGHBORHOOD_BASE_HH
 
-#endif // ! MLN_CORE_INTERNAL_GRAPH_VERTEX_IMPL_HH
diff --git a/milena/mln/core/internal/graph_window_base.hh b/milena/mln/core/internal/graph_window_base.hh
new file mode 100644
index 0000000..ff4bfc0
--- /dev/null
+++ b/milena/mln/core/internal/graph_window_base.hh
@@ -0,0 +1,146 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_INTERNAL_GRAPH_WINDOW_BASE_HH
+# define MLN_CORE_INTERNAL_GRAPH_WINDOW_BASE_HH
+
+/// \file mln/internal/graph_window_base.hh
+///
+/// FIXME: doc
+
+namespace mln
+{
+
+  template <typename G, typename F, typename P, typename E>
+  class graph_window_base : public Window< E >
+  {
+    typedef graph_window_base<G, F, P, E> self_;
+
+  public:
+    /// Associated types.
+    /// \{
+    /// The type of site corresponding to the window.
+    typedef mln_site(P) site;
+
+    // The type of the set of window sites (ids adjacent to the
+    // reference psite).
+    typedef std::set<unsigned> sites_t;
+
+    // FIXME: This is a dummy value.
+    typedef void dpsite;
+    /// \}
+
+    /// Interface of the concept Window.
+    /// \{
+    /// Is the window is empty?
+    bool is_empty() const;
+    /// Is the window centered?
+    bool is_centered() const;
+    /// Is the window symmetric?
+    // FIXME: We should define this more precisely.
+    bool is_symmetric() const;
+    /// Return the maximum coordinate gap between the window center
+    /// and a window point.
+    /* FIXME: This method returns a dummy value (0), since the delta
+       of a window on a graph/line_graph
+
+       1. is not constant (line graph edges/graph vertices are not necessarily
+          aligned on a regular grid);
+
+       2. depends on the underlying line_graph/graph, too.
+
+       It raises another question: should delta() be part of the
+       concept ``Window''?  */
+    unsigned delta() const;
+    /// Apply a central symmetry to the target window.
+    self_& sym();
+    /// \}
+
+  protected:
+    graph_window_base();
+  };
+
+} // end of namespace mln
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  graph_window_base<G, F, P, E>::graph_window_base()
+  {
+  }
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  bool
+  graph_window_base<G, F, P, E>::is_empty() const
+  {
+    return false;
+  }
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  bool
+  graph_window_base<G, F, P, E>::is_centered() const
+  {
+    return false;
+  }
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  bool
+  graph_window_base<G, F, P, E>::is_symmetric() const
+  {
+    return true;
+  }
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  unsigned
+  graph_window_base<G, F, P, E>::delta() const
+  {
+    // Dummy value (see the interface of the method above).
+    return 0;
+  }
+
+  template <typename G, typename F, typename P, typename E>
+  inline
+  graph_window_base<G, F, P, E>&
+  graph_window_base<G, F, P, E>::sym()
+  {
+    return *this;
+  }
+
+} // end of namespace mln
+
+# endif // !MLN_INCLUDE_ONLY
+
+#endif // !MLN_CORE_INTERNAL_GRAPH_WINDOW_BASE_HH
+
diff --git a/milena/mln/core/internal/line_graph_vicinity_piter.hh b/milena/mln/core/internal/line_graph_vicinity_piter.hh
index 395b014..9ef41e6 100644
--- a/milena/mln/core/internal/line_graph_vicinity_piter.hh
+++ b/milena/mln/core/internal/line_graph_vicinity_piter.hh
@@ -36,8 +36,6 @@
 # include <set>
 
 # include <mln/core/internal/site_relative_iterator_base.hh>
-# include <mln/core/site_set/p_line_graph.hh>
-# include <mln/core/image/line_graph_psite.hh>
 
 /* FIXME: Factor those classes:
 
@@ -47,9 +45,6 @@
 
 namespace mln
 {
-  // Fwd decls.
-  template <typename P> class p_line_graph;
-  template <typename P> class line_graph_psite;
 
   // FIXME: Consider renaming line_graph_vicinity_piter_ as
   // line_graph_relative_piter_.
@@ -72,7 +67,7 @@ namespace mln
       typedef void mesh;
 
       // The type of the set of vicinity sites (adjacent edge ids).
-      typedef std::set<util::edge_id> sites_t;
+      typedef std::set<unsigned> sites_t;
 
     public:
       /// Return the set of sites (adjacent edge ids).
@@ -119,7 +114,7 @@ namespace mln
 
     template <typename P, typename S, typename E>
     inline
-    std::set<util::edge_id>&
+    std::set<unsigned>&
     line_graph_vicinity_piter_<P, S, E>::sites()
     {
       return sites_;
diff --git a/milena/mln/core/site_set/p_graph.hh b/milena/mln/core/site_set/p_graph.hh
deleted file mode 100644
index c0711c6..0000000
--- a/milena/mln/core/site_set/p_graph.hh
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CORE_SITE_SET_P_GRAPH_HH
-# define MLN_CORE_SITE_SET_P_GRAPH_HH
-
-/// \file mln/core/site_set/p_graph.hh
-/// \brief Definition of a point set based on a graph.
-
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/util/graph.hh>
-# include <mln/util/tracked_ptr.hh>
-
-# include <mln/core/site_set/p_graph_piter.hh>
-
-/* FIXME: This class shares a lot with p_line_graph.  Factor as much
-   as possible.  */
-
-/* FIXME: We should move the `adjacent'/`adjacent_or_equal' methods
-   out of this class (into iterators on *graph*).  */
-
-
-namespace mln
-{
-  // Forward declaration.
-  template <typename P> struct p_graph;
-
-  namespace trait
-  {
-    template <typename P>
-    struct site_set_< p_graph<P> >
-    {
-      typedef trait::site_set::nsites::known   nsites;
-      // FIXME: Depends on P!
-      typedef trait::site_set::bbox::unknown   bbox;
-      typedef trait::site_set::contents::fixed contents;
-      typedef trait::site_set::arity::unique   arity;
-    };
-  } // end of namespace mln::trait
-
-
-  template <typename P>
-  struct p_graph
-    : public internal::site_set_base_< P, p_graph<P> >
-  {
-    typedef p_graph<P> self_;
-    typedef internal::site_set_base_< P, self_ > super_;
-
-    typedef util::graph graph;
-
-    /// \brief Construct a graph psite set from a graph of points.
-    ///
-    /// \param gr The graph upon which the graph psite set is built.
-    ///
-    /// \a gr is \em copied internally, so that the graph psite set is
-    /// still valid after the initial graph has been removed.
-    p_graph(const graph& gr);
-
-    /// Associated types.
-    /// \{
-    /// Element associated type.
-    typedef mln_site(super_) element;
-    /// Point_Site associated type.
-    typedef graph_psite<P> psite;
-
-    /// Forward Site_Iterator associated type.
-    typedef p_graph_fwd_piter_<P> fwd_piter;
-
-    /// Backward Site_Iterator associated type.
-    typedef p_graph_bkd_piter_<P> bkd_piter;
-
-    /// Site_Iterator associated type.
-    typedef fwd_piter piter;
-    /// \}
-
-    /// \brief Return The number of points (sites) of the set, i.e.,
-    /// the number of \em vertices.
-    ///
-    /// Required by the mln::Point_Set concept.
-    unsigned nsites() const;
-
-    /// Return The number of vertices in the graph.
-    unsigned nvertices() const;
-    /// Return The number of edges in the graph.
-    unsigned nedges() const;
-
-    /// Is this site set valid?
-    bool is_valid() const;
-
-    /// Does this site set has \a p?
-    bool has(const psite& p) const;
-
-    // FIXME: Dummy.
-    std::size_t memory_size() const;
-
-    /// Accessors.
-    /// \{
-    /// Return the graph associated to this site set (const version)
-    const graph& gr() const;
-    /// Return the graph associated to this site set (mutable version).
-    graph& gr();
-    /// \}
-
-    /// \brief Graph-related services
-    ///
-    /// \todo Move them into iterators on graphs.
-    /// \{
-    /// Return the graph point (FIXME site?) from an index
-    const P& point_from_id(const util::vertex_id& id) const;
-    P& point_from_id(const util::vertex_id& id);
-
-    /// Return the point contained in the first vertex adjacent
-    // to the edge id \a e.
-    const P& vertex1(const util::edge_id& e) const;
-    /// Return the point contained in the second vertex adjacent
-    /// to the edge  id \a e.
-    const P& vertex2(const util::edge_id& e) const;
-
-    // FIXME: These would probably be no longer needed as soon as
-    // iterators on graphs are available.
-
-    /// Adjacency tests.
-    /// \{
-    /// Return true if the psites \a lhs and \a rhs are adjacent.
-    /// (If \a lhs and \a rhs are equal, return false).
-    bool adjacent(const psite& lhs, const psite& rhs) const;
-    /// Return true if the vertices \a lhs and \a rhs are adjacent.
-    /// (If \a lhs and \a rhs are equal, return false).
-    bool adjacent(const util::vertex_id& lhs, const util::vertex_id& rhs) const;
-
-    /// Return true if the psites \a lhs and \a rhs are adjacent, or equal.
-    bool adjacent_or_equal(const psite& lhs, const psite& rhs) const;
-    /// Return true if the vertices \a lhs and \a rhs are adjacent, or equal
-    bool adjacent_or_equal(const util::vertex_id& lhs,
-			   const util::vertex_id& rhs) const;
-    /// \}
-
-    /// \}
-
-  public:
-    // FIXME: Should be private.
-    util::tracked_ptr<graph> gr_;
-  };
-
-
-  /// \brief Comparison between two mln::p_graph's.
-  ///
-  /// Two mln::p_graph's are considered equal if they share the
-  /// same graph.
-  template <typename P>
-  bool
-  operator==(const p_graph<P>& lhs, const p_graph<P>& rhs);
-
-
-  /* FIXME: Extend the `ord' mechanism instead of this ill-defined
-     pseudo-order. */
-
-  /// \brief Inclusion of a mln::p_graph in another one.
-  ///
-  /// This inclusion relation is very strict for the moment, since our
-  /// infrastructure for graphs is simple: a mln::p_graph is included
-  /// in another one if their are equal.
-  ///
-  /// \todo Refine this later, when we are able to express subgraph
-  /// relations.
-  template <typename P>
-  bool
-  operator<=(const p_graph<P>& lhs, const p_graph<P>& rhs);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-  template <typename P>
-  inline
-  p_graph<P>::p_graph(const graph& gr)
-    // Create a deep, managed copy of GR.
-    : gr_ (new util::graph(gr))
-  {
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_graph<P>::nsites() const
-  {
-    return nvertices();
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_graph<P>::nvertices() const
-  {
-    return this->gr_->nvertices();
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_graph<P>::nedges() const
-  {
-    return this->gr_->nedges();
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::is_valid() const
-  {
-    // FIXME: Might be too low-level, again.
-    return gr_.ptr_;
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::has(const psite& p) const
-  {
-    mln_precondition(is_valid());
-    return
-      // Check whether P is compatible with this psite set.
-      (p.target_() == this) &&
-      // Check that the vertex id of P belongs to the range of valid
-      // vertex ids.
-      (p.is_valid());
-  }
-
-  template <typename P>
-  inline
-  std::size_t
-  p_graph<P>::memory_size() const
-  {
-    // FIXME: Dummy; implement (see other site sets).
-    abort();
-    return 0;
-  }
-
-  template <typename P>
-  const typename p_graph<P>::graph&
-  p_graph<P>::gr() const
-  {
-    mln_precondition(is_valid());
-    return *gr_.ptr;
-  }
-
-  template <typename P>
-  typename p_graph<P>::graph&
-  p_graph<P>::gr()
-  {
-    mln_precondition(is_valid());
-    return *gr_.ptr;
-  }
-
-  template <typename P>
-  const P&
-  p_graph<P>::point_from_id(const util::vertex_id& id) const
-  {
-    return this->gr_->vertex_data(id);
-  }
-
-  template <typename P>
-  P&
-  p_graph<P>::point_from_id(const util::vertex_id& id)
-  {
-    return this->gr_->vertex_data(id);
-  }
-
-  template <typename P>
-  const P&
-  p_graph<P>::vertex1(const util::edge_id& e) const
-  {
-    util::vertex_id v1 = this->gr_->edge(e).v1();
-    return this->point_from_id(v1);
-  }
-
-  template <typename P>
-  const P&
-  p_graph<P>::vertex2(const util::edge_id& e) const
-  {
-    util::vertex_id v2 = this->gr_->edge(e).v2();
-    return this->point_from_id(v2);
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::adjacent(const psite& lhs, const psite& rhs) const
-  {
-    mln_assertion(&lhs.pg() == this && rhs.pg() == this);
-    return adjacent(lhs.id(), rhs.id());
-  }
-
-  /* FIXME: This could be more efficient, if the graph structure had a
-     richer interface.  */
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::adjacent(const util::vertex_id& lhs,
-		       const util::vertex_id& rhs) const
-  {
-    mln_assertion(lhs < this->nsites());
-    mln_assertion(rhs < this->nsites());
-
-    // Ensure LHS and RHS are *not* equal.
-    if (rhs == lhs)
-      return false;
-
-    // Check whether LHS and RHS are adjacent (i.e., whether RHS is
-    // among the neighbors of LHS).
-    typedef std::vector<util::edge_id> edges_t;
-    const edges_t& lhs_neighbs = gr_->vertices()[lhs]->edges;
-    for (edges_t::const_iterator e = lhs_neighbs.begin();
-	 e != lhs_neighbs.end(); ++e)
-      if (gr_->edges()[*e]->v1() == rhs ||
-	  gr_->edges()[*e]->v2() == rhs)
-	return true;
-
-    return false;
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::adjacent_or_equal(const psite& lhs, const psite& rhs) const
-  {
-    mln_assertion(&lhs.pg() == this && rhs.pg() == this);
-    return adjacent_or_equal(lhs.id(), rhs.id());
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_graph<P>::adjacent_or_equal(const util::vertex_id& lhs,
-				const util::vertex_id& rhs) const
-  {
-    mln_assertion(lhs < this->nsites());
-    mln_assertion(rhs < this->nsites());
-
-    // Check whether LHS and RHS are equal.
-    if (lhs == rhs)
-      return true;
-    // Check whether LHS and RHS are adjacent.
-    return adjacent(lhs, rhs);
-  }
-
-
-  template <typename P>
-  bool
-  operator==(const p_graph<P>& lhs, const p_graph<P>& rhs)
-  {
-    /* FIXME: We should not rely on pointer equality here, as graph
-       will soon become shells using (shared) tracked pointers to
-       actual data.  So, delegate the equality test to the graphs
-       themselves.  */
-    return lhs.gr_.ptr_ == rhs.gr_.ptr_;
-  }
-
-  template <typename P>
-  bool
-  operator<=(const p_graph<P>& lhs, const p_graph<P>& rhs)
-  {
-    return lhs == rhs;
-  }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // MLN_CORE_SITE_SET_P_GRAPH_HH
diff --git a/milena/mln/core/site_set/p_line_graph.hh b/milena/mln/core/site_set/p_line_graph.hh
deleted file mode 100644
index 28780ea..0000000
--- a/milena/mln/core/site_set/p_line_graph.hh
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CORE_SITE_SET_P_LINE_GRAPH_HH
-# define MLN_CORE_SITE_SET_P_LINE_GRAPH_HH
-
-/// \file mln/core/site_set/p_line_graph.hh
-/// \brief Definition of a point set based on a line graph.
-
-# include <mln/core/internal/site_set_base.hh>
-# include <mln/util/graph.hh>
-# include <mln/util/tracked_ptr.hh>
-# include <mln/util/site_pair.hh>
-
-# include <mln/core/image/line_graph_psite.hh>
-# include <mln/core/site_set/p_line_graph_piter.hh>
-
-/* FIXME: This class shares a lot with p_graph.  Factor as much as
-   possible.  */
-
-/* FIXME: We should move the `adjacent'/`adjacent_or_equal' methods
-   out of this class (into iterators on *graph*).  */
-
-namespace mln
-{
-
-  // Forward declaration.
-  template<typename P> struct p_line_graph;
-
-
-  namespace trait
-  {
-    template <typename P>
-    struct site_set_< p_line_graph<P> >
-    {
-      typedef trait::site_set::nsites::known   nsites;
-      // FIXME: Depends on P!
-      typedef trait::site_set::bbox::unknown   bbox;
-      typedef trait::site_set::contents::fixed contents;
-      typedef trait::site_set::arity::unique   arity;
-    };
-  } // end of namespace mln::trait
-
-
-  template<typename P>
-  struct p_line_graph
-    : public internal::site_set_base_< util::site_pair<P>, p_line_graph<P> >
-  {
-    typedef p_line_graph<P> self_;
-    typedef internal::site_set_base_< util::site_pair<P>, self_ > super_;
-
-    typedef util::graph<P> graph;
-
-    /// \brief Construct a line graph psite set from a graph of points.
-    ///
-    /// \param gr The graph upon which the line graph psite set is built.
-    ///
-    /// \a gr is \em copied internally, so that the line graph psite
-    /// set is still valid after the initial graph has been removed.
-    p_line_graph(const graph& gr);
-
-    /// Associated types.
-    /// \{
-    /// Element associated type.
-    typedef mln_site(super_) element;
-
-    /// Point_Site associated type.
-    typedef line_graph_psite<P> psite;
-
-    /// Forward Site_Iterator associated type.
-    typedef p_line_graph_fwd_piter_<P> fwd_piter;
-
-    /// Backward Site_Iterator associated type.
-    typedef p_line_graph_bkd_piter_<P> bkd_piter;
-
-    /// Site_Iterator associated type.
-    typedef fwd_piter piter;
-    /// \}
-
-    /// \brief Return The number of sites of the set, i.e., the number
-    /// of \em edges.
-    ///
-    /// (Required by the mln::Site_Set concept, since the property
-    /// trait::site_set::nsites::known of this site set is set to
-    /// `known'.)
-    /* FIXME: Return type should be std::size_t (see
-       mln/core/concept/site_set.hh). */
-    unsigned nsites() const;
-
-    /// Return The number of vertices in the graph.
-    unsigned nvertices() const;
-    /// Return The number of edges in the graph.
-    unsigned nedges() const;
-
-    /// Is this site set valid?
-    bool is_valid() const;
-
-    /// Does this site set has \a p?
-    bool has(const psite& p) const;
-
-    // FIXME: Dummy.
-    std::size_t memory_size() const;
-
-    /// Accessors.
-    /// \{
-    /// Return the graph associated to this site set (const version)
-    const graph& gr() const;
-    /// Return the graph associated to this site set (mutable version).
-    graph& gr();
-    /// \}
-
-    // FIXME: These would probably be no longer needed as soon as
-    // iterators on graphs are available.
-
-    /// Adjacency tests.
-    /// \{
-    /// Return true if the psites \a lhs and \a rhs are adjacent.
-    /// (If \a lhs and \a rhs are equal, return false).
-    bool adjacent(const psite& lhs, const psite& rhs) const;
-    /// Return true if the edges \a lhs and \a rhs are adjacent.
-    /// (If \a lhs and \a rhs are equal, return false).
-    bool adjacent(const util::edge_id& lhs, const util::edge_id& rhs) const;
-
-    /// Return true if the psites \a lhs and \a rhs are adjacent, or equal.
-    bool adjacent_or_equal(const psite& lhs, const psite& rhs) const;
-    /// Return true if the edges \a lhs and \a rhs are adjacent, or equal
-    bool adjacent_or_equal(const util::edge_id& lhs,
-			   const util::edge_id& rhs) const;
-    /// \}
-
-    // FIXME: Should be private.
-    /// The graph on which the pset is built.
-    util::tracked_ptr<graph> gr_;
-  };
-
-
-  /// \brief Comparison between two mln::p_line_graph's.
-  ///
-  /// Two mln::p_line_graph's are considered equal if they share the
-  /// same graph.
-  template <typename P>
-  bool
-  operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs);
-
-
-  /* FIXME: Extend the `ord' mechanism instead of this ill-defined
-     pseudo-order. */
-
-  /// \brief Inclusion of a mln::p_line_graph in another one.
-  ///
-  /// This inclusion relation is very strict for the moment, since our
-  /// infrastructure for graphs is simple: a mln::p_line_graph is
-  /// included in another one if their are equal.
-  ///
-  /// \todo Refine this later, when we are able to express subgraph
-  /// relations.
-  template <typename P>
-  bool
-  operator<=(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-  template <typename P>
-  inline
-  p_line_graph<P>::p_line_graph(const graph& gr)
-    // Create a deep, managed copy of GR.
-    : gr_(new util::graph<P>(gr))
-  {
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_line_graph<P>::nsites() const
-  {
-    return nedges();
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_line_graph<P>::nvertices() const
-  {
-    return this->gr_->nvertices();
-  }
-
-  template <typename P>
-  inline
-  unsigned
-  p_line_graph<P>::nedges() const
-  {
-    return this->gr_->nedges();
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::is_valid() const
-  {
-    // FIXME: Might be too low-level, again.
-    return gr_.ptr_;
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::has(const psite& p) const
-  {
-    mln_precondition(is_valid());
-    return
-      // Check whether P is compatible with this psite set.
-      (p.target_() == this) &&
-      // Check that the edge id of P belongs to the range of valid edge ids.
-      (p.is_valid());
-  }
-
-  template <typename P>
-  inline
-  std::size_t
-  p_line_graph<P>::memory_size() const
-  {
-    // FIXME: Dummy; implement (see other site sets).
-    abort();
-    return 0;
-  }
-
-  template <typename P>
-  const util::graph<P>&
-  p_line_graph<P>::gr() const
-  {
-    mln_precondition(is_valid());
-    return *gr_.ptr_;
-  }
-
-  template <typename P>
-  util::graph<P>&
-  p_line_graph<P>::gr()
-  {
-    mln_precondition(is_valid());
-    return *gr_.ptr_;
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::adjacent(const psite& lhs, const psite& rhs) const
-  {
-    mln_assertion(&lhs.plg() == this && rhs.plg() == this);
-    return adjacent(lhs.id(), rhs.id());
-  }
-
-  /* FIXME: This could be more efficient, if the graph structure had a
-     richer interface.  */
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::adjacent(const util::edge_id& lhs,
-			    const util::edge_id& rhs) const
-  {
-    mln_assertion(lhs < this->nsites());
-    mln_assertion(rhs < this->nsites());
-
-    // Ensure LHS and RHS are *not* equal.
-    if (lhs == rhs)
-      return false;
-
-    // Check whether LHS and RHS are adjacent (i.e., whether LHS and
-    // RHS share a common vertex.
-    /* FIXME: This is too low-level.  Yet another service the graph
-       should provide.  */
-    if (gr_->edge(lhs).v1() == gr_->edge(rhs).v1() ||
-	gr_->edge(lhs).v1() == gr_->edge(rhs).v2() ||
-	gr_->edge(lhs).v2() == gr_->edge(rhs).v1() ||
-	gr_->edge(lhs).v2() == gr_->edge(rhs).v2())
-      return true;
-
-    return false;
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::adjacent_or_equal(const psite& lhs, const psite& rhs) const
-  {
-    mln_assertion(&lhs.pg() == this && rhs.pg() == this);
-    return adjacent_or_equal(lhs.id(), rhs.id());
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph<P>::adjacent_or_equal(const util::edge_id& lhs,
-				     const util::edge_id& rhs) const
-  {
-    mln_assertion(lhs < this->nsites());
-    mln_assertion(rhs < this->nsites());
-
-    // Check whether LHS and RHS are equal.
-    if (lhs == rhs)
-      return true;
-    // Check whether RHS and LHS are adjacent.
-    return adjacent(lhs, rhs);
-  }
-
-
-  /*--------------.
-  | Comparisons.  |
-  `--------------*/
-
-  template <typename P>
-  bool
-  operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs)
-  {
-    /* FIXME: We should not rely on pointer equality here, as graph
-       will soon become shells using (shared) tracked pointers to
-       actual data.  So, delegate the equality test to the graphs
-       themselves.  */
-    return lhs.gr_.ptr_ == rhs.gr_.ptr_;
-  }
-
-  template <typename P>
-  bool
-  operator<=(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs)
-  {
-    return lhs == rhs;
-  }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // ! MLN_CORE_SITE_SET_P_LINE_GRAPH_HH
diff --git a/milena/mln/core/site_set/p_line_graph_piter.hh b/milena/mln/core/site_set/p_line_graph_piter.hh
deleted file mode 100644
index 8c73c26..0000000
--- a/milena/mln/core/site_set/p_line_graph_piter.hh
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CORE_SITE_SET_P_LINE_GRAPH_PITER_HH
-# define MLN_CORE_SITE_SET_P_LINE_GRAPH_PITER_HH
-
-/// \file mln/core/site_set/p_line_graph_piter.hh
-/// \brief Definition of point iterators on line graph-based site set.
-
-# include <mln/core/internal/site_set_iterator_base.hh>
-# include <mln/core/site_set/p_line_graph.hh>
-# include <mln/core/image/line_graph_psite.hh>
-
-/* FIXME: Iterators on p_graph and p_line_graph share common code.
-   Factor as much as possible.  */
-
-
-namespace mln
-{
-
-  // Forward declarations.
-  template <typename P> class p_line_graph;
-  template <typename P> class line_graph_psite;
-
-
-  /*-----------------------------.
-  | p_line_graph_fwd_piter_<P>.  |
-  `-----------------------------*/
-
-  /// \brief Forward iterator on point sites of a mln::p_line_graph<P>.
-  template <typename P>
-  class p_line_graph_fwd_piter_
-    : public internal::site_set_iterator_base< p_line_graph<P>,
-					       p_line_graph_fwd_piter_<P> >
-  {
-    typedef p_line_graph_fwd_piter_<P> self_;
-    typedef internal::site_set_iterator_base< p_line_graph<P>, self_ > super_;
-
-  public:
-    /// Construction and assignment.
-    /// \{
-    p_line_graph_fwd_piter_();
-    p_line_graph_fwd_piter_(const p_line_graph<P>& plg);
-    /// \}
-
-    /// Manipulation.
-    /// \{
-    /// 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_();
-    /// \}
-
-  protected:
-    /// The psite corresponding to this iterator.
-    using super_::p_;
-  };
-
-
-  /// Print an mln::p_line_graph_fwd_piter_<P>.
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_line_graph_fwd_piter_<P>& p);
-
-
-  /*-----------------------------.
-  | p_line_graph_bkd_piter_<P>.  |
-  `-----------------------------*/
-
-  /// \brief Backward iterator on point sites of a mln::p_line_graph<P>.
-  template <typename P>
-  class p_line_graph_bkd_piter_
-    : public internal::site_set_iterator_base< p_line_graph<P>,
-					       p_line_graph_bkd_piter_<P> >
-  {
-    typedef p_line_graph_bkd_piter_<P> self_;
-    typedef internal::site_set_iterator_base< p_line_graph<P>, self_ > super_;
-
-  public:
-    /// Construction and assignment.
-    /// \{
-    p_line_graph_bkd_piter_();
-    p_line_graph_bkd_piter_(const p_line_graph<P>& plg);
-    /// \}
-
-    /// Manipulation.
-    /// \{
-    /// 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_();
-    /// \}
-
-  protected:
-    /// The psite corresponding to this iterator.
-    using super_::p_;
-  };
-
-
-  /// Print an mln::p_line_graph_bkd_piter_<P>.
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_line_graph_bkd_piter_<P>& p);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-  /*-----------------------------.
-  | p_line_graph_fwd_piter_<P>.  |
-  `-----------------------------*/
-
-  template <typename P>
-  inline
-  p_line_graph_fwd_piter_<P>::p_line_graph_fwd_piter_()
-  {
-    mln_postcondition(!this->is_valid());
-  }
-
-  template <typename P>
-  inline
-  p_line_graph_fwd_piter_<P>::p_line_graph_fwd_piter_(const p_line_graph<P>& plg)
-  {
-    this->change_target(plg);
-    mln_postcondition(!this->is_valid());
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph_fwd_piter_<P>::is_valid_() const
-  {
-    return p_.is_valid();
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_fwd_piter_<P>::invalidate_()
-  {
-    p_.invalidate();
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_fwd_piter_<P>::start_()
-  {
-    p_.change_edge_id(0);
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_fwd_piter_<P>::next_()
-  {
-    p_.inc_edge_id();
-  }
-
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_line_graph_fwd_piter_<P>& p)
-  {
-    return ostr << p.unproxy_();
-  }
-
-
-  /*-----------------------------.
-  | p_line_graph_bkd_piter_<P>.  |
-  `-----------------------------*/
-
-  template <typename P>
-  inline
-  p_line_graph_bkd_piter_<P>::p_line_graph_bkd_piter_()
-  {
-    mln_postcondition(!this->is_valid());
-  }
-
-  template <typename P>
-  inline
-  p_line_graph_bkd_piter_<P>::p_line_graph_bkd_piter_(const p_line_graph<P>& plg)
-  {
-    this->change_target(plg);
-    mln_postcondition(!this->is_valid());
-  }
-
-  template <typename P>
-  inline
-  bool
-  p_line_graph_bkd_piter_<P>::is_valid_() const
-  {
-    return p_.is_valid();
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_bkd_piter_<P>::invalidate_()
-  {
-    p_.change_edge_id(this->site_set().nedges());
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_bkd_piter_<P>::start_()
-  {
-    p_.change_edge_id(this->site_set().nedges() - 1);
-  }
-
-  template <typename P>
-  inline
-  void
-  p_line_graph_bkd_piter_<P>::next_()
-  {
-    p_.dec_edge_id();
-  }
-
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const p_line_graph_bkd_piter_<P>& p)
-  {
-    return ostr << p.unproxy_();
-  }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-} // end of mln
-
-
-#endif // ! MLN_CORE_SITE_SET_P_LINE_GRAPH_PITER_HH
diff --git a/milena/mln/make/all.hh b/milena/mln/make/all.hh
index 5d11136..910d943 100644
--- a/milena/mln/make/all.hh
+++ b/milena/mln/make/all.hh
@@ -55,7 +55,7 @@ namespace mln
 # include <mln/make/pixel.hh>
 # include <mln/make/point2d_h.hh>
 # include <mln/make/vec.hh>
-//# include <mln/make/voronoi.hh>
+# include <mln/make/voronoi.hh>
 # include <mln/make/w_window.hh>
 # include <mln/make/w_window1d.hh>
 # include <mln/make/w_window1d_int.hh>
diff --git a/milena/mln/make/essential.hh b/milena/mln/make/essential.hh
index d0e8f85..856e75a 100644
--- a/milena/mln/make/essential.hh
+++ b/milena/mln/make/essential.hh
@@ -40,9 +40,9 @@
 # include <mln/make/pix.hh>
 # include <mln/make/pixel.hh>
 # include <mln/make/vec.hh>
-//# include <mln/make/voronoi.hh>
+# include <mln/make/voronoi.hh>
 # include <mln/make/w_window.hh>
 # include <mln/make/w_window_directional.hh>
-//# include <mln/make/win_chamfer.hh>
+# include <mln/make/win_chamfer.hh>
 
 #endif // ! MLN_MAKE_ESSENTIAL_HH
diff --git a/milena/mln/make/voronoi.hh b/milena/mln/make/voronoi.hh
index 0127c97..30101f2 100644
--- a/milena/mln/make/voronoi.hh
+++ b/milena/mln/make/voronoi.hh
@@ -29,18 +29,18 @@
 #ifndef MLN_MAKE_VORONOI_HH
 # define MLN_MAKE_VORONOI_HH
 
-/*! \file mln/make/voronoi.hh
- *
- * \brief Routine to construct a Voronoi mln::p_graph.
- */
+/// \file mln/make/voronoi.hh
+///
+/// Routine to construct a Voronoi mln::p_graph.
 
 # include <vector>
 # include <map>
 
 # include <mln/core/concept/neighborhood.hh>
-# include <mln/core/site_set/p_graph.hh>
+# include <mln/core/site_set/p_vertices.hh>
 # include <mln/accu/mean.hh>
 # include <mln/estim/min_max.hh>
+# include <mln/util/graph.hh>
 
 namespace mln
 {
@@ -48,10 +48,9 @@ namespace mln
   namespace make
   {
 
+    /// Apply the Voronoi algorithm on \p ima_ with the original
+    /// image \p orig_ for node computing with neighborhood \p nbh.
     /*!
-     *  \brief Apply the Voronoi algorithm on \p ima_ with the original
-     *  image \p orig_ for node computing with neighborhood \p nbh.
-     *
      * \param[in] ima_ The labeling image.
      * \param[in] orig_ The original image.
      * \param[in] nbh The neighborhood for computing algorithm.
@@ -59,7 +58,7 @@ namespace mln
      * \return The computed graph.
      */
     template <typename I, typename N>
-    p_graph<mln_psite(I)>
+    p_vertices<util::graph, fun::i2v::array<mln_site(I)> >
     voronoi (Image<I>& ima_,
 	     Image<I>& orig_,
 	     const Neighborhood<N>& nbh);
@@ -68,7 +67,7 @@ namespace mln
 
     template <typename I, typename N>
     inline
-    p_graph<mln_psite(I)>
+    p_vertices<util::graph, fun::i2v::array<mln_site(I)> >
     voronoi (Image<I>& ima_,
 	     Image<I>& orig_,
 	     const Neighborhood<N>& nbh)
@@ -79,11 +78,11 @@ namespace mln
 
       I& ima = exact(ima_);
       I& orig = exact(orig_);
-      util::graph<void> gr;
+      util::graph gr;
       V min, max;
       estim::min_max (ima, min, max);
       unsigned nb = max - min + 1;
-      std::vector<P> v(nb);
+      fun::i2v::array<P> v(nb);
       std::vector< accu::mean< X > > tab_mean (nb);
       std::map<std::pair<V, V>, bool> m;
 
@@ -120,7 +119,7 @@ namespace mln
 	  gr.add_vertex();
 
 	  /// FIXME
- 	  v[i] = point2d ((unsigned)tab_mean[i].to_result ()[0],
+	  v[i] = point2d ((unsigned)tab_mean[i].to_result ()[0],
 				(unsigned)tab_mean[i].to_result ()[1]);
 	}
 
@@ -128,7 +127,7 @@ namespace mln
       for (; it != m.end (); ++it)
 	gr.add_edge((*it).first.first, (*it).first.second);
 
-      p_graph<P> res(gr, v);
+      p_vertices<util::graph, fun::i2v::array<P> > res(gr, v);
       return res;
     }
 
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh
index 0f8c1fa..dfcbc23 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/graph.hh
@@ -30,7 +30,7 @@
 # define MLN_UTIL_GRAPH_HH
 
 /// \file mln/util/graph.hh
-/// \brief Definitions of undirected graphs.
+/// Definitions of undirected graphs.
 
 # include <mln/util/internal/graph_base.hh>
 # include <mln/util/internal/graph_iter.hh>
diff --git a/milena/mln/util/internal/graph_edge_impl.hh b/milena/mln/util/internal/graph_edge_impl.hh
index 7f77f2a..3b75086 100644
--- a/milena/mln/util/internal/graph_edge_impl.hh
+++ b/milena/mln/util/internal/graph_edge_impl.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -28,11 +28,10 @@
 #ifndef MLN_CORE_INTERNAL_GRAPH_EDGE_IMPL_HH
 # define MLN_CORE_INTERNAL_GRAPH_EDGE_IMPL_HH
 
-/*! \file mln/util/internal/graph_edge_impl.hh
- *
- * \brief Define a couple of implementation classes to provide methods
- * to classes of generalized edges.
- */
+/// \file mln/util/internal/graph_edge_impl.hh
+///
+/// Define a couple of implementation classes to provide methods
+/// to classes of generalized edges.
 
 # include <mln/core/internal/force_exact.hh>
 
diff --git a/milena/mln/util/internal/graph_edge_psite.hh b/milena/mln/util/internal/graph_edge_psite.hh
index 05ad74f..c1c7d16 100644
--- a/milena/mln/util/internal/graph_edge_psite.hh
+++ b/milena/mln/util/internal/graph_edge_psite.hh
@@ -30,6 +30,7 @@
 
 # include <mln/core/concept/pseudo_site.hh>
 # include <mln/util/internal/graph_psite_base.hh>
+# include <mln/util/internal/graph_edge.hh>
 
 namespace mln
 {
@@ -112,7 +113,7 @@ namespace mln
       template <typename G, typename F>
       inline
       edge_psite<G, F>::edge_psite(const target_t& t, unsigned id)
-	: super_(id)
+	: super_(t, id)
       {
       }
 
diff --git a/milena/mln/util/internal/graph_vertex_impl.hh b/milena/mln/util/internal/graph_vertex_impl.hh
index 3abfaf5..bfe6360 100644
--- a/milena/mln/util/internal/graph_vertex_impl.hh
+++ b/milena/mln/util/internal/graph_vertex_impl.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -28,11 +28,10 @@
 #ifndef MLN_CORE_INTERNAL_GRAPH_VERTEX_IMPL_HH
 # define MLN_CORE_INTERNAL_GRAPH_VERTEX_IMPL_HH
 
-/*! \file mln/util/internal/graph_vertex_impl.hh
- *
- * \brief Define a couple of implementation classes to provide methods
- * to classes of generalized vertexs.
- */
+/// \file mln/util/internal/graph_vertex_impl.hh
+///
+/// Define a couple of implementation classes to provide methods
+/// to classes of generalized vertexs.
 
 # include <mln/core/internal/force_exact.hh>
 
diff --git a/milena/tests/core/image/graph_image.cc b/milena/tests/core/image/graph_image.cc
index 4c3f09a..9fc556c 100644
--- a/milena/tests/core/image/graph_image.cc
+++ b/milena/tests/core/image/graph_image.cc
@@ -46,12 +46,10 @@
 #include <mln/core/image/graph_elt_neighborhood.hh>
 
 #include <mln/fun/i2v/array.hh>
-#include <mln/fun/p2v/iota.hh>
 
 #include <mln/util/graph.hh>
 
 #include <mln/debug/graph.hh>
-//#include <mln/debug/iota.hh>
 #include <mln/debug/println.hh>
 #include <mln/core/concept/function.hh>
 
@@ -101,18 +99,18 @@ int main()
   */
 
   // Points associated to vertices.
-  typedef fun::i2v::array<point2d> fpoint_t;
-  fpoint_t points(5);
-  points(0) = point2d(0,0); // Point associated to vertex 0.
-  points(1) = point2d(2,2); // Point associated to vertex 1.
-  points(2) = point2d(0,4); // Point associated to vertex 2.
-  points(3) = point2d(4,3); // Point associated to vertex 3.
-  points(4) = point2d(4,4); // Point associated to vertex 4.
+  typedef fun::i2v::array<point2d> fsite_t;
+  fsite_t sites(5);
+  sites(0) = point2d(0,0); // Point associated to vertex 0.
+  sites(1) = point2d(2,2); // Point associated to vertex 1.
+  sites(2) = point2d(0,4); // Point associated to vertex 2.
+  sites(3) = point2d(4,3); // Point associated to vertex 3.
+  sites(4) = point2d(4,4); // Point associated to vertex 4.
 
   // Edges.
   util::graph g;
   // Populate the graph with vertices.
-  for (unsigned i = 0; i < points.size(); ++i)
+  for (unsigned i = 0; i < sites.size(); ++i)
     g.add_vertex();
   // Populate the graph with edges.
   g.add_edge(0, 1);
@@ -127,8 +125,8 @@ int main()
   | Graph image support.  |
   `----------------------*/
 
-  typedef p_vertices<util::graph, fpoint_t> S;
-  S pv(g, points);
+  typedef p_vertices<util::graph, fsite_t> S;
+  S pv(g, sites);
 
   /*-------------.
   | Graph image.  |
@@ -187,7 +185,7 @@ int main()
 
   {
     // Window - Forward iteration
-    typedef graph_elt_window<util::graph, fpoint_t> win_t;
+    typedef graph_elt_window<util::graph, fsite_t> win_t;
     win_t win;
     mln_qiter_(win_t) q(win, p);
     for_all (p)
@@ -201,7 +199,7 @@ int main()
 
   {
     // Window - Backward iteration
-    typedef graph_elt_window<util::graph, fpoint_t> win_t;
+    typedef graph_elt_window<util::graph, fsite_t> win_t;
     win_t win;
     mln_bkd_qiter_(win_t) q(win, p);
     for_all (p)
@@ -215,29 +213,33 @@ int main()
 
   {
     // Neighborhood - Forward iteration
-    typedef graph_elt_neighborhood<util::graph, fpoint_t> neigh_t;
+    typedef graph_elt_neighborhood<util::graph, fsite_t> neigh_t;
     neigh_t neigh;
     mln_niter_(neigh_t) n(neigh, p);
     for_all (p)
     {
-      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
-		<< "including the site itself:" << std::endl;
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), " << std::endl;
       for_all (n)
+      {
+	mln_assertion(n != p);
 	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+      }
     }
   }
 
   {
     // Neighborhood - Backward iteration
-    typedef graph_elt_neighborhood<util::graph, fpoint_t> neigh_t;
+    typedef graph_elt_neighborhood<util::graph, fsite_t> neigh_t;
     neigh_t neigh;
     mln_bkd_niter_(neigh_t) n(neigh, p);
     for_all (p)
     {
-      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
-		<< "including the site itself:" << std::endl;
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), " << std::endl;
       for_all (n)
+      {
+	mln_assertion(n != p);
 	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+      }
     }
   }
   std::cout << std::endl;
diff --git a/milena/tests/core/image/line_graph_image.cc b/milena/tests/core/image/line_graph_image.cc
index 74d374b..360623c 100644
--- a/milena/tests/core/image/line_graph_image.cc
+++ b/milena/tests/core/image/line_graph_image.cc
@@ -31,9 +31,41 @@
 #include <vector>
 
 #include <mln/core/alias/point2d.hh>
-#include <mln/core/image/line_graph_image.hh>
+#include <mln/pw/all.hh>
+
+//#include <mln/core/image/line_graph_image.hh>
 #include <mln/core/image/line_graph_elt_window.hh>
-#include <mln/core/image/line_graph_window_piter.hh>
+#include <mln/core/image/line_graph_elt_neighborhood.hh>
+#include <mln/core/site_set/p_edges.hh>
+
+#include <mln/fun/i2v/array.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/core/var.hh>
+
+template <typename S>
+struct viota_t : public mln::Function_p2v< viota_t<S> >
+{
+  typedef unsigned result;
+
+  viota_t(unsigned size)
+  {
+    v_.resize(size);
+    for (unsigned i = 0; i < size; ++i)
+      v_[i] = 10 + i;
+  }
+
+  unsigned
+  operator()(const mln_psite(S)& p) const
+  {
+    return v_[p.e().id()];
+  }
+
+  protected:
+    std::vector<result> v_;
+};
+
 
 
 int main()
@@ -48,7 +80,7 @@ int main()
 
             0 1 2 3 4               0 1 2 3 4
          .-----------	         .-----------
-         |		         |	     
+         |		         |
        0 |  0       2	       0 |  *       *
        1 |    \   / |	       1 |    0   1 |
        2 |      1   |	       2 |      *   4
@@ -57,19 +89,19 @@ int main()
 
   */
 
-  // Points associated to vertices.
-  std::vector<point2d> points;
-  points.push_back(point2d(0,0)); // Point associated to vertex 0.
-  points.push_back(point2d(2,2)); // Point associated to vertex 1.
-  points.push_back(point2d(0,4)); // Point associated to vertex 2.
-  points.push_back(point2d(4,3)); // Point associated to vertex 3.
-  points.push_back(point2d(4,4)); // Point associated to vertex 4.
+  // Sites associated to edges.
+  typedef fun::i2v::array<point2d> fsite_t;
+  fsite_t sites(5);
+  sites(0) = point2d(0,0); // Point associated to edge 0.
+  sites(1) = point2d(2,2); // Point associated to edge 1.
+  sites(2) = point2d(0,4); // Point associated to edge 2.
+  sites(3) = point2d(4,3); // Point associated to edge 3.
+  sites(4) = point2d(4,4); // Point associated to edge 4.
 
-  // Edges.
-  util::graph<point2d> g;
+  util::graph g;
   // Populate the graph with vertices.
-  for (unsigned i = 0; i < points.size(); ++i)
-    g.add_vertex (points[i]);
+  for (unsigned i = 0; i < sites.size(); ++i)
+    g.add_vertex();
   // Populate the graph with edges.
   g.add_edge(0, 1);
   g.add_edge(1, 2);
@@ -81,33 +113,18 @@ int main()
   | Line graph image support.  |
   `---------------------------*/
 
-  p_line_graph<point2d> plg(g);
-
-  // Check adjacencies of edge 1.
-  mln_assertion( plg.adjacent(1, 0));
-  mln_assertion(!plg.adjacent(1, 1));
-  mln_assertion( plg.adjacent(1, 2));
-  mln_assertion(!plg.adjacent(1, 3));
-  mln_assertion( plg.adjacent(1, 4));
+  typedef p_edges<util::graph, fsite_t> S;
+  S pe(g, sites);
 
   /*-------------------.
   | Line graph image.  |
   `-------------------*/
 
-  // Values ("empty" vectors).
-  std::vector<int> vertex_values(5);
-  std::vector<int> edge_values(5);
-  // FIXME: hand-made iota's.
-  for (unsigned i = 0; i < vertex_values.size(); ++i)
-    vertex_values[i] = i;
-  for (unsigned i = 0; i < edge_values.size(); ++i)
-    edge_values[i] = i;
-
-  // Line graph image.
-  /* FIXME: We probably don't want to build line_graph_images by hand;
-     provide helpers and/or conversion functions.  */
-  typedef line_graph_image<point2d, int> ima_t;
-  ima_t ima(plg, vertex_values, edge_values);
+  // Graph values.
+  viota_t<S> iota(5);
+
+  // Create line graph image.
+  mln_const_VAR(ima, (iota | pe));
 
   /*------------.
   | Iterators.  |
@@ -115,20 +132,68 @@ int main()
 
   // Manual iteration over the domain of IMA.
   mln_piter_(ima_t) p(ima.domain());
+  unsigned i = 10;
   for_all (p)
-    std::cout << "ima (" << p << ") = " << ima(p) << std::endl;
+    mln_assertion(ima(p) == i++);
+
+  {
+    // Window - Forward iteration
+    typedef line_graph_elt_window<util::graph, fsite_t> win_t;
+    win_t win;
+    mln_qiter_(win_t) q(win, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (q)
+	std::cout << "  " << q << " (level = " << ima(q) << ")" << std::endl;
+    }
+  }
 
-  // Manual iterations over the neighborhoods of each point site of IMA.
-  typedef line_graph_elt_window<point2d> win_t;
-  win_t win;
-  mln_qiter_(win_t) q(win, p);
-  for_all (p)
   {
-    std::cout << "sites adjacent to " << p << " (" << ima(p) << "), "
-	      << "including the site itself:" << std::endl;
-    for_all (q)
-      std::cout << "  " << q << " (level = " << ima(q) << ")"
-		<< std::endl;
+    // Window - Backward iteration
+    typedef line_graph_elt_window<util::graph, fsite_t> win_t;
+    win_t win;
+    mln_bkd_qiter_(win_t) q(win, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (q)
+	std::cout << "  " << q << " (level = " << ima(q) << ")" << std::endl;
+    }
   }
+  {
+    // Neighborhood - Forward iteration
+    typedef line_graph_elt_neighborhood<util::graph, fsite_t> neigh_t;
+    neigh_t neigh;
+    mln_niter_(neigh_t) n(neigh, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), " << std::endl;
+      for_all (n)
+      {
+	mln_assertion(n != p);
+	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+      }
+    }
+  }
+
+  {
+    // Neighborhood - Backward iteration
+    typedef line_graph_elt_neighborhood<util::graph, fsite_t> neigh_t;
+    neigh_t neigh;
+    mln_bkd_niter_(neigh_t) n(neigh, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), " << std::endl;
+      for_all (n)
+      {
+	mln_assertion(n != p);
+	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+      }
+    }
+  }
+
   std::cout << std::endl;
 }
diff --git a/milena/tests/core/site_set/p_edges.cc b/milena/tests/core/site_set/p_edges.cc
index 9ab01a1..1210bce 100644
--- a/milena/tests/core/site_set/p_edges.cc
+++ b/milena/tests/core/site_set/p_edges.cc
@@ -1,4 +1,5 @@
 // Copyright (C) 2008 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,10 +26,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/core/site_set/p_edges.cc
- *
- * \brief Tests on mln::p_edges.
- */
+/// \file tests/core/site_set/p_edges.cc
+///
+/// Tests on mln::p_edges.
 
 #include <mln/util/graph.hh>
 #include <mln/core/alias/point2d.hh>
@@ -40,10 +40,10 @@ struct my_fun
 {
   typedef mln::point2d result;
 
-  const result& operator()(const mln::util::edge<G>& v) const
+  const result& operator()(unsigned v) const
   {
     static mln::point2d res(0, 0);
-    res.row() = v.id();
+    res.row() = v;
     return res;
   }
 };
diff --git a/milena/tests/core/site_set/p_vertices.cc b/milena/tests/core/site_set/p_vertices.cc
index b2c600d..f94ad3b 100644
--- a/milena/tests/core/site_set/p_vertices.cc
+++ b/milena/tests/core/site_set/p_vertices.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,10 +25,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/core/site_set/p_vertices.cc
- *
- * \brief Tests on mln::p_vertices.
- */
+/// \file tests/core/site_set/p_vertices.cc
+///
+/// Tests on mln::p_vertices.
 
 #include <mln/util/graph.hh>
 #include <mln/core/alias/point2d.hh>
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            cleanup-2008 2880: Migrate generic code from morpho	erosion to new files in accu.
                        
                        
by Thierry Geraud 14 Nov '08
                    by Thierry Geraud 14 Nov '08
14 Nov '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Migrate generic code from morpho erosion to new files in accu.
	* mln/morpho/erosion.spe.hh
	(erosion_arbitrary_2d_fastest_functor): Move and rename as...
	* mln/accu/snake_2d.hh (snake_2d_fastest_functor): ...this.
	(todo): New.
	(snake_2d): Move code into (and call it)...
	(snake_2d_dispatch): ...these new routines.
	* mln/morpho/erosion.spe.hh (dp_directional): Move into...
	* mln/accu/transform_directional.hh: ...this new file.
	* mln/morpho/erosion.spe.hh: .
	(dp_directional, erosion_directional_nd_functor),
	(erosion_directional_nd_fastest_functor): Move and rename as...
	* mln/accu/transform_directional.hh
	(directional_functor, directional_fastest_functor): ...these.
	(transform_directional, transform_directional_dispatch): New.
	* mln/morpho/erosion.spe.hh (erosion_on_set_fastest): Remove.
	It is obsolete since handled by accu::transform, called by...
	(generic::erosion_on_set): ...this.
	* mln/morpho/includes.hh (include): Update.
	* tests/morpho/erosion.cc: Update.
 mln/accu/snake_2d.hh              |  218 +++++++++++++
 mln/accu/transform_directional.hh |  347 +++++++++++++++++++++
 mln/morpho/erosion.spe.hh         |  602 +-------------------------------------
 mln/morpho/includes.hh            |    2 
 tests/morpho/erosion.cc           |   45 --
 5 files changed, 586 insertions(+), 628 deletions(-)
Index: tests/morpho/erosion.cc
--- tests/morpho/erosion.cc	(revision 2879)
+++ tests/morpho/erosion.cc	(working copy)
@@ -65,7 +65,9 @@
 
 //   trace::quiet = false;
 
+
   // Rectangle
+
   {
     ref = morpho::impl::generic::erosion_on_function(lena, rec);
   }
@@ -77,18 +79,14 @@
   }
 
   {
-    out = morpho::impl::erosion_arbitrary_2d_fastest(lena, rec);
-    bool test = out == ref;
-    mln_assertion(test);
-  }
-
-  {
     out = morpho::impl::erosion_arbitrary_2d(lena, rec);
     bool test = out == ref;
     mln_assertion(test);
   }
 
+
   //Hline
+
   {
     ref = morpho::impl::generic::erosion_on_function(lena, hline);
   }
@@ -100,19 +98,14 @@
   }
 
   {
-    out = morpho::impl::erosion_arbitrary_2d_fastest(lena, hline);
-    bool test = out == ref;
-    mln_assertion(test);
-  }
-
-
-  {
     out = morpho::impl::erosion_arbitrary_2d(lena, hline);
     bool test = out == ref;
     mln_assertion(test);
   }
 
+
   //Vline
+
   {
     ref = morpho::impl::generic::erosion_on_function(lena, vline);
   }
@@ -123,14 +116,6 @@
     mln_assertion(test);
   }
 
-
-  {
-    out = morpho::impl::erosion_arbitrary_2d_fastest(lena, vline);
-    bool test = out == ref;
-    mln_assertion(test);
-  }
-
-
   {
     out = morpho::impl::erosion_arbitrary_2d(lena, vline);
     bool test = out == ref;
@@ -150,20 +135,13 @@
     mln_assertion(test);
   }
 
-
-  {
-    out = morpho::impl::erosion_arbitrary_2d_fastest(lena, diag2d);
-    bool test = out == ref;
-    mln_assertion(test);
-  }
-
-
   {
     out = morpho::impl::erosion_arbitrary_2d(lena, diag2d);
     bool test = out == ref;
     mln_assertion(test);
   }
 
+
   //Backdiag2d
 
   {
@@ -176,14 +154,6 @@
     mln_assertion(test);
   }
 
-
-  {
-    out = morpho::impl::erosion_arbitrary_2d_fastest(lena, backdiag2d);
-    bool test = out == ref;
-    mln_assertion(test);
-  }
-
-
   {
     out = morpho::impl::erosion_arbitrary_2d(lena, backdiag2d);
     bool test = out == ref;
@@ -193,6 +163,7 @@
 
 
   // Octagon
+
   {
     ref = morpho::impl::generic::erosion_on_function(lena, oct);
     io::pgm::save(ref, "out_oct_ref.pgm");
Index: mln/accu/snake_2d.hh
--- mln/accu/snake_2d.hh	(revision 2879)
+++ mln/accu/snake_2d.hh	(working copy)
@@ -32,13 +32,20 @@
 ///
 /// Run an accumulator in a snake-like browsing.
 ///
+/// \todo Rename as transform_snake_2d.
+///
 /// \todo Make it n-D.
+///
+/// \todo Split dispatch and impl.
+///
+/// \todo Pass the accumulator to the function-object.
 
 #include <mln/core/concept/image.hh>
 #include <mln/core/concept/meta_accumulator.hh>
 #include <mln/core/alias/window2d.hh>
 #include <mln/win/diff.hh>
 #include <mln/win/shift.hh>
+#include <mln/geom/delta.hh>
 #include <mln/extension/adjust.hh>
 #include <mln/canvas/browsing/snake_generic.hh>
 
@@ -83,6 +90,8 @@
       }
 
 
+      // Functor.
+
       template <typename I, typename W, typename A>
       struct snake_2d_functor
       {
@@ -232,45 +241,234 @@
       };
 
 
+
+      // Functor (fastest version).
+
+      template <typename I, typename W, typename A>
+      struct snake_2d_fastest_functor
+      {
+	typedef snake_2d_fastest_functor<I,W,A> self;
+	typedef void (self::*move_fun)();
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+
+	window2d
+	win_left_fwd,
+	  win_right_fwd,
+	  win_left_bkd,
+	  win_right_bkd,
+	  win_bot_up,
+	  win_top_up,
+	  win_bot_down,
+	  win_top_down;
+
+	mln_qixter(const I, window2d)
+	q_l_fwd,
+	  q_r_fwd,
+	  q_l_bkd,
+	  q_r_bkd,
+	  q_top_up,
+	  q_bot_up,
+	  q_top_down,
+	  q_bot_down;
+
+
+	std::vector<move_fun> moves;
+	std::vector<dpsite> dps;
+
+	snake_2d_fastest_functor(const I& input, const W& win)
+	  : input(input),
+	    win(win),
+	    accu(),
+
+	    win_left_fwd(win::shift(win, mln::left) - win),
+	    win_right_fwd(win - win::shift(win, mln::left)),
+	    win_left_bkd(win::shift(win_left_fwd, mln::right)),
+	    win_right_bkd(win::shift(win_right_fwd, mln::right)),
+
+	    win_bot_up(win::shift(win, mln::down) - win),
+	    win_top_up(win - win::shift(win, mln::down)),
+	    win_bot_down(win::shift(win_bot_up, mln::up)),
+	    win_top_down(win::shift(win_top_up, mln::up)),
+
+	    q_l_fwd(input, win_left_fwd, p),
+	    q_r_fwd(input, win_right_fwd, p),
+	    q_l_bkd(input, win_left_bkd, p),
+	    q_r_bkd(input, win_right_bkd, p),
+
+	    q_top_up(input, win_top_up, p),
+	    q_bot_up(input, win_bot_up, p),
+	    q_top_down(input, win_top_down, p),
+	    q_bot_down(input, win_bot_down, p),
+
+	    moves(3),
+	    dps(3)
+	{
+	  if (win_bot_up.size()   + win_top_up.size() +
+	      win_bot_down.size() + win_top_down.size() <
+	      win_left_fwd.size() + win_right_fwd.size() +
+	      win_left_bkd.size() + win_right_bkd.size())
+	  {
+	    // Vertical snake
+	    dps[0] = mln::right;
+	    dps[1] = mln::down;
+	    dps[2] = mln::up;
+	    moves[0] = &self::right;
+	    moves[1] = &self::down;
+	    moves[2] = &self::up;
+	  }
+	  else
+	  {
+	    // Horizontal snake
+	    dps[0] = mln::down;
+	    dps[1] = mln::right;
+	    dps[2] = mln::left;
+	    moves[0] = &self::down;
+	    moves[1] = &self::right;
+	    moves[2] = &self::left;
+	  }
+	}
+
+	void init()
+	{
+	  // extension::adjust_fill is performed in the routine
+	  // because it has to be done before the initialization of
+	  // the fast iterators (q_*).
+	  initialize(output, input);
+	  accu.init();
+	  p = input.domain().pmin() - dps[0];
+	  mln_qixter(const I, W) q(input, win, p);
+	  for_all(q)
+	    accu.take(q.val());
+	  p = input.domain().pmin();
+	}
+
+	void right()
+	{
+	  for_all(q_l_fwd)
+	    accu.untake(q_l_fwd.val());
+	  for_all(q_r_fwd)
+	    accu.take(q_r_fwd.val());
+	  output(p) = accu;
+	}
+
+	void left()
+	{
+	  for_all(q_r_bkd)
+	    accu.untake(q_r_bkd.val());
+	  for_all(q_l_bkd)
+	    accu.take(q_l_bkd.val());
+	  output(p) = accu;
+	}
+
+	void down()
+	{
+	  for_all(q_top_down)
+	    accu.untake(q_top_down.val());
+	  for_all(q_bot_down)
+	    accu.take(q_bot_down.val());
+	  output(p) = accu;
+	}
+
+	void up()
+	{
+	  for_all(q_bot_up)
+	    accu.untake(q_bot_up.val());
+	  for_all(q_top_up)
+	    accu.take(q_top_up.val());
+	  output(p) = accu;
+	}
+
+      };
+
+
+      // Both dispatch and implementation (hum...)
+
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      snake_2d_dispatch(trait::image::speed::any,
+			const Accumulator<A>& /* FIXME a */,
+			const Image<I>& input, const Window<W>& win)
+      {
+	typedef snake_2d_functor<I, W, A> F;
+	F f(exact(input), exact(win));  // FIXME: Pass a to f.
+	canvas::browsing::snake_generic(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      snake_2d_dispatch(trait::image::speed::fastest,
+			const Accumulator<A>& /* FIXME a*/,
+			const Image<I>& input, const Window<W>& win)
+      {
+	typedef snake_2d_fastest_functor<I, W, A> F;
+	F f(exact(input), exact(win));  // FIXME: Pass a to f.
+	canvas::browsing::snake_generic(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      snake_2d_dispatch(const Accumulator<A>& a,
+			const Image<I>& input, const Window<W>& win)
+      {
+	return snake_2d_dispatch(mln_trait_image_speed(I)(),
+				 a, input, win);
+      }
+
     } // end of namespace mln::accu::internal
 
 
 
+
     template <typename A, typename I, typename W>
     inline
     mln_ch_value(I, mln_result(A))
-      snake_2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win)
+    snake_2d(const Accumulator<A>& a,
+	     const Image<I>& input, const Window<W>& win)
     {
       trace::entering("accu::snake_2d");
 
       internal::snake_2d_tests(input, win);
 
-      extension::adjust(input, win);
-      internal::snake_2d_functor<I, W, A> f(input, win);
-      canvas::browsing::snake_generic(f);
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A)) output;
+      output = internal::snake_2d_dispatch(a, input, win);
 
       trace::exiting("accu::snake_2d");
-      return f.output;
+      return output;
     }
 
 
     template <typename A, typename I, typename W>
     inline
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-      snake_2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win)
+    snake_2d(const Meta_Accumulator<A>& a,
+	     const Image<I>& input, const Window<W>& win)
     {
       trace::entering("accu::snake_2d");
 
       internal::snake_2d_tests(input, win);
 
       typedef mln_accu_with(A, mln_value(I)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_value(I)());
 
-      extension::adjust(input, win);
-      internal::snake_2d_functor<I, W, A_> f(input, win);
-      canvas::browsing::snake_generic(f);
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A_)) output;
+      output = internal::snake_2d_dispatch(a_, input, win);
 
       trace::exiting("accu::snake_2d");
-      return f.output;
+      return output;
     }
 
 
Index: mln/accu/transform_directional.hh
--- mln/accu/transform_directional.hh	(revision 0)
+++ mln/accu/transform_directional.hh	(revision 0)
@@ -0,0 +1,347 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
+# define MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
+
+/// \file mln/accu/transform_directional.hh
+///
+/// Run an accumulator over a particular direction.
+///
+/// \todo Split dispatch and impl.
+///
+/// \todo Pass the accumulator to the function-object.
+
+
+#include <mln/core/concept/image.hh>
+#include <mln/core/concept/meta_accumulator.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/win/diff.hh>
+#include <mln/win/shift.hh>
+#include <mln/geom/delta.hh>
+#include <mln/literal/zero.hh>
+#include <mln/extension/adjust.hh>
+#include <mln/canvas/browsing/directional.hh>
+
+
+
+namespace mln
+{
+
+  namespace accu
+  {
+
+
+    template <typename A, typename I, typename W>
+    mln_ch_value(I, mln_result(A))
+    transform_directional(const Accumulator<A>&,
+			  const Image<I>& input, const Window<W>& win,
+			  unsigned dir);
+
+
+    template <typename A, typename I, typename W>
+    mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+    transform_directional(const Meta_Accumulator<A>&,
+			  const Image<I>& input, const Window<W>& win,
+			  unsigned dir);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace internal
+    {
+
+
+      // Tests.
+
+
+      template <typename I, typename W>
+      void transform_directional_tests(const Image<I>& input_, const Window<W>& win_)
+      {
+	const I& input = exact(input_);
+	const W& win   = exact(win_);
+
+	mln_precondition(input.has_data());
+	mln_precondition(! win.is_empty());
+	// mln_precondition(! win.is_valid());
+
+	(void) input;
+	(void) win;
+      }
+
+
+
+      // Utility.
+
+
+      template <typename Dp>
+      Dp dp_directional(int dir)
+      {
+	Dp dp = literal::zero;
+	dp[dir] = 1;
+	return dp;
+      }
+
+
+
+      // Functor.
+
+
+      template <typename I_, typename W, typename A>
+      struct directional_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+	enum { dim = I::site::dim };
+
+	mln_psite(I) p;
+	unsigned dir;
+
+	window2d
+	win_left,
+	  win_right;
+
+	mln_qiter(window2d)
+	q_l,
+	  q_r;
+
+	directional_functor(const I& input, const W& win, int dir)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
+	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
+	    q_l(win_left, p),
+	    q_r(win_right, p)
+	{
+
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void init_run()
+	{
+	  accu.init();
+	  p[dir]--;
+	  mln_qiter(W) q(win, p);
+	  for_all(q) if (input.has(q))
+	    accu.take(input(q));
+	  p[dir]++;
+	}
+
+	void next()
+	{
+	  for_all(q_l) if (input.has(q_l))
+	    accu.untake(input(q_l));
+	  for_all(q_r) if (input.has(q_r))
+	    accu.take(input(q_r));
+	  output(p) = accu;
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+
+      // Functor (fastest version).
+
+
+      template <typename I_, typename W, typename A>
+      struct directional_fastest_functor
+      {
+	typedef I_ I;
+	typedef mln_deduce(I, psite, delta) dpsite;
+
+	const I& input;
+	const W& win;
+	mln_concrete(I) output;
+	A accu;
+
+	mln_psite(I) p;
+	enum { dim = I::site::dim };
+	unsigned dir;
+
+	window2d win_left, win_right;
+
+	mln_qixter(const I, window2d) q_l, q_r;
+
+	directional_fastest_functor(const I& input, const W& win, unsigned dir)
+	  : input(input),
+	    win(win),
+	    accu(),
+	    dir(dir),
+	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
+	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
+	    q_l(input, win_left, p),
+	    q_r(input, win_right, p)
+	{
+	}
+
+	void init()
+	{
+	  initialize(output, input);
+	}
+
+	void next()
+	{
+	  for_all(q_l)
+	    accu.untake(q_l.val());
+	  for_all(q_r)
+	    accu.take(q_r.val());
+	  output(p) = accu;
+	}
+
+
+	void init_run()
+	{
+	  accu.init();
+	  p[dir]--;
+	  mln_qixter(const I, W) q(input, win, p);
+	  for_all(q)
+	    accu.take(q.val());
+	  p[dir]++;
+	}
+
+	void final()
+	{
+	}
+
+      };
+
+
+
+
+      // Both dispatch and implementation (hum...)
+
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_directional_dispatch(trait::image::speed::any,
+				     const Accumulator<A>& /* FIXME a */,
+				     const Image<I>& input, const Window<W>& win,
+				     unsigned dir)
+      {
+	typedef directional_functor<I, W, A> F;
+	F f(exact(input), exact(win), dir); // FIXME: Pass a to f.
+	canvas::browsing::directional(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_directional_dispatch(trait::image::speed::fastest,
+				     const Accumulator<A>& /* FIXME a*/,
+				     const Image<I>& input, const Window<W>& win,
+				     unsigned dir)
+      {
+	typedef directional_fastest_functor<I, W, A> F;
+	F f(exact(input), exact(win), dir); // FIXME: Pass a to f.
+	canvas::browsing::directional(f);
+	return f.output;
+      }
+      
+      template <typename A, typename I, typename W>
+      inline
+      mln_ch_value(I, mln_result(A))
+      transform_directional_dispatch(const Accumulator<A>& a,
+				     const Image<I>& input, const Window<W>& win,
+				     unsigned dir)
+      {
+	return transform_directional_dispatch(mln_trait_image_speed(I)(),
+					      a, input, win, dir);
+      }
+
+    } // end of namespace mln::accu::internal
+
+
+
+
+    template <typename A, typename I, typename W>
+    inline
+    mln_ch_value(I, mln_result(A))
+    transform_directional(const Accumulator<A>& a,
+			  const Image<I>& input, const Window<W>& win,
+			  unsigned dir)
+    {
+      trace::entering("accu::transform_directional");
+
+      internal::transform_directional_tests(input, win);
+
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A)) output;
+      output = internal::transform_directional_dispatch(a, input, win, dir);
+
+      trace::exiting("accu::transform_directional");
+      return output;
+    }
+
+
+    template <typename A, typename I, typename W>
+    inline
+    mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
+    transform_directional(const Meta_Accumulator<A>& a,
+			  const Image<I>& input, const Window<W>& win,
+			  unsigned dir)
+    {
+      trace::entering("accu::transform_directional");
+
+      internal::transform_directional_tests(input, win);
+
+      typedef mln_accu_with(A, mln_value(I)) A_;
+      A_ a_ = accu::unmeta(exact(a), mln_value(I)());
+
+      extension::adjust(input, geom::delta(win) + 1);
+      mln_ch_value(I, mln_result(A_)) output;
+      output = internal::transform_directional_dispatch(a_, input, win, dir);
+
+      trace::exiting("accu::transform_directional");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
Index: mln/morpho/erosion.spe.hh
--- mln/morpho/erosion.spe.hh	(revision 2879)
+++ mln/morpho/erosion.spe.hh	(working copy)
@@ -95,37 +95,8 @@
 	erosion_on_set(const Image<I>& input_, const Window<W>& win_);
       }
 
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_on_set_fastest(const Image<I>& input_, const Window<W>& win_)
-      {
-	trace::entering("morpho::impl::erosion_on_set_fastest");
-
-	typedef mln_concrete(I) O;
-	const I& input = exact(input_);
-	const W& win = exact(win_);
-
-	extension::adjust_fill(input, win, true);
-
-	O output;
-	initialize(output, input);
-
-	mln_pixter(const I) p(input);
-	mln_pixter(O) p_out(output);
-	mln_qixter(const I, W) q(p, win);
-	for_all_2(p, p_out)
-	{
-	  for_all(q)
-	    if (q.val() == false)
-	      break;
-	  p_out.val() = ! q.is_valid();
-	}
-
-	trace::exiting("morpho::impl::erosion_on_set_fastest");
-
-	return output;
-      }
 
+      // On set with centered window.
 
       template <typename I, typename W>
       mln_concrete(I)
@@ -189,6 +160,7 @@
       }
 
 
+
       template <typename I, typename G, unsigned Dir, typename C>
       inline
       mln_concrete(I)
@@ -277,313 +249,7 @@
 	return output;
       }
 
-      template <typename I, typename W, typename A>
-      struct erosion_arbitrary_2d_fastest_functor
-      {
-	typedef erosion_arbitrary_2d_fastest_functor<I,W,A> self;
-	typedef void (self::*move_fun)();
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-
-	window2d
-	win_left_fwd,
-	  win_right_fwd,
-	  win_left_bkd,
-	  win_right_bkd,
-	  win_bot_up,
-	  win_top_up,
-	  win_bot_down,
-	  win_top_down;
-
-	mln_qixter(const I, window2d)
-	q_l_fwd,
-	  q_r_fwd,
-	  q_l_bkd,
-	  q_r_bkd,
-	  q_top_up,
-	  q_bot_up,
-	  q_top_down,
-	  q_bot_down;
-
-
-	std::vector<move_fun> moves;
-	std::vector<dpsite> dps;
-
-	erosion_arbitrary_2d_fastest_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-
-	    win_left_fwd(win::shift(win, mln::left) - win),
-	    win_right_fwd(win - win::shift(win, mln::left)),
-	    win_left_bkd(win::shift(win_left_fwd, mln::right)),
-	    win_right_bkd(win::shift(win_right_fwd, mln::right)),
-
-	    win_bot_up(win::shift(win, mln::down) - win),
-	    win_top_up(win - win::shift(win, mln::down)),
-	    win_bot_down(win::shift(win_bot_up, mln::up)),
-	    win_top_down(win::shift(win_top_up, mln::up)),
-
-	    q_l_fwd(input, win_left_fwd, p),
-	    q_r_fwd(input, win_right_fwd, p),
-	    q_l_bkd(input, win_left_bkd, p),
-	    q_r_bkd(input, win_right_bkd, p),
-
-	    q_top_up(input, win_top_up, p),
-	    q_bot_up(input, win_bot_up, p),
-	    q_top_down(input, win_top_down, p),
-	    q_bot_down(input, win_bot_down, p),
-
-	    moves(3),
-	    dps(3)
-	{
-	  if (win_bot_up.size()   + win_top_up.size() +
-	      win_bot_down.size() + win_top_down.size() <
-	      win_left_fwd.size() + win_right_fwd.size() +
-	      win_left_bkd.size() + win_right_bkd.size())
-	  {
-	    // Vertical snake
-	    dps[0] = mln::right;
-	    dps[1] = mln::down;
-	    dps[2] = mln::up;
-	    moves[0] = &self::right;
-	    moves[1] = &self::down;
-	    moves[2] = &self::up;
-	  }
-	  else
-	  {
-	    // Horizontal snake
-	    dps[0] = mln::down;
-	    dps[1] = mln::right;
-	    dps[2] = mln::left;
-	    moves[0] = &self::down;
-	    moves[1] = &self::right;
-	    moves[2] = &self::left;
-	  }
-	}
-
-	void init()
-	{
-	  // extension::adjust_fill is performed in the routine
-	  // because it has to be done before the initialization of
-	  // the fast iterators (q_*).
-	  initialize(output, input);
-	  accu.init();
-	  p = input.domain().pmin() - dps[0];
-	  mln_qixter(const I, W) q(input, win, p);
-	  for_all(q)
-	    accu.take(q.val());
-	  p = input.domain().pmin();
-	}
-
-	void right()
-	{
-	  for_all(q_l_fwd)
-	    accu.untake(q_l_fwd.val());
-	  for_all(q_r_fwd)
-	    accu.take(q_r_fwd.val());
-	  output(p) = accu;
-	}
-
-	void left()
-	{
-	  for_all(q_r_bkd)
-	    accu.untake(q_r_bkd.val());
-	  for_all(q_l_bkd)
-	    accu.take(q_l_bkd.val());
-	  output(p) = accu;
-	}
-
-	void down()
-	{
-	  for_all(q_top_down)
-	    accu.untake(q_top_down.val());
-	  for_all(q_bot_down)
-	    accu.take(q_bot_down.val());
-	  output(p) = accu;
-	}
-
-	void up()
-	{
-	  for_all(q_bot_up)
-	    accu.untake(q_bot_up.val());
-	  for_all(q_top_up)
-	    accu.take(q_top_up.val());
-	  output(p) = accu;
-	}
 
-      };
-
-      template <typename I, typename W>
-      inline
-      mln_concrete(I)
-      erosion_arbitrary_2d_fastest(const Image<I>& input, const Window<W>& win)
-      {
-	trace::entering("morpho::impl:erosion_arbitrary_2d_fastest");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
-	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
-
-	extension::adjust_fill(input,
-			       geom::delta(win) + 1,
-			       A());
-
-	typedef erosion_arbitrary_2d_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win));
-	canvas::browsing::snake_generic(f);
-
-	trace::exiting("morpho::impl:erosion_arbitrary_2d_fastest");
-
-	return f.output;
-      }
-
-
-      template <typename I, typename W, typename A>
-      struct erosion_arbitrary_2d_functor
-      {
-	typedef erosion_arbitrary_2d_functor<I,W, A> self;
-	typedef void (self::*move_fun)();
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-
-	window2d
-	win_left_fwd,
-	  win_right_fwd,
-	  win_left_bkd,
-	  win_right_bkd,
-	  win_bot_up,
-	  win_top_up,
-	  win_bot_down,
-	  win_top_down;
-
-	mln_qiter(window2d)
-	q_l_fwd,
-	  q_r_fwd,
-	  q_l_bkd,
-	  q_r_bkd,
-	  q_top_up,
-	  q_bot_up,
-	  q_top_down,
-	  q_bot_down;
-
-	std::vector<move_fun> moves;
-	std::vector<dpsite> dps;
-
-	erosion_arbitrary_2d_functor(const I& input, const W& win)
-	  : input(input),
-	    win(win),
-	    accu(),
-
-	    win_left_fwd(win::shift(win, mln::left) - win),
-	    win_right_fwd(win - win::shift(win, mln::left)),
-	    win_left_bkd(win::shift(win_left_fwd, mln::right)),
-	    win_right_bkd(win::shift(win_right_fwd, mln::right)),
-
-	    win_bot_up(win::shift(win, mln::down) - win),
-	    win_top_up(win - win::shift(win, mln::down)),
-	    win_bot_down(win::shift(win_bot_up, mln::up)),
-	    win_top_down(win::shift(win_top_up, mln::up)),
-
-	    q_l_fwd(win_left_fwd, p),
-	    q_r_fwd(win_right_fwd, p),
-	    q_l_bkd(win_left_bkd, p),
-	    q_r_bkd(win_right_bkd, p),
-
-	    q_top_up(win_top_up, p),
-	    q_bot_up(win_bot_up, p),
-	    q_top_down(win_top_down, p),
-	    q_bot_down(win_bot_down, p),
-
-	    moves(3),
-	    dps(3)
-	{
-	  if (win_bot_up.size()   + win_top_up.size() +
-	      win_bot_down.size() + win_top_down.size() <
-	      win_left_fwd.size() + win_right_fwd.size() +
-	      win_left_bkd.size() + win_right_bkd.size())
-	  {
-	    // Vertical snake
-	    dps[0] = mln::right;
-	    dps[1] = mln::down;
-	    dps[2] = mln::up;
-	    moves[0] = &self::right;
-	    moves[1] = &self::down;
-	    moves[2] = &self::up;
-	  }
-	  else
-	  {
-	    // Horizontal snake
-	    dps[0] = mln::down;
-	    dps[1] = mln::right;
-	    dps[2] = mln::left;
-	    moves[0] = &self::down;
-	    moves[1] = &self::right;
-	    moves[2] = &self::left;
-	  }
-	}
-
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	  accu.init();
-	  p = input.domain().pmin() - dps[0];
-	  mln_qiter(W) q(win, p);
-	  for_all(q)
-	    accu.take(input(q));
-	  p = input.domain().pmin();
-	}
-
-	void right()
-	{
-	  for_all(q_l_fwd)
-	    accu.untake(input(q_l_fwd));
-	  for_all(q_r_fwd)
-	    accu.take(input(q_r_fwd));
-	  output(p) = accu;
-	}
-
-	void left()
-	{
-	  for_all(q_r_bkd)
-	    accu.untake(input(q_r_bkd));
-	  for_all(q_l_bkd)
-	    accu.take(input(q_l_bkd));
-	  output(p) = accu;
-	}
-
-	void down()
-	{
-	  for_all(q_top_down)
-	    accu.untake(input(q_top_down));
-	  for_all(q_bot_down)
-	    accu.take(input(q_bot_down));
-	  output(p) = accu;
-	}
-
-	void up()
-	{
-	  for_all(q_bot_up)
-	    accu.untake(input(q_bot_up));
-	  for_all(q_top_up)
-	    accu.take(input(q_top_up));
-	  output(p) = accu;
-	}
-
-      };
 
       template <typename I, typename W>
       inline
@@ -592,203 +258,39 @@
       {
 	trace::entering("morpho::impl:erosion_arbitrary_2d");
 
-	typedef erosion_arbitrary_2d_functor<I, W, accu::min_h<mln_value(I)> > F;
-	F f(exact(input), exact(win));
-	canvas::browsing::snake_generic(f);
-
-	trace::exiting("morpho::impl:erosion_arbitrary_2d");
-
-	return f.output;
-      }
-
-
-      template <typename Dp>
-      Dp dp_directional(int dir)
-      {
-	Dp dp = literal::zero;
-	dp[dir] = 1;
-	return dp;
-      }
-
-      template <typename I_, typename W, typename A>
-      struct erosion_directional_nd_functor
-      {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-	enum { dim = I::site::dim };
-
-	mln_psite(I) p;
-	unsigned dir;
-
-	window2d
-	win_left,
-	  win_right;
-
-	mln_qiter(window2d)
-	q_l,
-	  q_r;
-
-	erosion_directional_nd_functor(const I& input, const W& win, int dir)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
-	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
-	    q_l(win_left, p),
-	    q_r(win_right, p)
-	{
-
-	}
-
-	void init()
-	{
-	  extension::adjust_fill(input, win, accu);
-	  initialize(output, input);
-	}
-
-	void init_run()
-	{
-	  accu.init();
-	  p[dir]--;
-	  mln_qiter(W) q(win, p);
-	  for_all(q) if (input.has(q))
-	    accu.take(input(q));
-	  p[dir]++;
-	}
-
-	void next()
-	{
-	  for_all(q_l) if (input.has(q_l))
-	    accu.untake(input(q_l));
-	  for_all(q_r) if (input.has(q_r))
-	    accu.take(input(q_r));
-	  output(p) = accu;
-	}
-
-	void final()
-	{
-	}
-
-      };
-
-      template <typename I, typename W>
-      inline
-      mln_concrete(I)
-      erosion_directional_nd(const Image<I>& input, const Window<W>& win, unsigned dir)
-      {
-	trace::entering("morpho::impl:erosion_directional_nd");
-
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
+	typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
 	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
+	A a;
 
-	typedef erosion_directional_nd_functor<I, W, A> F;
-	F f(exact(input), exact(win), dir);
-	canvas::browsing::directional(f);
-
-	trace::exiting("morpho::impl:erosion_directional_nd");
-
-	return f.output;
-      }
-
-
-      template <typename I_, typename W, typename A>
-      struct erosion_directional_nd_fastest_functor
-      {
-	typedef I_ I;
-	typedef mln_deduce(I, psite, delta) dpsite;
-
-	const I& input;
-	const W& win;
-	mln_concrete(I) output;
-	A accu;
-
-	mln_psite(I) p;
-	enum { dim = I::site::dim };
-	unsigned dir;
-
-	window2d win_left, win_right;
-
-	mln_qixter(const I, window2d) q_l, q_r;
-
-	erosion_directional_nd_fastest_functor(const I& input, const W& win, unsigned dir)
-	  : input(input),
-	    win(win),
-	    accu(),
-	    dir(dir),
-	    win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
-	    win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
-	    q_l(input, win_left, p),
-	    q_r(input, win_right, p)
-	{
-	}
-
-	void init()
-	{
-	  // extension::adjust_fill is performed in the routine
-	  // because it has to be done before the initialization of
-	  // the fast iterators (q_l and q_r).
-	  initialize(output, input);
-	}
-
-	void next()
-	{
-	  for_all(q_l)
-	    accu.untake(q_l.val());
-	  for_all(q_r)
-	    accu.take(q_r.val());
-	  output(p) = accu;
-	}
-
+	extension::adjust_fill(input, geom::delta(win) + 1, a);
+	mln_concrete(I) output = accu::snake_2d(a, input, win);
 
-	void init_run()
-	{
-	  accu.init();
-	  p[dir]--;
-	  mln_qixter(const I, W) q(input, win, p);
-	  for_all(q)
-	    accu.take(q.val());
-	  p[dir]++;
-	}
-
-	void final()
-	{
+	trace::exiting("morpho::impl:erosion_arbitrary_2d");
+	return output;
 	}
 
-      };
 
 
       template <typename I, typename W>
       inline
       mln_concrete(I)
-      erosion_directional_nd_fastest(const Image<I>& input, const Window<W>& win, unsigned dir)
+      erosion_directional(const Image<I>& input, const Window<W>& win, unsigned dir)
       {
-	trace::entering("morpho::impl:erosion_directional_nd_fastest");
+	trace::entering("morpho::impl:erosion_directional");
 
-	typedef mlc_is(mln_trait_image_kind(I),
-		       trait::image::kind::binary) is_binary;
+	typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
 	typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
+	A a;
 
-	extension::adjust_fill(input,
-			       geom::delta(win) + 1,
-			       A());
-
-	typedef erosion_directional_nd_fastest_functor<I, W, A> F;
-	F f(exact(input), exact(win), dir);
-	canvas::browsing::directional(f);
-
-	trace::exiting("morpho::impl:erosion_directional_nd_fastest");
+	extension::adjust_fill(input, geom::delta(win) + 1, a);
+	mln_concrete(I) output = accu::transform_directional(a, input, win, dir);
 
-	return f.output;
+	trace::exiting("morpho::impl:erosion_directional");
+	return output;
       }
 
 
+
       // Diagonal2d non fastest.
       template <typename I_, typename W, typename A>
       struct erosion_diagonal2d_functor
@@ -1172,68 +674,6 @@
       }
 
 
-      // dispatch for arbitrary elements
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_arbitrary(trait::image::speed::fastest,
-				     const I& input, const W& win)
-      {
-	return impl::erosion_arbitrary_2d_fastest(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_arbitrary(trait::image::speed::any,
-				     const I& input, const W& win)
-      {
-	return impl::erosion_arbitrary_2d(input, win);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_arbitrary(const I& input, const W& win)
-      {
-	trace::entering("morpho::erosion_dispatch_for_arbitrary");
-	mln_concrete(I) ima =
-	  erosion_dispatch_for_arbitrary(mln_trait_image_speed(I)(),
-					 input, win);
-	trace::exiting("morpho::erosion_dispatch_for_arbitrary");
-	return ima;
-      }
-
-
-
-      // dispatch for directional_nd w.r.t. speed
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_directional(trait::image::speed::fastest,
-				       const I& input, const W& win, unsigned dir)
-      {
-	return impl::erosion_directional_nd_fastest(input, win, dir);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_directional(trait::image::speed::any,
-				       const I& input, const W& win, unsigned dir)
-      {
-	return impl::erosion_directional_nd(input, win, dir);
-      }
-
-      template <typename I, typename W>
-      mln_concrete(I)
-      erosion_dispatch_for_directional(const I& input, const W& win, unsigned dir)
-      {
-	trace::entering("morpho::erosion_dispatch_for_directional");
-	mln_concrete(I) ima =
-	  erosion_dispatch_for_directional(mln_trait_image_speed(I)(),
-					   input, win, dir);
-	trace::exiting("morpho::erosion_dispatch_for_directional");
-	return ima;
-      }
-
 
       // dispatch for diagonal2d w.r.t. speed
 
@@ -1305,7 +745,7 @@
       erosion_dispatch_wrt_arbitrary_win(metal::true_,
 					 const I& input, const W& win)
       {
-	return erosion_dispatch_for_arbitrary(input, win);
+	return morpho::impl::erosion_arbitrary_2d(input, win);
       }
 
       template <typename I, typename W>
@@ -1351,7 +791,7 @@
       erosion_dispatch_wrt_win(const I& input, const win::octagon2d& win)
       {
 	if (win.length() < 5)
-	  return erosion_dispatch_for_arbitrary(input, win);
+	  return morpho::impl::erosion_arbitrary_2d(input, win);
 	else
 	  return impl::erosion_octagon2d(input, win);
       }
@@ -1365,7 +805,7 @@
       erosion_dispatch_wrt_win(metal::true_,
 			       const I& input, const win::hline2d& win)
       {
-	return erosion_dispatch_for_directional(input, win, 1);
+	return impl::erosion_directional(input, win, 1);
       }
 
       template <typename I>
@@ -1405,7 +845,7 @@
       erosion_dispatch_wrt_win(metal::true_,
 			       const I& input, const win::vline2d& win)
       {
-	return erosion_dispatch_for_directional(input, win, 0);
+	return impl::erosion_directional(input, win, 0);
       }
 
       template <typename I>
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh	(revision 2879)
+++ mln/morpho/includes.hh	(working copy)
@@ -51,8 +51,10 @@
 # include <mln/accu/max_h.hh>
 # include <mln/accu/rank.hh>
 
+# include <mln/accu/snake_2d.hh>
 # include <mln/accu/transform.hh>
 # include <mln/accu/transform_stop.hh>
+# include <mln/accu/transform_directional.hh>
 
 # include <mln/fun/v2v/saturate.hh>
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Maxime van Noppen <yabo(a)lrde.epita.fr>
To: transformers-patches(a)lrde.epita.fr, olena-patches(a)lrde.epita.fr
Subject: scool r130: Fix verbatim C++
  URL: https://svn.lrde.epita.fr/svn/scool/branches/scool-ng
ChangeLog:
2008-11-14  Maxime van Noppen  <yabo(a)lrde.epita.fr>
	Fix verbatim C++.
	* pp-cxx/CxxStm.str: Add a semicolon when verbatim C++ is used as an
	* expression.
	* scl-syn/Expression.sdf: Verbatim C++ may be an expression.
	* scl-syn/Lexical.sdf: Fix regexp.
	* scl-syn/Statement.sdf: Add a semicolon after verbatim C++ blocks
	* to be coherent with the other statements syntax.
	* scoolt/Expression.str: Handle verbatim C++ when used as an expression.
	* scoolt/Statement.str: F.
---
 pp-cxx/CxxStm.str      |    2 +-
 scl-syn/Expression.sdf |    2 ++
 scl-syn/Lexical.sdf    |    2 +-
 scl-syn/Statement.sdf  |    4 ++--
 scoolt/Expression.str  |    3 +++
 scoolt/Statement.str   |    2 +-
 6 files changed, 10 insertions(+), 5 deletions(-)
Index: branches/scool-ng/src/pp-cxx/CxxStm.str
===================================================================
--- branches/scool-ng/src/pp-cxx/CxxStm.str	(revision 129)
+++ branches/scool-ng/src/pp-cxx/CxxStm.str	(revision 130)
@@ -5,7 +5,7 @@
 rules
 
   CxxStmToAbox:
-	CxxExpStm(e) -> H hs=0 [ ~<CxxExpToAbox> e ~<Semicolon> e]
+	CxxExpStm(e) -> H hs=0 [ ~<CxxExpToAbox> e ";"]
 
   // Don't add an extra ';' to verbatim C++ that we insert.
   // As said on https://trac.lrde.org/scool/wiki/SCOOL/Specs/Misc the C++ inserted
Index: branches/scool-ng/src/scoolt/Expression.str
===================================================================
--- branches/scool-ng/src/scoolt/Expression.str	(revision 129)
+++ branches/scool-ng/src/scoolt/Expression.str	(revision 130)
@@ -17,6 +17,9 @@
   BaseExpressionToCxx:
     Integer(int) -> CxxInt(int)
 
+  BaseExpressionToCxx:
+    Cxx(cxx_code) -> CxxProgram(cxx_code)
+
 
 
   ExpressionToCxx:
Index: branches/scool-ng/src/scoolt/Statement.str
===================================================================
--- branches/scool-ng/src/scoolt/Statement.str	(revision 129)
+++ branches/scool-ng/src/scoolt/Statement.str	(revision 130)
@@ -5,7 +5,7 @@
 rules
 
   RawCxx:
-    Cxx(cxx_code) -> CxxProgram(cxx_code)
+    CxxStatement(Cxx(cxx_code)) -> CxxProgram(cxx_code)
 
 strategies
 
Index: branches/scool-ng/src/scl-syn/Statement.sdf
===================================================================
--- branches/scool-ng/src/scl-syn/Statement.sdf	(revision 129)
+++ branches/scool-ng/src/scl-syn/Statement.sdf	(revision 130)
@@ -4,15 +4,15 @@
   Lexical Declaration Expression
 
 exports
-  sorts Statement FunctionStatement
+  sorts Statement FunctionStatement CxxStatement
   context-free syntax
 
 	Declaration		    -> Statement
 
-	Cxx			    -> CxxStatement
 	CxxStatement		    -> Statement
 	CxxStatement		    -> FunctionStatement
 
+	Cxx ";"			    -> CxxStatement {cons("CxxStatement")}
 	Expression ";"		    -> FunctionStatement  {cons("ExpressionStatement")}
 	SimpleDeclaration	    -> FunctionStatement
 	"->" Expression ";"	    -> FunctionStatement  {cons("ReturnStatement")}
Index: branches/scool-ng/src/scl-syn/Expression.sdf
===================================================================
--- branches/scool-ng/src/scl-syn/Expression.sdf	(revision 129)
+++ branches/scool-ng/src/scl-syn/Expression.sdf	(revision 130)
@@ -7,6 +7,8 @@
   sorts Expression StaticExpression StaticFunctionCall
   context-free syntax
 
+	Cxx						    -> Expression
+	Cxx						    -> StaticExpression
 	Id						    -> Expression		{cons("Identifier")}
 
 	Integer						    -> Expression		{cons("Integer")}
Index: branches/scool-ng/src/scl-syn/Lexical.sdf
===================================================================
--- branches/scool-ng/src/scl-syn/Lexical.sdf	(revision 129)
+++ branches/scool-ng/src/scl-syn/Lexical.sdf	(revision 130)
@@ -12,7 +12,7 @@
 	[A-Za-z][A-Za-z0-9\_]*	    -> Id
 	[0-9]+			    -> Integer		{cons("Integer")}
 	"\"" [A-Za-z0-9]* "\""	    -> String		{cons("String")}
-	~[\ ]~[\]\|]*~[\ ]	    -> RawCxx
+	~[\]\|]*		    -> RawCxx
 
 	"//" ~[\n]* [\n] -> LAYOUT
 	[\ \t\n] -> LAYOUT
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Maxime van Noppen <yabo(a)lrde.epita.fr>
To: transformers-patches(a)lrde.epita.fr, olena-patches(a)lrde.epita.fr
Subject: scool r129: Fix tests
  URL: https://svn.lrde.epita.fr/svn/scool/branches/scool-ng
ChangeLog:
2008-11-14  Maxime van Noppen  <yabo(a)lrde.epita.fr>
	Fix tests.
	* examples/c++_ast/point1d_simple.aterm: New.
	* examples/c++_ast/sample_1.aterm: New.
	* examples/c++_ast/sample_3.aterm: New.
	* examples/c++_ast/sample_4.aterm: New.
	* examples/c++_build/point1d_simple.g++: New.
	* examples/c++_build/sample_3.g++: New.
	* examples/c++_build/sample_4.g++: New.
	* examples/c++_src/point1d_simple.cc: New.
	* examples/c++_src/sample_1.cc: New.
	* examples/c++_src/sample_3.cc: New.
	* examples/c++_src/sample_4.cc: New.
	* examples/scool_ast/point1d_simple.aterm: New.
	* examples/scool_ast/sample_1.aterm: New.
	* examples/scool_ast/sample_3.aterm: New.
	* examples/scool_ast/sample_4.aterm: New.
	* examples/scool_ast/sample_animal_hierarchy.aterm: New.
	* examples/scool_src/point1d_simple.scl: .
	* examples/scool_src/sample_4.scl: .
	* examples/scool_src/sample_5.scl: Remove.
	* examples/scool_src/sample_animal_hierarchy.scl: .
	* function/scool_ast/call_003.aterm: .
	* function/scool_src/call_003.scl: .
	* type/c++_ast/typedef_001.aterm: New.
	* type/c++_build/typedef_001.g++: New.
	* type/c++_src/typedef_001.cc: New.
	* type/scool_ast/typedef_001.aterm: New.
	* variable/scool_ast/declaration_005.aterm: .
	* variable/scool_src/declaration_005.scl: .
---
 examples/c++_ast/point1d_simple.aterm            |    1 +
 examples/c++_ast/sample_1.aterm                  |    1 +
 examples/c++_ast/sample_3.aterm                  |    1 +
 examples/c++_ast/sample_4.aterm                  |    1 +
 examples/c++_src/point1d_simple.cc               |   16 ++++++++++++++++
 examples/c++_src/sample_1.cc                     |    7 +++++++
 examples/c++_src/sample_3.cc                     |    8 ++++++++
 examples/c++_src/sample_4.cc                     |    5 +++++
 examples/scool_ast/point1d_simple.aterm          |    1 +
 examples/scool_ast/sample_1.aterm                |    1 +
 examples/scool_ast/sample_3.aterm                |    1 +
 examples/scool_ast/sample_4.aterm                |    1 +
 examples/scool_ast/sample_animal_hierarchy.aterm |    1 +
 examples/scool_src/point1d_simple.scl            |    6 +++---
 examples/scool_src/sample_4.scl                  |    2 ++
 examples/scool_src/sample_animal_hierarchy.scl   |    2 +-
 function/scool_ast/call_003.aterm                |    2 +-
 function/scool_src/call_003.scl                  |    2 +-
 type/c++_ast/typedef_001.aterm                   |    1 +
 type/c++_src/typedef_001.cc                      |    1 +
 type/scool_ast/typedef_001.aterm                 |    1 +
 variable/scool_ast/declaration_005.aterm         |    2 +-
 variable/scool_src/declaration_005.scl           |    2 +-
 23 files changed, 58 insertions(+), 8 deletions(-)
Index: branches/scool-ng/tests/type/c++_ast/typedef_001.aterm
===================================================================
--- branches/scool-ng/tests/type/c++_ast/typedef_001.aterm	(revision 0)
+++ branches/scool-ng/tests/type/c++_ast/typedef_001.aterm	(revision 129)
@@ -0,0 +1 @@
+CxxProgram([CxxTypedef(CxxType("int"),CxxId("t"))])
Index: branches/scool-ng/tests/type/c++_src/typedef_001.cc
===================================================================
--- branches/scool-ng/tests/type/c++_src/typedef_001.cc	(revision 0)
+++ branches/scool-ng/tests/type/c++_src/typedef_001.cc	(revision 129)
@@ -0,0 +1 @@
+typedef int t;
Index: branches/scool-ng/tests/type/scool_ast/typedef_001.aterm
===================================================================
--- branches/scool-ng/tests/type/scool_ast/typedef_001.aterm	(revision 0)
+++ branches/scool-ng/tests/type/scool_ast/typedef_001.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([TypeDefinition(None,Identifier("t"),StaticInitialiser(SimpleType("int")))])
Index: branches/scool-ng/tests/type/c++_build/typedef_001.g++
===================================================================
Index: branches/scool-ng/tests/function/scool_ast/call_003.aterm
===================================================================
--- branches/scool-ng/tests/function/scool_ast/call_003.aterm	(revision 128)
+++ branches/scool-ng/tests/function/scool_ast/call_003.aterm	(revision 129)
@@ -1 +1 @@
-Program([Cxx("#include <string>\n\nusing std::string;\n"),FunctionDefinition(None,Identifier("doit"),FunctionType(None,ArgumentsDeclaration([TypedId(Identifier("s"),SimpleType("string")),TypedId(Identifier("i"),SimpleType("int"))]),SimpleType("void")),FunctionBlock([ExpressionStatement(FunctionCall(Identifier("doit"),None,Arguments([String("\"bar\""),Integer("42")])))]))])
+Program([CxxStatement(Cxx("#include <string>\n\nusing std::string;\n")),FunctionDefinition(None,Identifier("doit"),FunctionType(None,ArgumentsDeclaration([TypedId(Identifier("s"),SimpleType("string")),TypedId(Identifier("i"),SimpleType("int"))]),SimpleType("void")),FunctionBlock([ExpressionStatement(FunctionCall(Identifier("doit"),None,Arguments([String("\"bar\""),Integer("42")])))]))])
Index: branches/scool-ng/tests/function/scool_src/call_003.scl
===================================================================
--- branches/scool-ng/tests/function/scool_src/call_003.scl	(revision 128)
+++ branches/scool-ng/tests/function/scool_src/call_003.scl	(revision 129)
@@ -2,7 +2,7 @@
 #include <string>
 
 using std::string;
-]|
+]|;
 
 doit : (s : string, i : int) -> void =
 {
Index: branches/scool-ng/tests/variable/scool_ast/declaration_005.aterm
===================================================================
--- branches/scool-ng/tests/variable/scool_ast/declaration_005.aterm	(revision 128)
+++ branches/scool-ng/tests/variable/scool_ast/declaration_005.aterm	(revision 129)
@@ -1 +1 @@
-Program([Cxx("#include <list>\n\nusing std::list;\n"),SimpleDeclaration(Some("var"),Identifier("l"),StaticFunctionCall(Identifier("list"),Parameters([SimpleType("int")])),None)])
+Program([CxxStatement(Cxx("#include <list>\n\nusing std::list;\n")),SimpleDeclaration(Some("var"),Identifier("l"),StaticFunctionCall(Identifier("list"),Parameters([SimpleType("int")])),None)])
Index: branches/scool-ng/tests/variable/scool_src/declaration_005.scl
===================================================================
--- branches/scool-ng/tests/variable/scool_src/declaration_005.scl	(revision 128)
+++ branches/scool-ng/tests/variable/scool_src/declaration_005.scl	(revision 129)
@@ -2,6 +2,6 @@
 #include <list>
 
 using std::list;
-]|
+]|;
 
 var l : list[int];
Index: branches/scool-ng/tests/examples/c++_ast/sample_1.aterm
===================================================================
--- branches/scool-ng/tests/examples/c++_ast/sample_1.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/c++_ast/sample_1.aterm	(revision 129)
@@ -0,0 +1 @@
+CxxProgram([CxxFun([],CxxType("void"),CxxId("f"),[],None,[CxxDecl(CxxConstType(CxxType("int")),CxxId("i"),CxxInt("3")),CxxExpStm(CxxAssign(CxxId("i"),CxxInt("4"))),CxxDecl(CxxType("int"),CxxId("j"),CxxInt("3")),CxxExpStm(CxxAssign(CxxId("j"),CxxInt("4")))])])
Index: branches/scool-ng/tests/examples/c++_ast/sample_3.aterm
===================================================================
--- branches/scool-ng/tests/examples/c++_ast/sample_3.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/c++_ast/sample_3.aterm	(revision 129)
@@ -0,0 +1 @@
+CxxProgram([CxxFun([],CxxType("void"),CxxId("f"),[],None,[CxxDecl(CxxType("int"),CxxId("i")),CxxDecl(CxxType("int"),CxxId("j")),CxxExpStm(CxxAssign(CxxId("i"),CxxInt("0"))),CxxExpStm(CxxAssign(CxxId("j"),CxxId("i"))),CxxExpStm(CxxAssign(CxxId("i"),CxxSum(CxxId("j"),CxxId("i"))))])])
Index: branches/scool-ng/tests/examples/c++_ast/sample_4.aterm
===================================================================
--- branches/scool-ng/tests/examples/c++_ast/sample_4.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/c++_ast/sample_4.aterm	(revision 129)
@@ -0,0 +1 @@
+CxxProgram([CxxProgram("#include <cmath>"),CxxFun([],CxxType("float"),CxxId("sqrt"),[(CxxType("float"),CxxId("arg"))],None,[CxxExpStm(CxxKeyword("return",CxxProgram("std::sqrt(arg) ")))])])
Index: branches/scool-ng/tests/examples/c++_ast/point1d_simple.aterm
===================================================================
--- branches/scool-ng/tests/examples/c++_ast/point1d_simple.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/c++_ast/point1d_simple.aterm	(revision 129)
@@ -0,0 +1 @@
+CxxProgram([CxxClassDecl([(CxxType("typename"),"Exact")],CxxId("point1d"),[],[CxxPublic([CxxTypedef(CxxType("int"),CxxId("point_type")),CxxFun([],CxxType("point_type"),CxxId("get_x"),[],Const,[CxxExpStm(CxxKeyword("return",CxxId("x_")))]),CxxFun([],CxxType("point_type"),CxxId("set_x"),[(CxxConstType(CxxRefType(CxxType("point_type"))),CxxId("x"))],None,[CxxExpStm(CxxKeyword("return",CxxAssign(CxxId("x_"),CxxId("x"))))])]),CxxPrivate([CxxDecl(CxxType("point_type"),CxxId("x_"))])])])
Index: branches/scool-ng/tests/examples/c++_src/sample_1.cc
===================================================================
--- branches/scool-ng/tests/examples/c++_src/sample_1.cc	(revision 0)
+++ branches/scool-ng/tests/examples/c++_src/sample_1.cc	(revision 129)
@@ -0,0 +1,7 @@
+void f()
+{
+  const int i = 3;
+  i = 4;
+  int j = 3;
+  j = 4;
+}
Index: branches/scool-ng/tests/examples/c++_src/sample_3.cc
===================================================================
--- branches/scool-ng/tests/examples/c++_src/sample_3.cc	(revision 0)
+++ branches/scool-ng/tests/examples/c++_src/sample_3.cc	(revision 129)
@@ -0,0 +1,8 @@
+void f()
+{
+  int i;
+  int j;
+  i = 0;
+  j = i;
+  i = j + i;
+}
Index: branches/scool-ng/tests/examples/c++_src/sample_4.cc
===================================================================
--- branches/scool-ng/tests/examples/c++_src/sample_4.cc	(revision 0)
+++ branches/scool-ng/tests/examples/c++_src/sample_4.cc	(revision 129)
@@ -0,0 +1,5 @@
+#include <cmath>
+float sqrt(float arg)
+{
+  return std::sqrt(arg) ;
+}
Index: branches/scool-ng/tests/examples/c++_src/point1d_simple.cc
===================================================================
--- branches/scool-ng/tests/examples/c++_src/point1d_simple.cc	(revision 0)
+++ branches/scool-ng/tests/examples/c++_src/point1d_simple.cc	(revision 129)
@@ -0,0 +1,16 @@
+template < typename Exact >
+class point1d
+{
+  public:
+    typedef int point_type;
+    point_type get_x() const
+    {
+      return x_;
+    }
+    point_type set_x(const point_type& x)
+    {
+      return x_ = x;
+    }
+  private:
+    point_type x_;
+};
Index: branches/scool-ng/tests/examples/scool_ast/sample_animal_hierarchy.aterm
===================================================================
--- branches/scool-ng/tests/examples/scool_ast/sample_animal_hierarchy.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/scool_ast/sample_animal_hierarchy.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([ClassDefinition(Identifier("Animal"),None,None,ClassBlock([AccessBlock(Public,[FunctionDeclaration(None,Identifier("scream"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("void")))])])),ClassDefinition(Identifier("Cat"),None,Some(ClassWhereClause([Inherits("Cat",SimpleType("Animal"))])),ClassBlock([AccessBlock(Public,[FunctionDefinition(None,Identifier("scream"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("void")),FunctionBlock([amb([ExpressionStatement(Cxx("std::cout << \"Miaou\" << std::endl; ")),CxxStatement(Cxx("std::cout << \"Miaou\" << std::endl; "))])]))])])),ClassDefinition(Identifier("Dog"),Some("final"),Some(ClassWhereClause([Inherits("Dog",SimpleType("Animal"))])),ClassBlock([AccessBlock(Public,[FunctionDefinition(None,Identifier("scream"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("void")),FunctionBlock([amb([ExpressionStatement(Cxx("std::cout << \"Wouf\" << std::endl; ")),CxxStatement(Cxx("std::cout << \"Wouf\" << std::endl; "))])]))])])),FunctionDefinition(None,Identifier("scream"),FunctionType(None,ArgumentsDeclaration([TypedId(Identifier("animal"),SimpleType("Animal"))]),SimpleType("void")),FunctionBlock([amb([ExpressionStatement(Cxx("animal.scream(); ")),CxxStatement(Cxx("animal.scream(); "))])])),FunctionDefinition(None,Identifier("main"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("int")),FunctionBlock([SimpleDeclaration(Some("var"),Identifier("cat"),SimpleType("Cat"),None),SimpleDeclaration(Some("var"),Identifier("dog"),SimpleType("Dog"),None),ExpressionStatement(FunctionCall(Identifier("scream"),None,Arguments([Identifier("cat")]))),ExpressionStatement(FunctionCall(Identifier("scream"),None,Arguments([Identifier("dog")]))),ReturnStatement(Integer("0"))]))])
Index: branches/scool-ng/tests/examples/scool_ast/sample_1.aterm
===================================================================
--- branches/scool-ng/tests/examples/scool_ast/sample_1.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/scool_ast/sample_1.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([FunctionDefinition(None,Identifier("f"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("void")),FunctionBlock([SimpleDeclaration(None,Identifier("i"),SimpleType("int"),Some(Initialiser(Integer("3")))),ExpressionStatement(Assign(Identifier("i"),Integer("4"))),SimpleDeclaration(Some("var"),Identifier("j"),SimpleType("int"),Some(Initialiser(Integer("3")))),ExpressionStatement(Assign(Identifier("j"),Integer("4")))]))])
Index: branches/scool-ng/tests/examples/scool_ast/sample_3.aterm
===================================================================
--- branches/scool-ng/tests/examples/scool_ast/sample_3.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/scool_ast/sample_3.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([FunctionDefinition(None,Identifier("f"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("void")),FunctionBlock([SimpleDeclaration(Some("var"),Identifier("i"),SimpleType("int"),None),SimpleDeclaration(Some("var"),Identifier("j"),SimpleType("int"),None),ExpressionStatement(Assign(Identifier("i"),Integer("0"))),ExpressionStatement(Assign(Identifier("j"),Identifier("i"))),ExpressionStatement(Assign(Identifier("i"),Sum(Identifier("j"),Identifier("i"))))]))])
Index: branches/scool-ng/tests/examples/scool_ast/sample_4.aterm
===================================================================
--- branches/scool-ng/tests/examples/scool_ast/sample_4.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/scool_ast/sample_4.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([CxxStatement(Cxx("#include <cmath>")),FunctionDefinition(None,Identifier("sqrt"),FunctionType(None,ArgumentsDeclaration([TypedId(Identifier("arg"),SimpleType("float"))]),SimpleType("float")),FunctionBlock([ReturnStatement(Cxx("std::sqrt(arg) "))]))])
Index: branches/scool-ng/tests/examples/scool_ast/point1d_simple.aterm
===================================================================
--- branches/scool-ng/tests/examples/scool_ast/point1d_simple.aterm	(revision 0)
+++ branches/scool-ng/tests/examples/scool_ast/point1d_simple.aterm	(revision 129)
@@ -0,0 +1 @@
+Program([ClassDefinition(Identifier("point1d"),None,None,ClassBlock([AccessBlock(Public,[TypeDefinition(None,Identifier("point_type"),StaticInitialiser(SimpleType("int"))),FunctionDefinition(None,Identifier("get_x"),FunctionType(None,ArgumentsDeclaration([]),SimpleType("point_type")),FunctionBlock(Identifier("x_"))),FunctionDefinition(Some("mutable"),Identifier("set_x"),FunctionType(None,ArgumentsDeclaration([TypedId(Identifier("x"),SimpleType("point_type"))]),SimpleType("point_type")),FunctionBlock(Assign(Identifier("x_"),Identifier("x"))))]),AccessBlock(Private,[SimpleDeclaration(Some("var"),Identifier("x_"),SimpleType("point_type"),None)])]))])
Index: branches/scool-ng/tests/examples/scool_src/sample_5.scl (deleted)
===================================================================
Index: branches/scool-ng/tests/examples/scool_src/sample_animal_hierarchy.scl
===================================================================
--- branches/scool-ng/tests/examples/scool_src/sample_animal_hierarchy.scl	(revision 128)
+++ branches/scool-ng/tests/examples/scool_src/sample_animal_hierarchy.scl	(revision 129)
@@ -14,7 +14,7 @@
   }
 }
 
-final Dog : class where Dog -> Animal =
+Dog : final class where Dog -> Animal =
 {
   public
   {
Index: branches/scool-ng/tests/examples/scool_src/sample_4.scl
===================================================================
--- branches/scool-ng/tests/examples/scool_src/sample_4.scl	(revision 128)
+++ branches/scool-ng/tests/examples/scool_src/sample_4.scl	(revision 129)
@@ -1,3 +1,5 @@
+|[#include <cmath>]|;
+
 sqrt : (arg : float) -> float =
 {
   -> |[ std::sqrt(arg) ]|;
Index: branches/scool-ng/tests/examples/scool_src/point1d_simple.scl
===================================================================
--- branches/scool-ng/tests/examples/scool_src/point1d_simple.scl	(revision 128)
+++ branches/scool-ng/tests/examples/scool_src/point1d_simple.scl	(revision 129)
@@ -4,12 +4,12 @@
   {
     point_type : type = int;
 
-    get_x : () -> point_type => x_;
-    mutable set_x : (x : point_type) -> point_type => x_ = x;
+    get_x : () -> point_type = x_;
+    mutable set_x : (x : point_type) -> point_type = x_ = x;
   }
 
   private
   {
-    var x : point_type;
+    var x_ : point_type;
   }
 }
Index: branches/scool-ng/tests/examples/c++_build/sample_4.g++
===================================================================
Index: branches/scool-ng/tests/examples/c++_build/point1d_simple.g++
===================================================================
Index: branches/scool-ng/tests/examples/c++_build/sample_3.g++
===================================================================
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            cleanup-2008 2879: Add accu transform stop and make	erosion rely on it.
                        
                        
by Thierry Geraud 14 Nov '08
                    by Thierry Geraud 14 Nov '08
14 Nov '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Add accu transform stop and make erosion rely on it.
	* mln/accu/land_basic.hh: New.
	* mln/accu/transform_stop.hh: New.
	* mln/accu/all.hh: Update.
	* mln/morpho/erosion.hh
	(erosion_on_set): Rely on accu::transform_stop.
	* mln/morpho/includes.hh: Update.
 accu/all.hh            |    8 ++++-
 accu/land_basic.hh     |   74 +++++++++++++++++++++++--------------------------
 accu/transform_stop.hh |   66 +++++++++++++++++++++++--------------------
 morpho/erosion.hh      |   19 +-----------
 morpho/includes.hh     |   14 +++++----
 5 files changed, 88 insertions(+), 93 deletions(-)
Index: mln/accu/all.hh
--- mln/accu/all.hh	(revision 2878)
+++ mln/accu/all.hh	(working copy)
@@ -58,7 +58,6 @@
 
 # include <mln/accu/bbox.hh>
 # include <mln/accu/count.hh>
-# include <mln/accu/convolve.hh>
 //# include <mln/accu/count_adjacent_vertices.hh>
 # include <mln/accu/height.hh>
 # include <mln/accu/histo.hh>
@@ -78,5 +77,12 @@
 # include <mln/accu/tuple.hh>
 # include <mln/accu/volume.hh>
 
+// Routines.
+
+# include <mln/accu/convolve.hh>
+# include <mln/accu/snake_2d.hh>
+# include <mln/accu/transform.hh>
+# include <mln/accu/transform_stop.hh>
+
 
 #endif // ! MLN_ACCU_ALL_HH
Index: mln/accu/land_basic.hh
--- mln/accu/land_basic.hh	(revision 2878)
+++ mln/accu/land_basic.hh	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,13 +26,12 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_ACCU_LAND_HH
-# define MLN_ACCU_LAND_HH
+#ifndef MLN_ACCU_LAND_BASIC_HH
+# define MLN_ACCU_LAND_BASIC_HH
 
-/// \file mln/accu/land.hh
-///
-/// Define a 'logical-and' accumulator.
+/// \file mln/accu/land_basic.hh
 ///
+/// Define a basic 'logical-and' accumulator.
 
 # include <mln/accu/internal/base.hh>
 
@@ -42,12 +42,14 @@
   namespace accu
   {
 
-    /// "Logical-and" accumulator class.
-    struct land : public mln::accu::internal::base< bool, land >
+    /// "Logical-and" accumulator class.  Conversely to accu::lands,
+    /// this version does not have the 'untake' method but features
+    /// the 'can_stop' method.
+    struct land_basic : public mln::accu::internal::base< bool, land_basic >
     {
       typedef bool argument;
 
-      land();
+      land_basic();
 
       /// Manipulators.
       /// \{
@@ -55,10 +57,7 @@
       void take_as_init(const argument& t);
 
       void take(const argument& t);
-      void take(const land& other);
-
-      void untake(const argument& t);
-      void untake(const land& other);
+      void take(const land_basic& other);
       /// \}
 
       /// Get the value of the accumulator.
@@ -68,73 +67,70 @@
       /// Always true here.
       bool is_valid() const;
 
+      /// Test if it is worth for this accumulator to take extra data.
+      /// If the result is already 'false' (because this accumulator
+      /// has already taken a 'false' value), can_stop returns true.
+      bool can_stop() const;
+
     protected:
-      unsigned nfalse_;
+      bool res_;
     };
 
 
 # ifndef MLN_INCLUDE_ONLY
 
     inline
-    land::land()
+    land_basic::land_basic()
     {
       init();
     }
 
     inline
     void
-    land::init()
+    land_basic::init()
     {
-      nfalse_ = 0;
+      res_ = true;
     }
 
     inline
-    void land::take_as_init(const argument& t)
+    void land_basic::take_as_init(const argument& t)
     {
-      nfalse_ = t ? 0 : 1;
+      res_ = t;
     }
 
     inline
-    void land::take(const argument& t)
+    void land_basic::take(const argument& t)
     {
-      if (t == false)
-	++nfalse_;
+      if (res_ == true && t == false)
+	res_ = false;
     }
 
     inline
     void
-    land::take(const land& other)
+    land_basic::take(const land_basic& other)
     {
-      nfalse_ += other.nfalse_;
+      res_ = res_ && other.res_;
     }
 
     inline
-    void land::untake(const argument& t)
-    {
-      if (t == false)
-	--nfalse_;
-    }
-
-    inline
-    void
-    land::untake(const land& other)
+    bool
+    land_basic::to_result() const
     {
-      mln_precondition(other.nfalse_ <= nfalse_);
-      nfalse_ -= other.nfalse_;
+      return res_;
     }
 
     inline
     bool
-    land::to_result() const
+    land_basic::is_valid() const
     {
-      return nfalse_ == 0;
+      return true;
     }
 
     inline
     bool
-    land::is_valid() const
+    land_basic::can_stop() const
     {
-      return true;
+      return res_ == false;
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Property changes on: mln/accu/land_basic.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/accu/transform_stop.hh
--- mln/accu/transform_stop.hh	(revision 2878)
+++ mln/accu/transform_stop.hh	(working copy)
@@ -25,12 +25,12 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_ACCU_TRANSFORM_HH
-# define MLN_ACCU_TRANSFORM_HH
+#ifndef MLN_ACCU_TRANSFORM_STOP_HH
+# define MLN_ACCU_TRANSFORM_STOP_HH
 
-/// \file mln/accu/transform.hh
+/// \file mln/accu/transform_stop.hh
 ///
-/// Transform an image by applying locally an accumulator on its
+/// Transform_Stop an image by applying locally an accumulator on its
 /// values.
 
 # include <mln/core/concept/meta_accumulator.hh>
@@ -47,15 +47,11 @@
 
     template <typename I, typename A, typename W>
     mln_ch_value(I, mln_result(A))
-      transform(const Image<I>& input, 
-		const Accumulator<A>& a,
-		const Window<W>& win);
+    transform_stop(const Image<I>& input, const Accumulator<A>& a, const Window<W>& win);
 
     template <typename I, typename A, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-      transform(const Image<I>& input, 
-		const Meta_Accumulator<A>& a,
-		const Window<W>& win);
+    transform_stop(const Image<I>& input, const Meta_Accumulator<A>& a, const Window<W>& win);
 
 
 
@@ -72,11 +68,11 @@
 	
 	template <typename I, typename A, typename W>
 	mln_ch_value(I, mln_result(A))
-	  transform(const Image<I>& input_,
+	  transform_stop(const Image<I>& input_,
 		    const Accumulator<A>& a_,
 		    const Window<W>& win_)
 	{
-	  trace::entering("accu::impl::generic::transform");
+	  trace::entering("accu::impl::generic::transform_stop");
 
 	  const I& input = exact(input_);
 	  const W& win   = exact(win_);
@@ -96,11 +92,15 @@
 	  {
 	    a.init();
 	    for_all(q)
+	    {
 	      a.take(input(q));
+	      if (a.can_stop())
+		break;
+	    }
 	    output(p) = a.to_result();
 	  }
 
-	  trace::exiting("accu::impl::generic::transform");
+	  trace::exiting("accu::impl::generic::transform_stop");
 	  return output;
 	}
 
@@ -111,9 +111,9 @@
 
       template <typename I, typename A, typename W>
       mln_ch_value(I, mln_result(A))
-      transform_fastest(const Image<I>& input_, const Accumulator<A>& a_, const Window<W>& win_)
+      transform_stop_fastest(const Image<I>& input_, const Accumulator<A>& a_, const Window<W>& win_)
       {
-	trace::entering("accu::impl::transform_fastest");
+	trace::entering("accu::impl::transform_stop_fastest");
 
 	const I& input = exact(input_);
 	const W& win   = exact(win_);
@@ -135,11 +135,15 @@
 	  {
 	    a.init();
 	    for_all(q)
+	    {
 	      a.take(q.val());
+	      if (a.can_stop())
+		break;
+	    }
 	    o.val() = a.to_result();
 	  }
 
-	trace::exiting("accu::impl::transform_fastest");
+	trace::exiting("accu::impl::transform_stop_fastest");
 	return output;
       }
 
@@ -154,25 +158,25 @@
 
       template <typename I, typename A, typename W>
       mln_ch_value(I, mln_result(A))
-      transform_dispatch(trait::image::speed::any,
+      transform_stop_dispatch(trait::image::speed::any,
 			 const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
       {
-	return impl::generic::transform(input, a, win);
+	return impl::generic::transform_stop(input, a, win);
       }
 
       template <typename I, typename A, typename W>
       mln_ch_value(I, mln_result(A))
-      transform_dispatch(trait::image::speed::fastest,
+      transform_stop_dispatch(trait::image::speed::fastest,
 			 const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
       {
-	return impl::transform_fastest(input, a, win);
+	return impl::transform_stop_fastest(input, a, win);
       }
 
       template <typename I, typename A, typename W>
       mln_ch_value(I, mln_result(A))
-      transform_dispatch(const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
+      transform_stop_dispatch(const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
       {
-	return transform_dispatch(mln_trait_image_speed(I)(),
+	return transform_stop_dispatch(mln_trait_image_speed(I)(),
 				  input, a, win);
       }
 
@@ -184,25 +188,25 @@
     template <typename I, typename A, typename W>
     inline
     mln_ch_value(I, mln_result(A))
-    transform(const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
+    transform_stop(const Image<I>& input, const Accumulator<A>& a, const Window<W>& win)
     {
-      trace::entering("accu::transform");
+      trace::entering("accu::transform_stop");
 
       mln_precondition(exact(input).has_data());
       // mln_precondition(exact(win).is_valid());
 
       mln_ch_value(I, mln_result(A)) output;
-      output = internal::transform_dispatch(input, a, win);
+      output = internal::transform_stop_dispatch(input, a, win);
 
-      trace::exiting("accu::transform");
+      trace::exiting("accu::transform_stop");
       return output;
     }
 
     template <typename I, typename A, typename W>
     mln_ch_value(I, mln_accu_with(A, mln_value(I))::result)
-    transform(const Image<I>& input, const Meta_Accumulator<A>& a, const Window<W>& win)
+    transform_stop(const Image<I>& input, const Meta_Accumulator<A>& a, const Window<W>& win)
     {
-      trace::entering("accu::transform");
+      trace::entering("accu::transform_stop");
 
       mln_precondition(exact(input).has_data());
       // mln_precondition(exact(win).is_valid());
@@ -211,9 +215,9 @@
       A_ a_ = accu::unmeta(exact(a), mln_value(I)());
 
       mln_ch_value(I, mln_result(A_)) output;
-      output = internal::transform_dispatch(input, a_, win);
+      output = internal::transform_stop_dispatch(input, a_, win);
 
-      trace::exiting("accu::transform");
+      trace::exiting("accu::transform_stop");
       return output;
     }
 
@@ -224,4 +228,4 @@
 } // end of namespace mln
 
 
-#endif // ! MLN_ACCU_TRANSFORM_HH
+#endif // ! MLN_ACCU_TRANSFORM_STOP_HH
Property changes on: mln/accu/transform_stop.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh	(revision 2878)
+++ mln/morpho/erosion.hh	(working copy)
@@ -34,7 +34,6 @@
 /// \brief Morphological erosion.
 
 # include <mln/morpho/includes.hh>
-# include <mln/accu/transform.hh>
 
 // Specializations are in:
 # include <mln/morpho/erosion.spe.hh>
@@ -109,27 +108,15 @@
 	template <typename I, typename W>
 	inline
 	mln_concrete(I)
-	erosion_on_set(const Image<I>& input_, const Window<W>& win_)
+	erosion_on_set(const Image<I>& input, const Window<W>& win)
 	{
 	  trace::entering("morpho::impl::generic::erosion_on_set");
 
-	  const I& input = exact(input_);
-	  const W& win = exact(win_);
+	  internal::erosion_tests(input, win);
 
 	  extension::adjust_fill(input, win, true);
-
 	  mln_concrete(I) output;
-	  initialize(output, input);
-
-	  mln_piter(I) p(input.domain());
-	  mln_qiter(W) q(win, p);
-	  for_all(p)
-	  {
-	    for_all(q) if (input.has(q))
-	      if (input(q) == false)
-		break;
-	    output(p) = ! q.is_valid();
-	  }
+	  output = accu::transform_stop(input, accu::land_basic(), win);
 
 	  trace::exiting("morpho::impl::generic::erosion_on_set");
 	  return output;
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh	(revision 2878)
+++ mln/morpho/includes.hh	(working copy)
@@ -1,4 +1,5 @@
 // Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -28,12 +29,9 @@
 #ifndef MLN_MORPHO_INCLUDES_HH
 # define MLN_MORPHO_INCLUDES_HH
 
-/*! \file mln/morpho/includes.hh
- *
- * \brief Basic list of includes for all files in mln/morpho/.
- *
- * \todo Re-activate the border/all include when ready.
- */
+/// \file mln/morpho/includes.hh
+///
+/// Basic list of includes for all files in mln/morpho/.
 
 
 # include <mln/core/concept/image.hh>
@@ -45,6 +43,7 @@
 # include <mln/value/ops.hh>
 
 # include <mln/accu/land.hh>
+# include <mln/accu/land_basic.hh>
 // # include <mln/accu/lor.hh>
 # include <mln/accu/min.hh>
 # include <mln/accu/max.hh>
@@ -52,6 +51,9 @@
 # include <mln/accu/max_h.hh>
 # include <mln/accu/rank.hh>
 
+# include <mln/accu/transform.hh>
+# include <mln/accu/transform_stop.hh>
+
 # include <mln/fun/v2v/saturate.hh>
 
 # include <mln/level/compare.hh>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0