
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add more documentation to forward iterators on graph neighborhoods and windows, and add backward iterators. * mln/core/graph_neighborhood_piter.hh: More documentation. (graph_neighborhood_fwd_piter(const N&, const Point_Site<Pref>&): Adopt the uniform initialization scheme used in other iterators on graph-related structures. (mln::graph_neighborhood_fwd_piter<P>::operator point): Remove. (mln::graph_neighborhood_fwd_piter<P>::invalidate): Initialize member id_ to -1. (mln::graph_neighborhood_bkd_piter<P>): New class. * mln/core/graph_window_piter.hh: More documentation. (mln::graph_window_fwd_piter<P>::operator point): Remove. (mln::graph_window_fwd_piter<P>::invalidate): Initialize member id_ to -1. (mln::graph_window_bkd_piter<P>): New class. * mln/core/line_graph_window_piter.hh, * mln/core/line_graph_neighborhood_piter.hh: Remove spurious comments. graph_neighborhood_piter.hh | 256 +++++++++++++++++++++++++++++++++++---- graph_window_piter.hh | 239 ++++++++++++++++++++++++++++++++---- line_graph_neighborhood_piter.hh | 10 - line_graph_window_piter.hh | 2 4 files changed, 453 insertions(+), 54 deletions(-) Index: mln/core/line_graph_window_piter.hh --- mln/core/line_graph_window_piter.hh (revision 1779) +++ mln/core/line_graph_window_piter.hh (working copy) @@ -70,7 +70,6 @@ typedef Point_Iterator< self_ > super_; public: - // Make definitions from super class available. enum { dim = P::dim }; typedef line_graph_psite<P> psite; @@ -154,7 +153,6 @@ typedef Point_Iterator< self_ > super_; public: - // Make definitions from super class available. enum { dim = P::dim }; typedef line_graph_psite<P> psite; Index: mln/core/line_graph_neighborhood_piter.hh --- mln/core/line_graph_neighborhood_piter.hh (revision 1779) +++ mln/core/line_graph_neighborhood_piter.hh (working copy) @@ -61,7 +61,7 @@ | line_graph_neighborhood_fwd_piter<P>. | `---------------------------------------*/ - /// \brief Backward iterator on line graph neighborhood. + /// \brief Forward iterator on line graph neighborhood. template <typename P> class line_graph_neighborhood_fwd_piter : public Point_Iterator< line_graph_neighborhood_fwd_piter<P> > // or Iterator<...>? @@ -70,7 +70,6 @@ typedef Point_Iterator< self_ > super_; public: - // Make definitions from super class available. enum { dim = P::dim }; typedef line_graph_psite<P> psite; @@ -157,7 +156,6 @@ typedef Point_Iterator< self_ > super_; public: - // Make definitions from super class available. enum { dim = P::dim }; typedef line_graph_psite<P> psite; @@ -244,9 +242,6 @@ inline line_graph_neighborhood_fwd_piter<P>::line_graph_neighborhood_fwd_piter(const N& /* nbh */, const Point_Site<Pref>& p_ref) - /* FIXME: We should use a routine actually checking the - conversion, since to_psite() checks nothing (as of - 2008-03-05). */ : p_ref_(exact(p_ref).to_psite()), // Initialize psite_ to a dummy value. psite_() @@ -402,9 +397,6 @@ inline line_graph_neighborhood_bkd_piter<P>::line_graph_neighborhood_bkd_piter(const N& /* nbh */, const Point_Site<Pref>& p_ref) - /* FIXME: We should use a routine actually checking the - conversion, since to_psite() checks nothing (as of - 2008-03-05). */ : p_ref_(exact(p_ref).to_psite()), // Initialize psite_ to a dummy value. psite_() Index: mln/core/graph_window_piter.hh --- mln/core/graph_window_piter.hh (revision 1779) +++ mln/core/graph_window_piter.hh (working copy) @@ -37,9 +37,6 @@ - mln::graph_neighborhood_fwd_piter - mln::line_graph_window_fwd_piter - mln::line_graph_neighborhood_fwd_piter. - - and later (when they get implemented): - - mln::graph_window_bkd_piter - mln::graph_neighborhood_bkd_piter - mln::line_graph_window_bkd_piter @@ -49,8 +46,6 @@ # include <mln/core/p_graph.hh> # include <mln/core/graph_psite.hh> -/* FIXME: Doc. */ - /* FIXME: Due to the poor interface of mln::p_graph and mln::util::graph, we show to much implementation details here. Enrich their interfaces to avoid that. */ @@ -66,6 +61,7 @@ | graph_window_fwd_piter<P>. | `----------------------------*/ + /// \brief Forward iterator on graph window. template <typename P> class graph_window_fwd_piter : public Point_Iterator< graph_window_fwd_piter<P> > // or Iterator<...>? @@ -74,41 +70,52 @@ typedef Point_Iterator< self_ > super_; public: - typedef graph_psite<P> psite; - enum { dim = P::dim }; - // FIXME: Dummy value. - typedef void mesh; + typedef graph_psite<P> psite; typedef P point; + typedef mln_coord(P) coord; // FIXME: Dummy typedef. typedef void dpoint; - typedef mln_coord(P) coord; + // FIXME: Dummy value. + typedef void mesh; public: + /// Construction. + /// \{ template <typename W, typename Pref> graph_window_fwd_piter(const W& win, const Point_Site<Pref>& p_ref); + /// \} + /// Manipulation. + /// \{ + /// Test if the iterator is valid. bool is_valid() const; + /// Invalidate the iterator. void invalidate(); + /// Start an iteration. void start(); + /// Go to the next point. void next_(); - + /// Is the piter adjacent or equal to the reference point? bool adjacent_or_equal_to_p_ref_() const; /// Update the internal data of the iterator. void update_(); + /// \} + /// Conversion and accessors. + /// \{ + /// Reference to the corresponding point. const point& to_point() const; - + /// Reference to the corresponding point site. const psite& to_psite() const; - - operator point() const; - + /// Convert the iterator into a line graph psite. operator psite() const; - /// Return the \a i th coordinate of the (iterated) point. + /// Read-only access to the \a i-th coordinate. coord operator[](unsigned i) const; + /// \} private: /// The ``central'' psite of the window. @@ -121,13 +128,86 @@ point p_; }; + /*----------------------------. | graph_window_bkd_piter<P>. | `----------------------------*/ + /// \brief Backward iterator on graph window. + template <typename P> + class graph_window_bkd_piter : + public Point_Iterator< graph_window_bkd_piter<P> > // or Iterator<...>? + { + typedef graph_window_bkd_piter<P> self_; + typedef Point_Iterator< self_ > super_; + + public: + enum { dim = P::dim }; + + typedef graph_psite<P> psite; + typedef P point; + typedef mln_coord(P) coord; + // FIXME: Dummy typedef. + typedef void dpoint; + // FIXME: Dummy value. + typedef void mesh; + + public: + /// Construction. + /// \{ + template <typename W, typename Pref> + graph_window_bkd_piter(const W& win, const Point_Site<Pref>& p_ref); + /// \} + + /// Manipulation. + /// \{ + /// Test if the iterator is valid. + bool is_valid() const; + /// Invalidate the iterator. + void invalidate(); + /// Start an iteration. + void start(); + + /// Go to the next point. + void next_(); + /// Is the piter adjacent or equal to the reference point? + bool adjacent_or_equal_to_p_ref_() const; + /// Update the internal data of the iterator. + void update_(); + /// \} + + /// Conversion and accessors. + /// \{ + /// Reference to the corresponding point. + const point& to_point() const; + /// Reference to the corresponding point site. + const psite& to_psite() const; + /// Convert the iterator into a line graph psite. + operator psite() const; + + /// Read-only access to the \a i-th coordinate. + coord operator[](unsigned i) const; + /// \} + + private: + /// The ``central'' psite of the window. + const psite& p_ref_; + /// An internal iterator on the set of nodes of the underlying graph. + util::node_id id_; + /// The psite corresponding to this iterator. + psite psite_; + /// The point corresponding to this iterator. + point p_; + }; + + # ifndef MLN_INCLUDE_ONLY + /*----------------------------. + | graph_window_fwd_piter<P>. | + `----------------------------*/ + // FIXME: Currently, argument win is ignored. template <typename P> template <typename W, typename Pref> @@ -136,7 +216,7 @@ const Point_Site<Pref>& p_ref) : p_ref_(exact(p_ref).to_psite()), // Initialize psite_ to a dummy value. - psite_(p_ref_.pg(), p_ref_.pg().npoints()), + psite_(), p_() { // Invalidate id_. @@ -156,7 +236,7 @@ void graph_window_fwd_piter<P>::invalidate() { - id_ = p_ref_.pg().npoints(); + id_ = -1; } template <typename P> @@ -187,9 +267,7 @@ window, which is not the case now! (Currently, next_() behaves as win was always an elementary window.) */ do - { ++id_; - } while (is_valid() && !adjacent_or_equal_to_p_ref_()); if (is_valid()) update_(); @@ -233,15 +311,130 @@ template <typename P> inline - graph_window_fwd_piter<P>::operator P() const + graph_window_fwd_piter<P>::operator graph_psite<P>() const { mln_precondition(is_valid()); + return psite_; + } + + template <typename P> + inline + mln_coord(P) + graph_window_fwd_piter<P>::operator[](unsigned i) const + { + assert(i < dim); + return p_[i]; + } + + + /*----------------------------. + | graph_window_bkd_piter<P>. | + `----------------------------*/ + + // FIXME: Currently, argument win is ignored. + template <typename P> + template <typename W, typename Pref> + inline + graph_window_bkd_piter<P>::graph_window_bkd_piter(const W& /* win */, + const Point_Site<Pref>& p_ref) + : p_ref_(exact(p_ref).to_psite()), + // Initialize psite_ to a dummy value. + psite_(), + p_() + { + // Invalidate id_. + invalidate(); + } + + template <typename P> + inline + bool + graph_window_bkd_piter<P>::is_valid() const + { + return id_ < p_ref_.pg().npoints(); + } + + template <typename P> + inline + void + graph_window_bkd_piter<P>::invalidate() + { + id_ = -1; + } + + template <typename P> + inline + void + graph_window_bkd_piter<P>::start() + { + id_ = p_ref_.plg().gr_.nnodes() - 1; + if (!adjacent_or_equal_to_p_ref_()) + next_(); + /* FIXME: This is redundant with the end of next_(), but we might + change the implementation of start_() when we'll fix it later, + and no longer use next_(). */ + if (is_valid()) + update_(); + } + + template <typename P> + inline + void + graph_window_bkd_piter<P>::next_() + { + /* FIXME: This is inefficient. The graph structure should be able + to produce the set of adjacent nodes fast. Boost Graphs + probably provides adequates structures to fetch these + neighbors in constant time. */ + /* FIXME: Moreover, the behavior of next shall depend on the + window, which is not the case now! (Currently, next_() behaves + as win was always an elementary window.) */ + do + --id_; + while (is_valid() && !adjacent_or_equal_to_p_ref_()); + if (is_valid()) + update_(); + } + + + template <typename P> + inline + bool + graph_window_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const + { + return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_); + } + + template <typename P> + inline + void + graph_window_bkd_piter<P>::update_() + { + // Update psite_. + psite_ = graph_psite<P>(p_ref_.pg(), id_); + // Update p_. + p_ = p_ref_.pg().point_from_id(id_); + } + + template <typename P> + inline + const P& + graph_window_bkd_piter<P>::to_point() const + { return p_; } template <typename P> inline - graph_window_fwd_piter<P>::operator graph_psite<P>() const + const graph_psite<P>& + graph_window_bkd_piter<P>::to_psite() const + { + return psite_; + } + + template <typename P> + inline + graph_window_bkd_piter<P>::operator graph_psite<P>() const { mln_precondition(is_valid()); return psite_; @@ -250,7 +443,7 @@ template <typename P> inline mln_coord(P) - graph_window_fwd_piter<P>::operator[](unsigned i) const + graph_window_bkd_piter<P>::operator[](unsigned i) const { assert(i < dim); return p_[i]; Index: mln/core/graph_neighborhood_piter.hh --- mln/core/graph_neighborhood_piter.hh (revision 1779) +++ mln/core/graph_neighborhood_piter.hh (working copy) @@ -37,9 +37,6 @@ - mln::graph_neighborhood_fwd_piter - mln::line_graph_window_fwd_piter - mln::line_graph_neighborhood_fwd_piter. - - and later (when they get implemented): - - mln::graph_window_bkd_piter - mln::graph_neighborhood_bkd_piter - mln::line_graph_window_bkd_piter @@ -49,8 +46,6 @@ # include <mln/core/p_graph.hh> # include <mln/core/graph_psite.hh> -/* FIXME: Doc. */ - /* FIXME: Due to the poor interface of mln::p_graph and mln::util::graph, we show to much implementation details here. Enrich their interfaces to avoid that. */ @@ -66,6 +61,7 @@ | graph_neighborhood_fwd_piter<P>. | `----------------------------------*/ + /// \brief Forward iterator on graph neighborhood. template <typename P> class graph_neighborhood_fwd_piter : public Point_Iterator< graph_neighborhood_fwd_piter<P> > // or Iterator<...>? @@ -74,39 +70,49 @@ typedef Point_Iterator< self_ > super_; public: - typedef graph_psite<P> psite; - enum { dim = P::dim }; - // FIXME: Dummy value. - typedef void mesh; + typedef graph_psite<P> psite; typedef P point; + typedef mln_coord(P) coord; // FIXME: Dummy typedef. typedef void dpoint; - typedef mln_coord(P) coord; + // FIXME: Dummy value. + typedef void mesh; public: + /// Construction. + /// \{ template <typename N, typename Pref> graph_neighborhood_fwd_piter(const N& nbh, const Point_Site<Pref>& p_ref); + /// \} + /// Manipulation. + /// \{ + /// Test if the iterator is valid. bool is_valid() const; + /// Invalidate the iterator. void invalidate(); + /// Start an iteration. void start(); + /// Go to the next point. void next_(); + /// Is the piter adjacent or equal to the reference point? bool adjacent_or_equal_to_p_ref_() const; /// Update the internal data of the iterator. void update_(); + /// \} + /// Conversion and accessors. + /// Reference to the corresponding point. const point& to_point() const; - + /// Reference to the corresponding point site. const psite& to_psite() const; - - operator point() const; - + /// Convert the iterator into a line graph psite. operator psite() const; - /// Return the \a i th coordinate of the (iterated) point. + /// Read-only access to the \a i-th coordinate. coord operator[](unsigned i) const; private: @@ -120,13 +126,84 @@ point p_; }; + /*----------------------------------. | graph_neighborhood_bkd_piter<P>. | `----------------------------------*/ + /// \brief Backward iterator on graph neighborhood. + template <typename P> + class graph_neighborhood_bkd_piter : + public Point_Iterator< graph_neighborhood_bkd_piter<P> > // or Iterator<...>? + { + typedef graph_neighborhood_bkd_piter<P> self_; + typedef Point_Iterator< self_ > super_; + + public: + enum { dim = P::dim }; + + typedef graph_psite<P> psite; + typedef P point; + typedef mln_coord(P) coord; + // FIXME: Dummy typedef. + typedef void dpoint; + // FIXME: Dummy value. + typedef void mesh; + + public: + /// Construction. + /// \{ + template <typename N, typename Pref> + graph_neighborhood_bkd_piter(const N& nbh, const Point_Site<Pref>& p_ref); + /// \} + + /// Manipulation. + /// \{ + /// Test if the iterator is valid. + bool is_valid() const; + /// Invalidate the iterator. + void invalidate(); + /// Start an iteration. + void start(); + + /// Go to the next point. + void next_(); + /// Is the piter adjacent or equal to the reference point? + bool adjacent_or_equal_to_p_ref_() const; + /// Update the internal data of the iterator. + void update_(); + /// \} + + /// Conversion and accessors. + /// Reference to the corresponding point. + const point& to_point() const; + /// Reference to the corresponding point site. + const psite& to_psite() const; + /// Convert the iterator into a line graph psite. + operator psite() const; + + /// Read-only access to the \a i-th coordinate. + coord operator[](unsigned i) const; + + private: + /// The ``central'' psite of the neighborhood. + const psite& p_ref_; + /// An internal iterator on the set of nodes of the underlying graph. + util::node_id id_; + /// The psite corresponding to this iterator. + psite psite_; + /// The point corresponding to this iterator. + point p_; + }; + + # ifndef MLN_INCLUDE_ONLY + /*----------------------------------. + | graph_neighborhood_fwd_piter<P>. | + `----------------------------------*/ + // FIXME: Currently, argument nbh is ignored. template <typename P> template <typename N, typename Pref> @@ -135,7 +212,7 @@ const Point_Site<Pref>& p_ref) : p_ref_(exact(p_ref).to_psite()), // Initialize psite_ to a dummy value. - psite_(p_ref_.pg(), p_ref_.pg().npoints()), + psite_(), p_() { // Invalidate id_. @@ -158,7 +235,7 @@ void graph_neighborhood_fwd_piter<P>::invalidate() { - id_ = p_ref_.pg().gr_.nnodes(); + id_ = -1 } template <typename P> @@ -254,15 +331,154 @@ template <typename P> inline - graph_neighborhood_fwd_piter<P>::operator P() const + graph_neighborhood_fwd_piter<P>::operator graph_psite<P>() const { mln_precondition(is_valid()); + return psite_; + } + + template <typename P> + inline + mln_coord(P) + graph_neighborhood_fwd_piter<P>::operator[](unsigned i) const + { + assert(i < dim); + return p_[i]; + } + + + /*----------------------------------. + | graph_neighborhood_bkd_piter<P>. | + `----------------------------------*/ + + // FIXME: Currently, argument nbh is ignored. + template <typename P> + template <typename N, typename Pref> + inline + graph_neighborhood_bkd_piter<P>::graph_neighborhood_bkd_piter(const N& /* nbh */, + const Point_Site<Pref>& p_ref) + : p_ref_(exact(p_ref).to_psite()), + // Initialize psite_ to a dummy value. + psite_(), + p_() + { + // Invalidate id_. + invalidate(); + } + + template <typename P> + inline + bool + graph_neighborhood_bkd_piter<P>::is_valid() const + { + // FIXME: We depend too much on the implementation of util::graph + // here. The util::graph should provide the service to abstract + // these manipulations. + return id_ < p_ref_.pg().gr_.nnodes(); + } + + template <typename P> + inline + void + graph_neighborhood_bkd_piter<P>::invalidate() + { + id_ = -1; + } + + template <typename P> + inline + void + graph_neighborhood_bkd_piter<P>::start() + { + id_ = p_ref_.plg().gr_.nnodes() - 1; + if (!adjacent_or_equal_to_p_ref_()) + next_(); + /* FIXME: This is redundant with the end of next_(), but we might + change the implementation of start_() when we'll fix it later, + and no longer use next_(). */ + if (is_valid()) + update_(); + } + + template <typename P> + inline + void + graph_neighborhood_bkd_piter<P>::next_() + { + /* FIXME: This is inefficient. The graph structure should be able + to produce the set of adjacent nodes fast. Boost Graphs + probably provides adequates structures to fetch these + neighbors in constant time. */ + /* FIXME: Moreover, the behavior of next shall depend on the + neighborhood, which is not the case now! (Currently, next_() behaves + as nbh was always an elementary neighborhood.) */ + do + --id_; + while (is_valid() && !adjacent_or_equal_to_p_ref_()); + if (is_valid()) + update_(); + } + + template <typename P> + inline + bool + graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const + { + // FIXME: Likewise, this is inefficient. + + // Check wether the iterator points to P_REF_. + if (id_ == p_ref_.id()) + return true; + + // Check whether the iterator is among the neighbors of P_REF_. + { + // Paranoid assertion. + assert (p_ref_.id() < p_ref_.pg().gr_.nnodes()); + // FIXME: This is too low-level. Yet another service the graph + // should provide. + typedef std::vector<util::node_id> adjacency_type; + const adjacency_type& p_ref_neighbs = + p_ref_.pg().gr_.nodes()[p_ref_.id()]->edges; + adjacency_type::const_iterator j = + std::find (p_ref_neighbs.begin(), p_ref_neighbs.end(), id_); + if (j != p_ref_neighbs.end()) + return true; + } + + // Otherwise, the iterator is not adjacent to P_REF_. + return false; + } + + template <typename P> + inline + void + graph_neighborhood_bkd_piter<P>::update_() + { + // Update psite_. + psite_ = graph_psite<P>(p_ref_.pg(), id_); + // Update p_. + p_ = p_ref_.pg().gr_.node_data(id_); + } + + template <typename P> + inline + const P& + graph_neighborhood_bkd_piter<P>::to_point() const + { return p_; } template <typename P> inline - graph_neighborhood_fwd_piter<P>::operator graph_psite<P>() const + const graph_psite<P>& + graph_neighborhood_bkd_piter<P>::to_psite() const + { + return psite_; + } + + template <typename P> + inline + graph_neighborhood_bkd_piter<P>::operator graph_psite<P>() const { mln_precondition(is_valid()); return psite_; @@ -271,7 +487,7 @@ template <typename P> inline mln_coord(P) - graph_neighborhood_fwd_piter<P>::operator[](unsigned i) const + graph_neighborhood_bkd_piter<P>::operator[](unsigned i) const { assert(i < dim); return p_[i];