
* 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@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@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