* mln/core/concept/graph.hh: Move is_valid() and invalidate()...
* mln/util/internal/graph_base.hh: ... here.
* mln/core/image/vertex_image.hh,
* mln/core/image/edge_image.hh: Add new typedefs for default
related windows and neighborhoods.
* mln/core/internal/site_relative_iterator_base.hh: Add a new
template parameter in order to define the type of the central
element.
* mln/core/neighb.hh,
* mln/core/internal/neighb_niter_impl.hh,
* mln/core/image/graph_elt_neighborhood.hh,
* mln/core/image/graph_elt_window.hh,
* mln/core/internal/window_base.hh: Update accordingly and add a
new typedef center_t.
* mln/core/image/graph_window_piter.hh: Handle the case where the
central element have a different type from the others.
* mln/core/internal/graph_psite_base.hh: Reindent and avoid a
warning.
* mln/util/internal/graph_nbh_iter.hh: Add new typedefs.
* tests/core/image/Makefile.am,
* tests/core/image/vertex_and_edge_image.cc: Add a new test.
---
milena/ChangeLog | 33 ++
milena/mln/core/concept/graph.hh | 30 +-
milena/mln/core/image/edge_image.hh | 13 +-
milena/mln/core/image/graph_elt_neighborhood.hh | 29 +-
milena/mln/core/image/graph_elt_window.hh | 79 ++-
milena/mln/core/image/graph_window_piter.hh | 128 ++++-
milena/mln/core/image/vertex_image.hh | 16 +-
milena/mln/core/internal/graph_psite_base.hh | 584 ++++++++++----------
milena/mln/core/internal/neighb_niter_impl.hh | 8 +-
.../core/internal/site_relative_iterator_base.hh | 59 +-
milena/mln/core/internal/window_base.hh | 6 +-
milena/mln/core/neighb.hh | 9 +-
milena/mln/util/internal/graph_base.hh | 27 +-
milena/mln/util/internal/graph_nbh_iter.hh | 112 +++--
milena/tests/core/image/Makefile.am | 11 +-
milena/tests/core/image/vertex_and_edge_image.cc | 166 ++++++
16 files changed, 858 insertions(+), 452 deletions(-)
create mode 100644 milena/tests/core/image/vertex_and_edge_image.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6f01493..6d3f30a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,38 @@
2009-08-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Improve graph images.
+
+ * mln/core/concept/graph.hh: Move is_valid() and invalidate()...
+ * mln/util/internal/graph_base.hh: ... here.
+
+ * mln/core/image/vertex_image.hh,
+ * mln/core/image/edge_image.hh: Add new typedefs for default
+ related windows and neighborhoods.
+
+ * mln/core/internal/site_relative_iterator_base.hh: Add a new
+ template parameter in order to define the type of the central
+ element.
+
+ * mln/core/neighb.hh,
+ * mln/core/internal/neighb_niter_impl.hh,
+ * mln/core/image/graph_elt_neighborhood.hh,
+ * mln/core/image/graph_elt_window.hh,
+ * mln/core/internal/window_base.hh: Update accordingly and add a
+ new typedef center_t.
+
+ * mln/core/image/graph_window_piter.hh: Handle the case where the
+ central element have a different type from the others.
+
+ * mln/core/internal/graph_psite_base.hh: Reindent and avoid a
+ warning.
+
+ * mln/util/internal/graph_nbh_iter.hh: Add new typedefs.
+
+ * tests/core/image/Makefile.am,
+ * tests/core/image/vertex_and_edge_image.cc: Add a new test.
+
+2009-08-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Update documentation.
* doc/examples/accu-wrong-instanciation.cc.raw: Fix an incomplete
diff --git a/milena/mln/core/concept/graph.hh b/milena/mln/core/concept/graph.hh
index 97aee25..c351f9c 100644
--- a/milena/mln/core/concept/graph.hh
+++ b/milena/mln/core/concept/graph.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -72,12 +73,6 @@ namespace mln
template<typename G2>
bool is_subgraph_of(const G2& gr) const;
*/
- /// Return true if this graph is valid.
- /// FIXME: currently it always returns true.
- bool is_valid() const;
- /// Invalidate the graph.
- /// FIXME: does nothing!
- void invalidate();
/*
// Vertex and edges oriented.
util::vertex_id_t v_other(const util::edge_id_t& id_e, const
util::vertex_id_t& id_v) const;
@@ -142,29 +137,16 @@ namespace mln
util::edge_id_t (E::*m13)(const util::edge_id_t& id_e, unsigned i) const = &
E::e_ith_nbh_edge;
m13 = 0;
+ bool (E::*m14)() const = & E::is_valid;
+ m14 = 0;
+ void (E::*m15)() = & E::invalidate;
+ m15 = 0;
//FIXME: enable this test. Currently does not work because this is
// a templated method.
//bool (E::*m14)(...) = & E::is_subgraph_of;
//m14 = 0;
}
- template <typename E>
- inline
- bool
- Graph<E>::is_valid() const
- {
- //FIXME: should not always return true!
- return true;
- }
-
- template <typename E>
- inline
- void
- Graph<E>::invalidate()
- {
- //FIXME: No op! Should do something.
- }
-
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/edge_image.hh b/milena/mln/core/image/edge_image.hh
index 2cf9ed8..7da1690 100644
--- a/milena/mln/core/image/edge_image.hh
+++ b/milena/mln/core/image/edge_image.hh
@@ -147,10 +147,17 @@ namespace mln
site_function_t;
typedef mln_result(site_function_t) function_result_t;
- /// Window type
- typedef graph_elt_window<G,p_edges<G,site_function_t> > win_t;
+ /// Edge Window type
+ typedef graph_elt_window<G,p_edges<G,site_function_t> > edge_win_t;
/// Neighborhood type.
- typedef graph_elt_neighborhood<G,p_edges<G,site_function_t> > nbh_t;
+ typedef graph_elt_neighborhood<G,p_edges<G,site_function_t> >
edge_nbh_t;
+
+ /// Default Window type
+ typedef edge_win_t win_t;
+
+ /// Default Neighborhood type
+ typedef edge_nbh_t nbh_t;
+
/// Constructors.
/// @{
diff --git a/milena/mln/core/image/graph_elt_neighborhood.hh
b/milena/mln/core/image/graph_elt_neighborhood.hh
index a8ac79c..a1a739f 100644
--- a/milena/mln/core/image/graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/graph_elt_neighborhood.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -38,23 +39,31 @@ namespace mln
{
/// Elementary neighborhood on graph class.
- template <typename G, typename S>
+ ///
+ /// \tparam G is a graph type.
+ /// \tparam S is a site set type.
+ /// \tparam S2 is the site set type of the neighbors.
+ //
+ template <typename G, typename S, typename S2 = S>
struct graph_elt_neighborhood
- : public neighb< graph_elt_window<G,S> >
+ : public neighb< graph_elt_window<G,S,S2> >
{
- typedef neighb< graph_elt_window<G,S> > super_;
+ typedef neighb< graph_elt_window<G,S,S2> > super_;
- graph_elt_neighborhood();
+ graph_elt_neighborhood();
};
+
# ifndef MLN_INCLUDE_ONLY
-template <typename G, typename S>
-inline
-graph_elt_neighborhood<G,S>::graph_elt_neighborhood()
-{
-}
+
+ template <typename G, typename S, typename S2>
+ inline
+ graph_elt_neighborhood<G,S,S2>::graph_elt_neighborhood()
+ {
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/graph_elt_window.hh
b/milena/mln/core/image/graph_elt_window.hh
index 0d730e2..867a7bd 100644
--- a/milena/mln/core/image/graph_elt_window.hh
+++ b/milena/mln/core/image/graph_elt_window.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -40,38 +41,63 @@ namespace mln
{
/// Forward declaration
- template <typename G, typename S> class graph_elt_window;
+ template <typename G, typename S, typename S2> class graph_elt_window;
template <typename G, typename F> struct p_edges;
template <typename G, typename F> struct p_vertices;
+ namespace util
+ {
+ template <typename G> class edge;
+ template <typename G> class vertex;
+ };
namespace internal
{
- template <typename G, typename S, typename E>
- struct neighborhood_impl<graph_elt_window<G,S>,E>
- : public neighborhood_extra_impl<graph_elt_window<G,S>,E>
+ template <typename G, typename S, typename S2, typename E>
+ struct neighborhood_impl<graph_elt_window<G,S,S2>,E>
+ : public neighborhood_extra_impl<graph_elt_window<G,S,S2>,E>
{
};
/// Default
/// The given site set parameter is not supported yet!
- template <typename G, typename S>
+ ///
+ /// \p G is the graph type.
+ /// \p S is an image site set from where the center is extracted.
+ /// \p S2 is an image site set from where the neighbors are
+ /// extracted.
+ //
+ template <typename G, typename S, typename S2>
struct graph_window_iter_dispatch;
template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_edges<G,F> >
+ struct graph_window_iter_dispatch<G, p_edges<G,F>, p_edges<G,F> >
{
- typedef mln_edge_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
- typedef mln_edge_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
+ typedef mln_edge_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
+ typedef mln_edge_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
+
+ typedef p_edges<G,F> target;
};
template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_vertices<G,F> >
+ struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_vertices<G,F>
>
{
- typedef mln_vertex_nbh_vertex_fwd_iter(G) nbh_fwd_iter_;
- typedef mln_vertex_nbh_vertex_bkd_iter(G) nbh_bkd_iter_;
+ typedef mln_vertex_nbh_vertex_fwd_iter(G) nbh_fwd_iter_;
+ typedef mln_vertex_nbh_vertex_bkd_iter(G) nbh_bkd_iter_;
+
+ typedef p_vertices<G,F> target;
+ };
+
+
+ template <typename G, typename F, typename F2>
+ struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_edges<G,F2>
>
+ {
+ typedef mln_vertex_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
+ typedef mln_vertex_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
+
+ typedef p_edges<G,F2> target;
};
@@ -81,8 +107,8 @@ namespace mln
namespace trait
{
- template <typename G, typename S>
- struct window_< mln::graph_elt_window<G,S> >
+ template <typename G, typename S, typename S2>
+ struct window_< mln::graph_elt_window<G,S,S2> >
{
typedef trait::window::size::unknown size;
typedef trait::window::support::irregular support;
@@ -94,15 +120,18 @@ namespace mln
/// Elementary window on graph class.
/// \p G is the graph type.
- /// \p S is the image site set.
- template <typename G, typename S>
+ /// \p S is an image site set from where the center is extracted.
+ /// \p S2 is an image site set from where the neighbors are
+ /// extracted.
+ //
+ template <typename G, typename S, typename S2 = S>
class graph_elt_window
- : public graph_window_base<mln_result(S::fun_t),
- graph_elt_window<G,S> >,
- public internal::graph_window_iter_dispatch<G,S>
+ : public graph_window_base<mln_result(S2::fun_t),
+ graph_elt_window<G,S,S2> >,
+ public internal::graph_window_iter_dispatch<G,S,S2>
{
- typedef graph_elt_window<G,S> self_;
- typedef internal::graph_window_iter_dispatch<G,S> super_;
+ typedef graph_elt_window<G,S,S2> self_;
+ typedef internal::graph_window_iter_dispatch<G,S,S2> super_;
typedef typename super_::nbh_fwd_iter_ nbh_fwd_iter_;
typedef typename super_::nbh_bkd_iter_ nbh_bkd_iter_;
@@ -110,10 +139,16 @@ namespace mln
public:
/// Associated types.
/// \{
- typedef S target;
+ typedef typename super_::target target;
/// The type of psite corresponding to the window.
typedef mln_psite(target) psite;
+ /// Type of the window center element.
+ typedef mln_psite(S) center_t;
+
+ /// Type of the graph element pointed by this iterator.
+ typedef mln_graph_element(target) graph_element;
+
/// Site_Iterator type to browse the psites of the window
/// w.r.t. the ordering of vertices.
typedef graph_window_piter<target,self_,nbh_fwd_iter_> fwd_qiter;
diff --git a/milena/mln/core/image/graph_window_piter.hh
b/milena/mln/core/image/graph_window_piter.hh
index 4a62572..7812767 100644
--- a/milena/mln/core/image/graph_window_piter.hh
+++ b/milena/mln/core/image/graph_window_piter.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -28,8 +29,10 @@
/// \file
///
-/// Definition of a point iterator on a line_graph window.
+/// Definition of a graph element iterator on a graph window.
+# include <mln/core/concept/site_set.hh>
+# include <mln/core/concept/window.hh>
# include <mln/core/internal/site_relative_iterator_base.hh>
@@ -40,25 +43,63 @@ namespace mln
template <typename S, typename I> class p_graph_piter;
/// Forward iterator on line graph window.
+ ///
+ /// \tparam S is the site set type.
+ /// \tparam W is the window type.
+ /// \tparam I is the underlying iterator type.
+ //
template <typename S, typename W, typename I>
class graph_window_piter
: public internal::site_relative_iterator_base< W,
- graph_window_piter<S,W,I> >
+ graph_window_piter<S,W,I>,
+ typename W::center_t >
{
typedef graph_window_piter<S,W,I> self_;
- typedef internal::site_relative_iterator_base<W,self_> super_;
+ typedef
+ internal::site_relative_iterator_base<W,self_,mln_psite(S)> super_;
public:
/// Associated types
/// \{
+ /// Type of the window elements.
typedef mln_result(S::fun_t) P;
+ /// Type of the window center.
+ typedef typename W::center_t center_t;
+ /// Type of the graph element pointed by this iterator.
+ typedef typename W::graph_element graph_element;
/// \}
/// Construction.
/// \{
graph_window_piter();
+
+
+ // ---------------------------------------------------------
+ // FIXME: probably ugly to provide constructors usable for
+ // specific cases only...
+ // ---------------------------------------------------------
+
+ /// To be used in case the center and neighbor sites have the same
+ /// type and belong to the same site set.
+ ///
+ /// \param win The underlying window.
+ /// \param p_ref Window center.
+ //
+ template <typename Pref>
+ graph_window_piter(const Window<W>& win,
+ const Pref& p_ref);
+
+ /// To be used in case center and neighbors sites do not have the
+ /// same type and do not belong to the same site set.
+ ///
+ /// \param win The underlying window.
+ /// \param target_site_set Site set in which neighbor sites are
+ /// extracted.
+ /// \param p_ref Window center.
+ //
template <typename Pref>
graph_window_piter(const Window<W>& win,
+ const Site_Set<S>& target_site_set,
const Pref& p_ref);
/// \}
@@ -79,11 +120,11 @@ namespace mln
void center_at_(const Pref& c);
/// Do some work while setting the reference site.
- template <typename I2>
- void center_at_(const p_graph_piter<S, I2>& c);
+ template <typename S2, typename I2>
+ void center_at_(const p_graph_piter<S2, I2>& c);
/// Return the graph element pointed by this iterator.
- const mln_graph_element(S)& element() const;
+ const graph_element& element() const;
/// Compute the current psite.
mln_psite(W) compute_p_() const;
@@ -95,8 +136,12 @@ namespace mln
unsigned id() const;
/// \}
+ void change_target_site_set(const S& s);
+ const S& target_site_set() const;
+
private:
I iter_;
+ const S* s_;
};
@@ -106,26 +151,56 @@ namespace mln
template <typename S, typename W, typename I>
inline
graph_window_piter<S,W,I>::graph_window_piter()
+ : s_(0)
{
}
+
template <typename S, typename W, typename I>
template <typename Pref>
inline
graph_window_piter<S,W,I>::graph_window_piter(const Window<W>& win,
const Pref& p_ref)
+ : s_(0)
{
+ // Center and neighbor sites have the same type and belong to
+ // the same site set.
+ mlc_is(center_t, mln_psite(W))::check();
+
this->center_at(p_ref);
this->change_target(exact(win));
+ change_target_site_set(this->center().site_set());
+
mln_postcondition(!this->is_valid());
}
+
+ template <typename S, typename W, typename I>
+ template <typename Pref>
+ inline
+ graph_window_piter<S,W,I>::graph_window_piter(const Window<W>& win,
+ const Site_Set<S>& target_site_set,
+ const Pref& p_ref)
+ : s_(0)
+ {
+ // Center and neighbors sites do not have the same type and do
+ // not belong to the same site set.
+ mlc_is_not(center_t, mln_psite(W))::check();
+
+ this->center_at(p_ref);
+ this->change_target(exact(win));
+ change_target_site_set(exact(target_site_set));
+
+ mln_postcondition(!this->is_valid());
+ }
+
+
template <typename S, typename W, typename I>
inline
bool
graph_window_piter<S,W,I>::is_valid_() const
{
- return iter_.is_valid();
+ return s_ != 0 && s_->is_valid() && iter_.is_valid();
}
template <typename S, typename W, typename I>
@@ -159,15 +234,17 @@ namespace mln
graph_window_piter<S, W, I>::center_at_(const Pref& c)
{
iter_.center_at(c.p_hook_());
+ //FIXME: should we update target site set?
}
template <typename S, typename W, typename I>
- template <typename I2>
+ template <typename S2, typename I2>
inline
void
- graph_window_piter<S, W, I>::center_at_(const p_graph_piter<S, I2>& c)
+ graph_window_piter<S, W, I>::center_at_(const p_graph_piter<S2, I2>&
c)
{
iter_.center_at(c.hook_elt_());
+ //FIXME: should we update target site set?
}
template <typename S, typename W, typename I>
@@ -175,24 +252,17 @@ namespace mln
mln_psite(W)
graph_window_piter<S,W,I>::compute_p_() const
{
- return mln_psite(S)(this->center().site_set(), iter_.id());
+ return mln_psite(S)(target_site_set(), iter_.id());
}
template <typename S, typename W, typename I>
inline
- const mln_graph_element(S)&
+ const typename graph_window_piter<S,W,I>::graph_element&
graph_window_piter<S, W, I>::element() const
{
return iter_;
}
-// template <typename S, typename W, typename I>
-// inline
-// graph_window_piter<S, W, I>::operator unsigned() const
-// {
-// return iter_.id();
-// }
-//
template <typename S, typename W, typename I>
inline
unsigned
@@ -201,6 +271,26 @@ namespace mln
return iter_.id();
}
+ template <typename S, typename W, typename I>
+ inline
+ void
+ graph_window_piter<S, W, I>::change_target_site_set(const S& s)
+ {
+ s_ = & s;
+ mln_assertion(s_ != 0);
+ }
+
+ template <typename S, typename W, typename I>
+ inline
+ const S&
+ graph_window_piter<S, W, I>::target_site_set() const
+ {
+ mln_precondition(s_ != 0);
+ mln_precondition(s_->is_valid());
+ return *s_;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
diff --git a/milena/mln/core/image/vertex_image.hh
b/milena/mln/core/image/vertex_image.hh
index d60debc..fd7d2eb 100644
--- a/milena/mln/core/image/vertex_image.hh
+++ b/milena/mln/core/image/vertex_image.hh
@@ -141,7 +141,7 @@ namespace mln
/// Function mapping graph elements to sites.
typedef typename internal::vfsite_selector<P,G>::site_function_t
- site_function_t;
+ site_function_t;
typedef mln_result(site_function_t) function_result_t;
@@ -150,10 +150,20 @@ namespace mln
tag::value_<V>,
tag::graph_<G> > skeleton;
+ typedef p_vertices<G,site_function_t> S;
+
+ /// Vertex Window type
+ typedef graph_elt_window<G,S> vertex_win_t;
+
+ /// Vertex Neighborhood type.
+ typedef graph_elt_neighborhood<G,S> vertex_nbh_t;
+
/// Window type
- typedef graph_elt_window<G,p_vertices<G,site_function_t> > win_t;
+ typedef vertex_win_t win_t;
/// Neighborhood type.
- typedef graph_elt_neighborhood<G,p_vertices<G,site_function_t> > nbh_t;
+ typedef vertex_nbh_t nbh_t;
+
+
/// Constructors.
/// @{
diff --git a/milena/mln/core/internal/graph_psite_base.hh
b/milena/mln/core/internal/graph_psite_base.hh
index 2133281..cb3b123 100644
--- a/milena/mln/core/internal/graph_psite_base.hh
+++ b/milena/mln/core/internal/graph_psite_base.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -124,103 +125,104 @@ namespace mln
};
- /* FIXME: Shouldn't those comparisons be part of a much general
- mechanism? */
-
- /// Comparison of two mln::graph_psite_base<S,E> instances.
- /// \{
- /// \brief Is \a lhs equal to \a rhs?
- ///
- /// \pre Arguments \a lhs and \a rhs must belong to the same
- /// mln::p_vertices.
- template <typename S, typename E>
- bool
- 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 S, typename E>
- bool
- operator!=(const graph_psite_base<S,E>& lhs, const
graph_psite_base<S,E>& 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_vertices.
- template <typename S, typename E>
- bool
- operator< (const graph_psite_base<S,E>& lhs, const
graph_psite_base<S,E>& rhs);
- /// \}
-
-
- /// \{
- /// subject_impl specialization (Proxy)
- template <typename S, typename P, typename E>
- struct subject_impl< const graph_psite_base<S,P>&, E >
- {
- const S* target_() const;
- const S& site_set() const;
- const typename S::graph_t& graph() const;
- unsigned id() const;
- bool is_valid() const;
- // operator unsigned() const;
- // operator const typename S::graph_element&() const;
- const typename S::graph_element& element() const;
- const typename S::graph_element& p_hook_() const;
-
- private:
- const E& exact_() const;
- };
-
- template <typename S, typename P, typename E>
- struct subject_impl< graph_psite_base<S,P>&, E > :
- subject_impl< const graph_psite_base<S,P>&, E >
- {
- void change_target(const S& new_target);
- void update_id(unsigned elt_id);
- void invalidate();
+ /* FIXME: Shouldn't those comparisons be part of a much general
+ mechanism? */
+
+ /// Comparison of two mln::graph_psite_base<S,E> instances.
+ /// \{
+ /// \brief Is \a lhs equal to \a rhs?
+ ///
+ /// \pre Arguments \a lhs and \a rhs must belong to the same
+ /// mln::p_vertices.
+ template <typename S, typename E>
+ bool
+ operator==(const graph_psite_base<S,E>& lhs, const
graph_psite_base<S,E>& rhs);
- private:
- E& exact_();
- };
- /// \}
+ /// \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 S, typename E>
+ bool
+ operator!=(const graph_psite_base<S,E>& lhs, const
graph_psite_base<S,E>& 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_vertices.
+ template <typename S, typename E>
+ bool
+ operator< (const graph_psite_base<S,E>& lhs, const
graph_psite_base<S,E>& rhs);
+ /// \}
+
+
+ /// \{
+ /// subject_impl specialization (Proxy)
+ template <typename S, typename P, typename E>
+ struct subject_impl< const graph_psite_base<S,P>&, E >
+ {
+ const S* target_() const;
+ const S& site_set() const;
+ const typename S::graph_t& graph() const;
+ unsigned id() const;
+ bool is_valid() const;
+ // operator unsigned() const;
+ // operator const typename S::graph_element&() const;
+ const typename S::graph_element& element() const;
+ const typename S::graph_element& p_hook_() const;
+
+ private:
+ const E& exact_() const;
+ };
+
+ template <typename S, typename P, typename E>
+ struct subject_impl< graph_psite_base<S,P>&, E > :
+ subject_impl< const graph_psite_base<S,P>&, E >
+ {
+ void change_target(const S& new_target);
+ void update_id(unsigned elt_id);
+ void invalidate();
+
+ private:
+ E& exact_();
+ };
+ /// \}
# ifndef MLN_INCLUDE_ONLY
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::graph_psite_base()
- : s_(0)
- {
- }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::graph_psite_base()
+ : s_(0)
+ {
+ }
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::graph_psite_base(const S& s)
- {
- change_target(s);
- }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::graph_psite_base(const S& s)
+ {
+ change_target(s);
+ }
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
- {
- change_target(s);
- update_id(id);
- }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
+ {
+ change_target(s);
+ update_id(id);
+ }
// The lines below are dedicated/local to this file.
template <typename E, typename S, typename G>
inline
void local_change_graph(E& elt_, S& site_, const G& g)
{
+ (void) site_;
elt_.change_graph(g);
}
template <typename E, typename G>
@@ -232,238 +234,238 @@ namespace mln
}
// End of local stuff.
- template <typename S, typename E>
- inline
- void
- graph_psite_base<S,E>::change_target(const S& new_target)
- {
- s_ = & new_target;
- local_change_graph(elt_, site_, new_target.graph());
- }
-
- template <typename S, typename E>
- inline
- void
- graph_psite_base<S,E>::update_id(unsigned id)
- {
- mln_precondition(s_ != 0);
- elt_.update_id(id);
- site_ = s_->function()(elt_.id());
- }
-
- template <typename S, typename E>
- inline
- const S*
- graph_psite_base<S,E>::target_() const
- {
- return s_;
- }
+ template <typename S, typename E>
+ inline
+ void
+ graph_psite_base<S,E>::change_target(const S& new_target)
+ {
+ s_ = & new_target;
+ local_change_graph(elt_, site_, new_target.graph());
+ }
- template <typename S, typename E>
- inline
- const S&
- graph_psite_base<S,E>::site_set() const
- {
- mln_precondition(s_ != 0);
- return *s_;
- }
-
- template <typename S, typename E>
- inline
- const typename S::graph_t&
- graph_psite_base<S,E>::graph() const
- {
- mln_precondition(s_ != 0);
- return s_->graph();
- }
-
- template <typename S, typename E>
- inline
- typename graph_psite_base<S,E>::id_t
- graph_psite_base<S,E>::id() const
- {
- return elt_.id();
- }
+ template <typename S, typename E>
+ inline
+ void
+ graph_psite_base<S,E>::update_id(unsigned id)
+ {
+ mln_precondition(s_ != 0);
+ elt_.update_id(id);
+ site_ = s_->function()(elt_.id());
+ }
- template <typename S, typename E>
- inline
- bool
- graph_psite_base<S,E>::is_valid() const
- {
- return s_ != 0 && s_->is_valid() && elt_.is_valid();
- }
+ template <typename S, typename E>
+ inline
+ const S*
+ graph_psite_base<S,E>::target_() const
+ {
+ return s_;
+ }
- template <typename S, typename E>
- inline
- void
- graph_psite_base<S,E>::invalidate()
- {
- s_ = 0;
- elt_.invalidate();
- }
-
- template <typename S, typename E>
- inline
- const mln_site(S)&
- graph_psite_base<S,E>::subj_()
- {
- /*FIXME: we may like to enable the following precondition, however, we
- ** can't do that since neighb_*_niters update the psite target after having
- ** taken the adress of the subject.
- */
- // mln_precondition(is_valid());
- return site_;
- }
-
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::operator unsigned () const
- {
- mln_precondition(is_valid());
- return elt_.id();
- }
+ template <typename S, typename E>
+ inline
+ const S&
+ graph_psite_base<S,E>::site_set() const
+ {
+ mln_precondition(s_ != 0);
+ return *s_;
+ }
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::operator typename S::graph_element::id_t () const
- {
- mln_precondition(is_valid());
- return elt_.id();
- }
+ template <typename S, typename E>
+ inline
+ const typename S::graph_t&
+ graph_psite_base<S,E>::graph() const
+ {
+ mln_precondition(s_ != 0);
+ return s_->graph();
+ }
- template <typename S, typename E>
- inline
- graph_psite_base<S,E>::operator const typename S::graph_element&() const
- {
- //mln_precondition(is_valid());
- return elt_;
- }
-
- template <typename S, typename E>
- inline
- const typename S::graph_element&
- graph_psite_base<S,E>::element() const
- {
- /*FIXME: we may like to enable the following precondition, however, we
- ** can't do that since neighb_*_niters update the psite target after having
- ** taken the adress of the subject.
- */
- // mln_precondition(is_valid());
- return elt_;
- }
-
- template <typename S, typename E>
- inline
- const typename S::graph_element&
- graph_psite_base<S,E>::p_hook_() const
- {
- return elt_;
- }
+ template <typename S, typename E>
+ inline
+ typename graph_psite_base<S,E>::id_t
+ graph_psite_base<S,E>::id() const
+ {
+ return elt_.id();
+ }
+ template <typename S, typename E>
+ inline
+ bool
+ graph_psite_base<S,E>::is_valid() const
+ {
+ return s_ != 0 && s_->is_valid() && elt_.is_valid();
+ }
- template <typename S, typename P, typename E>
- inline
- const E&
- subject_impl< const graph_psite_base<S,P>&, E >::exact_() const
- {
- return internal::force_exact<const E>(*this);
- }
+ template <typename S, typename E>
+ inline
+ void
+ graph_psite_base<S,E>::invalidate()
+ {
+ s_ = 0;
+ elt_.invalidate();
+ }
- template <typename S, typename P, typename E>
- inline
- const S*
- subject_impl< const graph_psite_base<S,P>&, E >::target_() const
- {
- return exact_().get_subject().target();
- }
+ template <typename S, typename E>
+ inline
+ const mln_site(S)&
+ graph_psite_base<S,E>::subj_()
+ {
+ /*FIXME: we may like to enable the following precondition, however, we
+ ** can't do that since neighb_*_niters update the psite target after having
+ ** taken the adress of the subject.
+ */
+ // mln_precondition(is_valid());
+ return site_;
+ }
- template <typename S, typename P, typename E>
- inline
- const S&
- subject_impl< const graph_psite_base<S,P>&, E >::site_set() const
- {
- return exact_().get_subject().site_set();
- }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::operator unsigned () const
+ {
+ mln_precondition(is_valid());
+ return elt_.id();
+ }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::operator typename S::graph_element::id_t () const
+ {
+ mln_precondition(is_valid());
+ return elt_.id();
+ }
- template <typename S, typename P, typename E>
- inline
- const typename S::graph_t&
- subject_impl< const graph_psite_base<S,P>&, E >::graph() const
- {
- return exact_().get_subject().graph();
- }
+ template <typename S, typename E>
+ inline
+ graph_psite_base<S,E>::operator const typename S::graph_element&() const
+ {
+ //mln_precondition(is_valid());
+ return elt_;
+ }
- template <typename S, typename P, typename E>
- inline
- unsigned
- subject_impl< const graph_psite_base<S,P>&, E >::id() const
- {
- return exact_().get_subject().id();
- };
+ template <typename S, typename E>
+ inline
+ const typename S::graph_element&
+ graph_psite_base<S,E>::element() const
+ {
+ /*FIXME: we may like to enable the following precondition, however, we
+ ** can't do that since neighb_*_niters update the psite target after having
+ ** taken the adress of the subject.
+ */
+ // mln_precondition(is_valid());
+ return elt_;
+ }
- template <typename S, typename P, typename E>
- inline
- bool
- subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const
- {
- return exact_().get_subject().is_valid();
- }
+ template <typename S, typename E>
+ inline
+ const typename S::graph_element&
+ graph_psite_base<S,E>::p_hook_() const
+ {
+ return elt_;
+ }
- template <typename S, typename P, typename E>
- inline
- const typename S::graph_element&
- subject_impl< const graph_psite_base<S,P>&, E >::element() const
- {
- return exact_().get_subject().element();
- }
- template <typename S, typename P, typename E>
- inline
- const typename S::graph_element&
- subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const
- {
- return exact_().get_subject().p_hook_();
- }
+ template <typename S, typename P, typename E>
+ inline
+ const E&
+ subject_impl< const graph_psite_base<S,P>&, E >::exact_() const
+ {
+ return internal::force_exact<const E>(*this);
+ }
+ template <typename S, typename P, typename E>
+ inline
+ const S*
+ subject_impl< const graph_psite_base<S,P>&, E >::target_() const
+ {
+ return exact_().get_subject().target();
+ }
- template <typename S, typename P, typename E>
- inline
- E&
- subject_impl< graph_psite_base<S,P>&, E >::exact_()
- {
- return internal::force_exact<E>(*this);
- }
+ template <typename S, typename P, typename E>
+ inline
+ const S&
+ subject_impl< const graph_psite_base<S,P>&, E >::site_set() const
+ {
+ return exact_().get_subject().site_set();
+ }
- template <typename S, typename P, typename E>
- inline
- void
- subject_impl< graph_psite_base<S,P>&, E >::change_target(const
S& new_target)
- {
- exact_().get_subject().change_target(new_target);
- }
- template <typename S, typename P, typename E>
- inline
- void
- subject_impl< graph_psite_base<S,P>&, E >::update_id(unsigned
id)
- {
- exact_().get_subject().update_id(id);
- };
+ template <typename S, typename P, typename E>
+ inline
+ const typename S::graph_t&
+ subject_impl< const graph_psite_base<S,P>&, E >::graph() const
+ {
+ return exact_().get_subject().graph();
+ }
- template <typename S, typename P, typename E>
- inline
- void
- subject_impl< graph_psite_base<S,P>&, E >::invalidate()
- {
- exact_().get_subject().invalidate();
- }
+ template <typename S, typename P, typename E>
+ inline
+ unsigned
+ subject_impl< const graph_psite_base<S,P>&, E >::id() const
+ {
+ return exact_().get_subject().id();
+ };
+
+ template <typename S, typename P, typename E>
+ inline
+ bool
+ subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const
+ {
+ return exact_().get_subject().is_valid();
+ }
+
+ template <typename S, typename P, typename E>
+ inline
+ const typename S::graph_element&
+ subject_impl< const graph_psite_base<S,P>&, E >::element() const
+ {
+ return exact_().get_subject().element();
+ }
+
+ template <typename S, typename P, typename E>
+ inline
+ const typename S::graph_element&
+ subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const
+ {
+ return exact_().get_subject().p_hook_();
+ }
+
+
+ template <typename S, typename P, typename E>
+ inline
+ E&
+ subject_impl< graph_psite_base<S,P>&, E >::exact_()
+ {
+ return internal::force_exact<E>(*this);
+ }
+
+ template <typename S, typename P, typename E>
+ inline
+ void
+ subject_impl< graph_psite_base<S,P>&, E >::change_target(const
S& new_target)
+ {
+ exact_().get_subject().change_target(new_target);
+ }
+
+ template <typename S, typename P, typename E>
+ inline
+ void
+ subject_impl< graph_psite_base<S,P>&, E >::update_id(unsigned
id)
+ {
+ exact_().get_subject().update_id(id);
+ };
+
+ template <typename S, typename P, typename E>
+ inline
+ void
+ subject_impl< graph_psite_base<S,P>&, E >::invalidate()
+ {
+ exact_().get_subject().invalidate();
+ }
# endif // ! MLN_INCLUDE_ONLY
-} // end of namespace internal
+ } // end of namespace internal
- } // end of namespace mln
+} // end of namespace mln
#endif // ! MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
diff --git a/milena/mln/core/internal/neighb_niter_impl.hh
b/milena/mln/core/internal/neighb_niter_impl.hh
index 75dfc60..ea44822 100644
--- a/milena/mln/core/internal/neighb_niter_impl.hh
+++ b/milena/mln/core/internal/neighb_niter_impl.hh
@@ -39,7 +39,7 @@ namespace mln
// Forward declaration.
template <typename P, typename W> class graph_window_base;
- template <typename G, typename F> class graph_elt_window;
+ template <typename G, typename F, typename Q> class graph_elt_window;
template <typename G, typename F, typename I> class graph_elt_window_if;
template <typename G, typename F> class line_graph_elt_window;
namespace util
@@ -124,10 +124,10 @@ namespace mln
/// Add more implementation for neighborhoods made from a
/// graph_window_piter.
- template <typename G, typename S, typename E>
- struct neighb_niter_impl<graph_elt_window<G,S>, E>
+ template <typename G, typename S, typename Q, typename E>
+ struct neighb_niter_impl<graph_elt_window<G,S,Q>, E>
: public neighb_niter_impl< graph_window_base< mln_result(S::fun_t),
- graph_elt_window<G,S> >,
+ graph_elt_window<G,S,Q> >,
E >
{
diff --git a/milena/mln/core/internal/site_relative_iterator_base.hh
b/milena/mln/core/internal/site_relative_iterator_base.hh
index 4809bf8..de4e5aa 100644
--- a/milena/mln/core/internal/site_relative_iterator_base.hh
+++ b/milena/mln/core/internal/site_relative_iterator_base.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -58,7 +59,7 @@ namespace mln
/// is_valid_, invalidate_ and compute_p_. They shall define
/// NEITHER start_ NOR next_.
///
- template <typename S, typename E>
+ template <typename S, typename E, typename C = mln_psite(S)>
class site_relative_iterator_base : public site_iterator_base< S, E >
{
public:
@@ -80,7 +81,7 @@ namespace mln
const S& site_set() const;
/// The psite around which this iterator moves.
- const mln_psite(S)& center() const;
+ const C& center() const;
/// This overriding is very useful: it adds a test to prevent
/// getting an invalid iterator when its center has moved. Some
@@ -106,7 +107,7 @@ namespace mln
/// A pointer to the center psite around which this iterator
/// moves.
- const mln_psite(S)* c_;
+ const C* c_;
private:
@@ -123,9 +124,9 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
- site_relative_iterator_base<S,E>::site_relative_iterator_base()
+ site_relative_iterator_base<S,E,C>::site_relative_iterator_base()
: c_(0)
{
void (E::*m1)() = & E::do_start_;
@@ -136,77 +137,77 @@ namespace mln
m3 = 0;
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
template <typename P>
inline
void
- site_relative_iterator_base<S,E>::center_at(const P& c)
+ site_relative_iterator_base<S,E,C>::center_at(const P& c)
{
- mlc_converts_to(P, const mln_psite(S)&)::check();
- c_ = & static_cast< const mln_psite(S)& >(c);
+ mlc_converts_to(P, const C&)::check();
+ c_ = & static_cast< const C& >(c);
exact(this)->center_at_(c); // May call some extra code.
this->invalidate();
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
void
- site_relative_iterator_base<S,E>::start_()
+ site_relative_iterator_base<S,E,C>::start_()
{
exact(this)->do_start_();
if (this->is_valid())
p_ = exact(this)->compute_p_();
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
void
- site_relative_iterator_base<S,E>::next_()
+ site_relative_iterator_base<S,E,C>::next_()
{
exact(this)->do_next_();
if (this->is_valid())
p_ = exact(this)->compute_p_();
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
- const mln_psite(S)&
- site_relative_iterator_base<S,E>::center() const
+ const C&
+ site_relative_iterator_base<S,E,C>::center() const
{
mln_precondition(c_ != 0);
return *c_;
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
const S&
- site_relative_iterator_base<S, E>::site_set() const
+ site_relative_iterator_base<S,E,C>::site_set() const
{
mln_precondition(this->s_ != 0);
return *this->s_;
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
const mln_psite(S)&
- site_relative_iterator_base<S,E>::subj_()
+ site_relative_iterator_base<S,E,C>::subj_()
{
mln_assertion(exact(this)->compute_p_() == p_);
return p_;
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
const mln_psite(S)&
- site_relative_iterator_base<S,E>::p_hook_() const
+ site_relative_iterator_base<S,E,C>::p_hook_() const
{
return p_;
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
void
- site_relative_iterator_base<S,E>::change_target(const S& s)
+ site_relative_iterator_base<S,E,C>::change_target(const S& s)
{
this->s_ = & s;
// p might be also updated since it can hold a pointer towards
@@ -216,10 +217,10 @@ namespace mln
this->invalidate();
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
inline
E&
- site_relative_iterator_base<S,E>::update()
+ site_relative_iterator_base<S,E,C>::update()
{
mln_precondition(this->s_ && c_);
p_ = exact(this)->compute_p_();
@@ -227,11 +228,11 @@ namespace mln
return exact(*this);
}
- template <typename S, typename E>
+ template <typename S, typename E, typename C>
template <typename P>
inline
void
- site_relative_iterator_base<S,E>::center_at_(const P&)
+ site_relative_iterator_base<S,E,C>::center_at_(const P&)
{
// Default is no-op, meaning "no extra code".
}
diff --git a/milena/mln/core/internal/window_base.hh
b/milena/mln/core/internal/window_base.hh
index 7648b13..0047055 100644
--- a/milena/mln/core/internal/window_base.hh
+++ b/milena/mln/core/internal/window_base.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -57,6 +58,9 @@ namespace mln
/// Site associated type.
typedef mln_site(D) site;
+ /// Type of the window center
+ typedef psite center_t;
+
/// Test if this window can be a neighborhood.
// This method is used in the neighborhood window-adapter.
bool is_neighbable_() const;
diff --git a/milena/mln/core/neighb.hh b/milena/mln/core/neighb.hh
index 57ab311..8ce148e 100644
--- a/milena/mln/core/neighb.hh
+++ b/milena/mln/core/neighb.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -114,7 +115,8 @@ namespace mln
template <typename W>
class neighb_fwd_niter
: public internal::site_relative_iterator_base< neighb<W>,
- neighb_fwd_niter<W> >,
+ neighb_fwd_niter<W>,
+ mln_psite(neighb<W>) >,
public internal::neighb_niter_impl<W, neighb_fwd_niter<W> >
{
public:
@@ -152,7 +154,8 @@ namespace mln
template <typename W>
class neighb_bkd_niter
: public internal::site_relative_iterator_base< neighb<W>,
- neighb_bkd_niter<W> >,
+ neighb_bkd_niter<W>,
+ mln_psite(neighb<W>)>,
public internal::neighb_niter_impl<W, neighb_fwd_niter<W> >
{
public:
diff --git a/milena/mln/util/internal/graph_base.hh
b/milena/mln/util/internal/graph_base.hh
index abfcc57..3a9eea9 100644
--- a/milena/mln/util/internal/graph_base.hh
+++ b/milena/mln/util/internal/graph_base.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -101,6 +102,12 @@ namespace mln
/// \{
/// Returns the other adjacent vertex id of a given edge id \p id_e.
vertex_id_t v_other(const edge_id_t& id_e, const vertex_id_t& id_v) const;
+
+ /// Return true if this graph is valid.
+ bool is_valid() const;
+ /// Invalidate the graph.
+ void invalidate();
+
/// \}
// FIXME: We might want to externalize this in routine of
@@ -206,6 +213,24 @@ namespace mln
return exact(this)->has_e(e.id());
}
+
+ template <typename E>
+ inline
+ bool
+ graph_base<E>::is_valid() const
+ {
+ return data_ != 0;
+ }
+
+ template <typename E>
+ inline
+ void
+ graph_base<E>::invalidate()
+ {
+ data_.clean_();
+ }
+
+
/*--------.
| Debug. |
`--------*/
diff --git a/milena/mln/util/internal/graph_nbh_iter.hh
b/milena/mln/util/internal/graph_nbh_iter.hh
index 8235b06..35f33b2 100644
--- a/milena/mln/util/internal/graph_nbh_iter.hh
+++ b/milena/mln/util/internal/graph_nbh_iter.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -32,7 +33,8 @@
# include <mln/util/edge.hh>
/// \file
-/// \brief Implementation for graph vertex iterators centered to a vertex.
+/// \brief Implementation for graph vertex iterators centered to a
+/// vertex.
namespace mln
{
@@ -51,11 +53,16 @@ namespace mln
util::vertex<G>,
vertex_nbh_vertex_fwd_iterator<G> >
{
- typedef util::vertex<G> V;
- typedef vertex_nbh_vertex_fwd_iterator<G> self_;
- typedef nbh_iterator_base<G, V, V, self_> super_;
+ typedef util::vertex<G> V;
+ typedef vertex_nbh_vertex_fwd_iterator<G> self_;
+ typedef nbh_iterator_base<G, V, V, self_> super_;
public:
+ /// Type of the iterator center element.
+ typedef V center;
+ /// Type of the iterator targeted elements.
+ typedef V nbh;
+
/// Construction and assignment.
/// \{
vertex_nbh_vertex_fwd_iterator();
@@ -88,11 +95,17 @@ namespace mln
util::vertex<G>,
vertex_nbh_vertex_bkd_iterator<G> >
{
- typedef util::vertex<G> V;
- typedef vertex_nbh_vertex_bkd_iterator<G> self_;
- typedef nbh_iterator_base<G, V, V, self_> super_;
+ typedef util::vertex<G> V;
+
+ typedef vertex_nbh_vertex_bkd_iterator<G> self_;
+ typedef nbh_iterator_base<G, V, V, self_> super_;
public:
+ /// Type of the iterator center element.
+ typedef V center;
+ /// Type of the iterator targeted elements.
+ typedef V nbh;
+
/// Construction and assignment.
/// \{
vertex_nbh_vertex_bkd_iterator();
@@ -130,12 +143,17 @@ namespace mln
util::edge<G>,
vertex_nbh_edge_fwd_iterator<G> >
{
- typedef util::vertex<G> V;
- typedef util::edge<G> E;
- typedef vertex_nbh_edge_fwd_iterator<G> self_;
- typedef nbh_iterator_base<G, V, E, self_> super_;
+ typedef util::vertex<G> V;
+ typedef util::edge<G> E;
+ typedef vertex_nbh_edge_fwd_iterator<G> self_;
+ typedef nbh_iterator_base<G, V, E, self_> super_;
public:
+ /// Type of the iterator center element.
+ typedef V center;
+ /// Type of the iterator targeted elements.
+ typedef E nbh;
+
/// Construction and assignment.
/// \{
vertex_nbh_edge_fwd_iterator();
@@ -169,12 +187,17 @@ namespace mln
util::edge<G>,
vertex_nbh_edge_bkd_iterator<G> >
{
- typedef util::vertex<G> V;
- typedef util::edge<G> E;
- typedef vertex_nbh_edge_bkd_iterator<G> self_;
- typedef nbh_iterator_base<G, V, E, self_> super_;
+ typedef util::vertex<G> V;
+ typedef util::edge<G> E;
+ typedef vertex_nbh_edge_bkd_iterator<G> self_;
+ typedef nbh_iterator_base<G, V, E, self_> super_;
public:
+ /// Type of the iterator center element.
+ typedef V center;
+ /// Type of the iterator targeted elements.
+ typedef E nbh;
+
/// Construction and assignment.
/// \{
vertex_nbh_edge_bkd_iterator();
@@ -212,11 +235,17 @@ namespace mln
util::edge<G>,
edge_nbh_edge_fwd_iterator<G> >
{
- typedef util::edge<G> E;
- typedef edge_nbh_edge_fwd_iterator<G> self_;
- typedef nbh_iterator_base<G, E, E, self_> super_;
+ typedef util::edge<G> E;
+ typedef edge_nbh_edge_fwd_iterator<G> self_;
+ typedef nbh_iterator_base<G, E, E, self_> super_;
public:
+ /// Type of the iterator center element.
+ typedef E center;
+ /// Type of the iterator targeted elements.
+ typedef E nbh;
+
+
/// Construction and assignment.
/// \{
edge_nbh_edge_fwd_iterator();
@@ -250,11 +279,18 @@ namespace mln
util::edge<G>,
edge_nbh_edge_bkd_iterator<G> >
{
- typedef util::edge<G> E;
- typedef edge_nbh_edge_bkd_iterator<G> self_;
- typedef nbh_iterator_base<G, E, E, self_> super_;
+ typedef util::edge<G> E;
+
+ typedef edge_nbh_edge_bkd_iterator<G> self_;
+ typedef nbh_iterator_base<G, E, E, self_> super_;
public:
+
+ /// Type of the iterator center element.
+ typedef E center;
+ /// Type of the iterator targeted elements.
+ typedef E nbh;
+
/// Construction and assignment.
/// \{
edge_nbh_edge_bkd_iterator();
@@ -296,7 +332,7 @@ namespace mln
template <typename C>
inline
vertex_nbh_vertex_fwd_iterator<G>::vertex_nbh_vertex_fwd_iterator(const C&
c)
- : super_(c)
+ : super_(c)
{
}
@@ -332,9 +368,9 @@ namespace mln
this->elt_.update_id(this->c_->ith_nbh_vertex(this->i_));
}
- /*-------------------------------`
- | vertex_nbh_vertex_bkd_iterator |
- \-------------------------------*/
+ /*-------------------------------`
+ | vertex_nbh_vertex_bkd_iterator |
+ \-------------------------------*/
template <typename G>
inline
@@ -383,9 +419,9 @@ namespace mln
}
- /*-----------------------------`
- | vertex_nbh_edge_fwd_iterator |
- \-----------------------------*/
+ /*-----------------------------`
+ | vertex_nbh_edge_fwd_iterator |
+ \-----------------------------*/
template <typename G>
inline
@@ -433,9 +469,9 @@ namespace mln
this->elt_.update_id(this->c_->ith_nbh_edge(this->i_));
}
- /*-----------------------------`
- | vertex_nbh_edge_bkd_iterator |
- \-----------------------------*/
+ /*-----------------------------`
+ | vertex_nbh_edge_bkd_iterator |
+ \-----------------------------*/
template <typename G>
inline
@@ -485,9 +521,9 @@ namespace mln
- /*-----------------------------`
- | edge_nbh_edge_fwd_iterator |
- \-----------------------------*/
+ /*-----------------------------`
+ | edge_nbh_edge_fwd_iterator |
+ \-----------------------------*/
template <typename G>
inline
@@ -546,9 +582,9 @@ namespace mln
this->elt_.update_id(e_id);
}
- /*-----------------------------`
- | edge_nbh_edge_bkd_iterator |
- \-----------------------------*/
+ /*-----------------------------`
+ | edge_nbh_edge_bkd_iterator |
+ \-----------------------------*/
template <typename G>
inline
diff --git a/milena/tests/core/image/Makefile.am b/milena/tests/core/image/Makefile.am
index 6266ceb..0bfff01 100644
--- a/milena/tests/core/image/Makefile.am
+++ b/milena/tests/core/image/Makefile.am
@@ -1,4 +1,5 @@
-# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+# (LRDE).
#
# This file is part of Olena.
#
@@ -33,19 +34,21 @@ check_PROGRAMS = \
image2d \
image3d \
line_graph_image \
- vertex_image
+ vertex_image \
+ vertex_and_edge_image
noinst_HEADERS = complex_image.hh
complex_image_SOURCES = complex_image.cc
-graph_image_SOURCES = graph_image.cc
+edge_image_SOURCES = edge_image.cc
flat_image_SOURCES = flat_image.cc
+graph_image_SOURCES = graph_image.cc
image1d_SOURCES = image1d.cc
image2d_SOURCES = image2d.cc
image3d_SOURCES = image3d.cc
line_graph_image_SOURCES = line_graph_image.cc
+vertex_and_edge_image_SOURCES = vertex_and_edge_image.cc
vertex_image_SOURCES = vertex_image.cc
-edge_image_SOURCES = edge_image.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/core/image/vertex_and_edge_image.cc
b/milena/tests/core/image/vertex_and_edge_image.cc
new file mode 100644
index 0000000..60a4609
--- /dev/null
+++ b/milena/tests/core/image/vertex_and_edge_image.cc
@@ -0,0 +1,166 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+#include <vector>
+
+#include <mln/core/image/vertex_image.hh>
+#include <mln/core/image/edge_image.hh>
+#include <mln/fun/i2v/array.hh>
+#include <mln/util/graph.hh>
+
+
+
+/* The graph is as follows:
+
+ 0 1 2 3 4
+ .-----------
+ |
+ 0 | 0 2
+ 1 | \ / |
+ 2 | 1 |
+ 3 | \ |
+ 4 | 3-4
+
+*/
+
+static const unsigned X = mln_max(unsigned); // Invalid id.
+
+
+static unsigned expected_fwd_nb[5][3] = { { 0, X, X },
+ { 0, 1, 2 },
+ { 1, 4, X },
+ { 2, 3, X },
+ { 3, 4, X } };
+
+
+static unsigned expected_bkd_nb[5][3] = { { 0, X, X },
+ { 2, 1, 0 },
+ { 4, 1, X },
+ { 3, 2, X },
+ { 4, 3, X } };
+
+
+int main()
+{
+ using namespace mln;
+
+ /*--------.
+ | Graph. |
+ `--------*/
+
+ // Points associated to vertices.
+ 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.
+ g.add_vertices(sites.size());
+
+ // Populate the graph with edges.
+ g.add_edge(0, 1);
+ g.add_edge(1, 2);
+ g.add_edge(1, 3);
+ g.add_edge(3, 4);
+ g.add_edge(4, 2);
+
+ //g.print_debug(std::cout);
+
+ /*-------------.
+ | Graph image. |
+ `-------------*/
+
+ // Vertex values.
+ typedef fun::i2v::array<unsigned> viota_t;
+ viota_t iota(g.v_nmax());
+ for (unsigned i = 0; i < iota.size(); ++i)
+ iota(i) = 10 + i;
+
+
+ // Edge values.
+ typedef fun::i2v::array<unsigned> eiota_t;
+ eiota_t eiota(g.e_nmax());
+ for (unsigned i = 0; i < eiota.size(); ++i)
+ eiota(i) = 20 + i;
+
+
+ typedef vertex_image<void,unsigned> v_ima_t;
+ v_ima_t v_ima(g, iota);
+
+ typedef edge_image<void,unsigned> e_ima_t;
+ e_ima_t e_ima(g, eiota);
+
+
+ // Iterator over the vertex image.
+ mln_piter_(v_ima_t) v(v_ima.domain());
+
+
+ typedef graph_elt_window<util::graph,
+ v_ima_t::domain_t,
+ e_ima_t::domain_t> edge_win_t;
+ edge_win_t win;
+
+ // Forward Iteration
+ {
+ for_all(v)
+ {
+ int i = 0;
+ // Iterator over the neighbor edges in the edge image.
+ mln_qiter_(edge_win_t) e(win, e_ima.domain(), v);
+ for_all(e)
+ {
+ mln_assertion(expected_fwd_nb[v.id()][i++] == e.id());
+ mln_assertion((e.id() + 20) == e_ima(e));
+ }
+ }
+ }
+
+ // Backward Iteration
+ {
+ for_all(v)
+ {
+ int i = 0;
+ // Iterator over the neighbor edges in the edge image.
+ mln_bkd_qiter_(edge_win_t) e(win, e_ima.domain(), v);
+ for_all(e)
+ {
+ mln_assertion(expected_bkd_nb[v.id()][i++] == e.id());
+ mln_assertion((e.id() + 20) == e_ima(e));
+ }
+ }
+ }
+
+
+
+// FIXME: add tests for graph_window_if and graph_neighborhood_if when
+// they support this feature.
+
+}
--
1.5.6.5