1800: Fix some memory management problems w.r.t. graph-based images.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Fix some memory management problems w.r.t. graph-based images. * mln/core/p_graph.hh (mln::p_graph<P>::gr_): Handle the underlying graph as a tracked pointer. (mln::p_graph<P>::p_graph(const graph&)) (mln::p_graph<P>::nnodes) (mln::p_graph<P>::point_from_id) (mln::p_graph<P>::node1, mln::p_graph<P>::node2) (mln::p_graph<P>::has(const psite&)) (mln::p_graph<P>::adjacent_or_equal) (mln::operator==(const p_graph<P>&, const p_graph<P>&)): Adjust. * mln/core/graph_image.hh (mln::internal::data_< graph_image<P, V> >::pg_): Handle the p_graph by copy, as the tracked pointer takes care of the memory management. (mln::graph_image<P, V>::operator()(const graph_psite<P>&)): Adjust operators. * mln/core/graph_psite.hh, * mln/core/graph_window_piter.hh: Adjust. * mln/core/graph_neighborhood_piter.hh: Likewise. (mln::graph_neighborhood_fwd_piter<P>::adjacent_or_equal_to_p_ref_) (mln::graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_): Simplify using mln::p_graph<P>::adjacent_or_equal. * mln/core/p_line_graph.hh (mln::p_line_graph<P>::gr_): Handle the underlying graph as a tracked pointer. (mln::p_line_graph<P>::p_line_graph(const graph&)) (mln::p_line_graph<P>::nnodes, mln::p_line_graph<P>::nedges) (mln::p_line_graph<P>::has(const psite&)) (mln::operator==(const p_line_graph<P>&, const p_line_graph<P>&)): Adjust. * mln/core/line_graph_image.hh (mln::internal::data_< line_graph_image<P, V> >::plg_): Handle the p_line_graph by copy, as the tracked pointer takes care of the memory management. (mln::line_graph_image<P, V>::operator()(const line_graph_psite<P>&)): Adjust operators. * mln/core/line_graph_psite.hh, * mln/core/line_graph_neighborhood_piter.hh, * mln/core/line_graph_window_piter.hh: Adjust. graph_image.hh | 11 ++----- graph_neighborhood_piter.hh | 58 ++++----------------------------------- graph_psite.hh | 2 - graph_window_piter.hh | 2 - line_graph_image.hh | 11 ++----- line_graph_neighborhood_piter.hh | 32 +++++++++++---------- line_graph_psite.hh | 6 ++-- line_graph_window_piter.hh | 32 +++++++++++---------- p_graph.hh | 42 ++++++++++++++++------------ p_line_graph.hh | 30 ++++++++++++-------- 10 files changed, 94 insertions(+), 132 deletions(-) Index: mln/core/p_graph.hh --- mln/core/p_graph.hh (revision 1799) +++ mln/core/p_graph.hh (working copy) @@ -31,6 +31,7 @@ # include <mln/core/concept/point_site.hh> # include <mln/core/internal/point_set_base.hh> # include <mln/accu/bbox.hh> +# include <mln/util/tracked_ptr.hh> # include <mln/util/graph.hh> # include <mln/core/graph_psite.hh> # include <mln/core/p_graph_piter.hh> @@ -50,8 +51,13 @@ { typedef util::graph<P> graph; - /// Construct a graph psite set from a graph of points. - p_graph (graph& gr); + /// \brief Construct a graph psite set from a graph of points. + /// + /// \param gr The graph upon which the graph psite set is built. + /// + /// \a gr is \em copied internally, so that the graph psite set is + /// still valid after the initial graph has been removed. + p_graph (const graph& gr); /// Point_Site associated type. typedef graph_psite<P> psite; @@ -102,7 +108,7 @@ // FIXME: Should be private. public: - graph gr_; + util::tracked_ptr<graph> gr_; // FIXME: (Roland) Is it really useful/needed? /* 2007-12-19: It seems so, since graph_image must implement a method named bbox(). Now the question is: should each image type have a @@ -114,8 +120,8 @@ /// \brief Comparison between two mln::p_graph's. /// - /// Two mln::p_graph's are considered equal if they have the - /// same address. + /// Two mln::p_graph's are considered equal if they share the + /// same graph. template <typename P> bool operator==(const p_graph<P>& lhs, const p_graph<P>& rhs); @@ -125,14 +131,14 @@ template<typename P> inline - p_graph<P>::p_graph (util::graph<P>& gr) - : gr_ (gr) + p_graph<P>::p_graph (const util::graph<P>& gr) + : gr_ (new util::graph<P>(gr)) { // FIXME: Warning: if the underlying graph is updated later, this // won't be taken into account by this p_graph! accu::bbox<P> a; for (unsigned i = 0; i < npoints(); ++i) - a.take(gr_.node_data(i)); + a.take(gr_->node_data(i)); bb_ = a.to_result(); } @@ -149,7 +155,7 @@ std::size_t p_graph<P>::nnodes() const { - return this->gr_.nnodes(); + return this->gr_->nnodes(); } template<typename P> @@ -157,7 +163,7 @@ std::size_t p_graph<P>::nedges() const { - return this->gr_.nedges(); + return this->gr_->nedges(); } template<typename P> @@ -177,28 +183,28 @@ // Check whether P is compatible with this psite set. (&p.pg() == this) && // Check that the node id of P belongs to the range of valid node ids. - (p.id() < gr_.nnodes()); + (p.id() < gr_->nnodes()); } template <typename P> const P& p_graph<P>::point_from_id(const util::node_id& id) const { - return this->gr_.node_data(id); + return this->gr_->node_data(id); } template <typename P> P& p_graph<P>::point_from_id(const util::node_id& id) { - return this->gr_.node_data(id); + return this->gr_->node_data(id); } template <typename P> const P& p_graph<P>::node1(const util::edge_id& e) const { - util::node_id n1 = this->gr_.edge(e).n1(); + util::node_id n1 = this->gr_->edge(e).n1(); return this->point_from_id(n1); } @@ -206,7 +212,7 @@ const P& p_graph<P>::node2(const util::edge_id& e) const { - util::node_id n2 = this->gr_.edge(e).n2(); + util::node_id n2 = this->gr_->edge(e).n2(); return this->point_from_id(n2); } @@ -225,7 +231,7 @@ p_graph<P>::adjacent_or_equal(const util::node_id& lhs, const util::node_id& rhs) const { - // FIXME: Likewise, this is inefficient. + // FIXME: This is inefficient. assert (lhs < this->npoints()); assert (rhs < this->npoints()); @@ -235,7 +241,7 @@ // Check whether the iterator is among the neighbors of P_REF_. typedef std::vector<util::node_id> adjacency_type; - const adjacency_type& lhs_neighbs = gr_.nodes()[lhs]->edges; + const adjacency_type& lhs_neighbs = gr_->nodes()[lhs]->edges; adjacency_type::const_iterator j = std::find (lhs_neighbs.begin(), lhs_neighbs.end(), rhs); @@ -264,7 +270,7 @@ bool operator==(const p_graph<P>& lhs, const p_graph<P>& rhs) { - return &lhs == &rhs; + return lhs.gr_.ptr_ == rhs.gr_.ptr_; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/graph_image.hh --- mln/core/graph_image.hh (revision 1799) +++ mln/core/graph_image.hh (working copy) @@ -56,12 +56,7 @@ data_(const p_graph<P>& g, const std::vector<V>& val); std::vector<V> val_; - /* The graph point set is handled by address, so that we can - check the compatibility of images w.r.t. to their point - sites. We could use a safer (and more complex) facility to - ensure (memory) equality of line graph point sets, but using - addresses is simple and efficient enough for the moment. */ - const p_graph<P>& pg_; + const p_graph<P> pg_; }; } // end of namespace mln::internal @@ -239,7 +234,7 @@ typename graph_image<P, V>::rvalue graph_image<P, V>::operator()(const graph_psite<P>& p) const { - mln_precondition(&p.pg() == &this->data_->pg_); + mln_precondition(p.pg() == this->data_->pg_); mln_precondition(p.id() < this->data_->val_.size()); return this->data_->val_[p.id()]; } @@ -249,7 +244,7 @@ typename graph_image<P, V>::lvalue graph_image<P, V>::operator()(const graph_psite<P>& p) { - mln_precondition(&p.pg() == &this->data_->pg_); + mln_precondition(p.pg() == this->data_->pg_); mln_precondition(p.id() < this->data_->val_.size()); return this->data_->val_[p.id()]; } Index: mln/core/graph_psite.hh --- mln/core/graph_psite.hh (revision 1799) +++ mln/core/graph_psite.hh (working copy) @@ -139,7 +139,7 @@ bool graph_psite<P>::is_valid_() const { - return pg_ && id_ < pg_->gr_.nnodes(); + return pg_ && id_ < pg_->gr_->nnodes(); } template<typename P> Index: mln/core/graph_window_piter.hh --- mln/core/graph_window_piter.hh (revision 1799) +++ mln/core/graph_window_piter.hh (working copy) @@ -367,7 +367,7 @@ void graph_window_bkd_piter<P>::start() { - id_ = p_ref_.plg().gr_.nnodes() - 1; + 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 Index: mln/core/graph_neighborhood_piter.hh --- mln/core/graph_neighborhood_piter.hh (revision 1799) +++ mln/core/graph_neighborhood_piter.hh (working copy) @@ -227,7 +227,7 @@ // 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(); + return id_ < p_ref_.pg().gr_->nnodes(); } template <typename P> @@ -277,29 +277,7 @@ bool graph_neighborhood_fwd_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; + return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_); } template <typename P> @@ -310,7 +288,7 @@ // Update psite_. psite_ = graph_psite<P>(p_ref_.pg(), id_); // Update p_. - p_ = p_ref_.pg().gr_.node_data(id_); + p_ = p_ref_.pg().gr_->node_data(id_); } template <typename P> @@ -374,7 +352,7 @@ // 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(); + return id_ < p_ref_.pg().gr_->nnodes(); } template <typename P> @@ -390,7 +368,7 @@ void graph_neighborhood_bkd_piter<P>::start() { - id_ = p_ref_.plg().gr_.nnodes() - 1; + 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 @@ -424,29 +402,7 @@ 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; + return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_); } template <typename P> @@ -457,7 +413,7 @@ // Update psite_. psite_ = graph_psite<P>(p_ref_.pg(), id_); // Update p_. - p_ = p_ref_.pg().gr_.node_data(id_); + p_ = p_ref_.pg().gr_->node_data(id_); } template <typename P> Index: mln/core/p_line_graph.hh --- mln/core/p_line_graph.hh (revision 1799) +++ mln/core/p_line_graph.hh (working copy) @@ -32,6 +32,7 @@ # include <mln/core/internal/point_set_base.hh> # include <mln/accu/bbox.hh> # include <mln/util/graph.hh> +# include <mln/util/tracked_ptr.hh> # include <mln/core/line_graph_psite.hh> # include <mln/core/p_line_graph_piter.hh> @@ -54,8 +55,13 @@ { typedef util::graph<P> graph; - /// Construct a line graph psite set from a graph of points. - p_line_graph (graph& gr); + /// \brief Construct a line graph psite set from a graph of points. + /// + /// \param gr The graph upon which the line graph psite set is built. + /// + /// \a gr is \em copied internally, so that the line graph psite + /// set is still valid after the initial graph has been removed. + p_line_graph (const graph& gr); /// Point_Site associated type. typedef line_graph_psite<P> psite; @@ -82,7 +88,7 @@ bool has(const psite& p) const; // FIXME: Should be private. - graph gr_; + util::tracked_ptr<graph> gr_; // FIXME: (Roland) Is it really useful/needed? /* 2007-12-19: It seems so, since graph_image must implement a method named bbox(). Now the question is: should each image @@ -93,8 +99,8 @@ /// \brief Comparison between two mln::p_line_graph's. /// - /// Two mln::p_line_graph's are considered equal if they have the - /// same address. + /// Two mln::p_line_graph's are considered equal if they share the + /// same graph. template <typename P> bool operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs); @@ -104,14 +110,14 @@ template<typename P> inline - p_line_graph<P>::p_line_graph (util::graph<P>& gr) - : gr_ (gr) + p_line_graph<P>::p_line_graph (const util::graph<P>& gr) + : gr_ (new util::graph<P>(gr)) { // FIXME: Warning: if the underlying graph is updated later, this // won't be taken into account by this p_line_graph! accu::bbox<P> a; for (unsigned i = 0; i < nnodes(); ++i) - a.take(gr_.node_data(i)); + a.take(gr_->node_data(i)); bb_ = a.to_result(); } @@ -128,7 +134,7 @@ std::size_t p_line_graph<P>::nnodes() const { - return this->gr_.nnodes(); + return this->gr_->nnodes(); } template<typename P> @@ -136,7 +142,7 @@ std::size_t p_line_graph<P>::nedges() const { - return this->gr_.nedges(); + return this->gr_->nedges(); } template<typename P> @@ -156,7 +162,7 @@ // Check whether P is compatible with this psite set. (&p.plg() == this) && // Check that the edge id of P belongs to the range of valid edge ids. - (p.id() < gr_.nedges()); + (p.id() < gr_->nedges()); } @@ -164,7 +170,7 @@ bool operator==(const p_line_graph<P>& lhs, const p_line_graph<P>& rhs) { - return &lhs == &rhs; + return lhs.gr_.ptr_ == rhs.gr_.ptr_; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/line_graph_image.hh --- mln/core/line_graph_image.hh (revision 1799) +++ mln/core/line_graph_image.hh (working copy) @@ -72,12 +72,7 @@ std::vector<V> node_val_; std::vector<V> edge_val_; - /* The line graph point set is handled by address, so that we - can check the compatibility of images w.r.t. to their point - sites. We could use a safer (and more complex) facility to - ensure (memory) equality of line graph point sets, but using - addresses is simple and efficient enough for the moment. */ - const p_line_graph<P>& plg_; + const p_line_graph<P> plg_; }; } // end of namespace mln::internal @@ -273,7 +268,7 @@ typename line_graph_image<P, V>::rvalue line_graph_image<P, V>::operator()(const line_graph_psite<P>& p) const { - mln_precondition(&p.plg() == &this->data_->plg_); + mln_precondition(p.plg() == this->data_->plg_); mln_precondition(p.id() < this->data_->edge_val_.size()); return this->data_->edge_val_[p.id()]; } @@ -283,7 +278,7 @@ typename line_graph_image<P, V>::lvalue line_graph_image<P, V>::operator()(const line_graph_psite<P>& p) { - mln_precondition(&p.plg() == &this->data_->plg_); + mln_precondition(p.plg() == this->data_->plg_); mln_precondition(p.id() < this->data_->edge_val_.size()); return this->data_->edge_val_[p.id()]; } Index: mln/core/line_graph_psite.hh --- mln/core/line_graph_psite.hh (revision 1799) +++ mln/core/line_graph_psite.hh (working copy) @@ -176,7 +176,7 @@ bool line_graph_psite<P>::is_valid_() const { - return plg_ && id_ < plg_->gr_.nedges(); + return plg_ && id_ < plg_->gr_->nedges(); } template<typename P> @@ -228,7 +228,7 @@ line_graph_psite<P>::first() const { mln_assertion(is_valid_()); - return plg().gr_.node_data(plg().gr_.edge(id_).n1()); + return plg().gr_->node_data(plg().gr_->edge(id_).n1()); } template<typename P> @@ -237,7 +237,7 @@ line_graph_psite<P>::second() const { mln_assertion(is_valid_()); - return plg().gr_.node_data(plg().gr_.edge(id_).n2()); + return plg().gr_->node_data(plg().gr_->edge(id_).n2()); } Index: mln/core/line_graph_neighborhood_piter.hh --- mln/core/line_graph_neighborhood_piter.hh (revision 1799) +++ mln/core/line_graph_neighborhood_piter.hh (working copy) @@ -258,7 +258,7 @@ // 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_.plg().gr_.nedges(); + return id_ < p_ref_.plg().gr_->nedges(); } template <typename P> @@ -315,19 +315,20 @@ // Check whether the iterator is among the neighbors of P_REF_. { // Paranoid assertion. - assert (p_ref_.id() < p_ref_.plg().gr_.nedges()); + assert (p_ref_.id() < p_ref_.plg().gr_->nedges()); /* FIXME: We should have a convenient shortcut for these repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr() or g() in this class. */ - const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_; + const util::tracked_ptr<typename p_line_graph<P>::graph>& gr = + p_ref_.plg().gr_; // Check whether the edge this iterator points to is adjacent to // the one p_ref points to, by comparing their ajacent nodes. /* FIXME: This is too low-level. Yet another service the graph // should provide. */ - if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2()) + if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2()) return true; } @@ -413,7 +414,7 @@ // 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_.plg().gr_.nedges(); + return id_ < p_ref_.plg().gr_->nedges(); } template <typename P> @@ -429,7 +430,7 @@ void line_graph_neighborhood_bkd_piter<P>::start() { - id_ = p_ref_.plg().gr_.nedges() - 1; + id_ = p_ref_.plg().gr_->nedges() - 1; if (!adjacent_or_equal_to_p_ref_()) next_(); /* FIXME: This is redundant with the end of next_(), but we might @@ -470,19 +471,20 @@ // Check whether the iterator is among the neighbors of P_REF_. { // Paranoid assertion. - assert (p_ref_.id() < p_ref_.plg().gr_.nedges()); + assert (p_ref_.id() < p_ref_.plg().gr_->nedges()); /* FIXME: We should have a convenient shortcut for these repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr() or g() in this class. */ - const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_; + const util::tracked_ptr<typename p_line_graph<P>::graph>& gr = + p_ref_.plg().gr_; // Check whether the edge this iterator points to is adjacent to // the one p_ref points to, by comparing their ajacent nodes. /* FIXME: This is too low-level. Yet another service the graph // should provide. */ - if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2()) + if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2()) return true; } Index: mln/core/line_graph_window_piter.hh --- mln/core/line_graph_window_piter.hh (revision 1799) +++ mln/core/line_graph_window_piter.hh (working copy) @@ -252,7 +252,7 @@ // 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_.plg().gr_.nedges(); + return id_ < p_ref_.plg().gr_->nedges(); } template <typename P> @@ -309,19 +309,20 @@ // Check whether the iterator is among the neighbors of P_REF_. { // Paranoid assertion. - assert (p_ref_.id() < p_ref_.plg().gr_.nedges()); + assert (p_ref_.id() < p_ref_.plg().gr_->nedges()); /* FIXME: We should have a convenient shortcut for these repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr() or g() in this class. */ - const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_; + const util::tracked_ptr<typename p_line_graph<P>::graph>& gr = + p_ref_.plg().gr_; // Check whether the edge this iterator points to is adjacent to // the one p_ref points to, by comparing their ajacent nodes. /* FIXME: This is too low-level. Yet another service the graph // should provide. */ - if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2()) + if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2()) return true; } @@ -406,7 +407,7 @@ // 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_.plg().gr_.nedges(); + return id_ < p_ref_.plg().gr_->nedges(); } template <typename P> @@ -422,7 +423,7 @@ void line_graph_window_bkd_piter<P>::start() { - id_ = p_ref_.plg().gr_.nedges() - 1; + id_ = p_ref_.plg().gr_->nedges() - 1; if (!adjacent_or_equal_to_p_ref_()) next_(); /* FIXME: This is redundant with the end of next_(), but we might @@ -463,19 +464,20 @@ // Check whether the iterator is among the neighbors of P_REF_. { // Paranoid assertion. - assert (p_ref_.id() < p_ref_.plg().gr_.nedges()); + assert (p_ref_.id() < p_ref_.plg().gr_->nedges()); /* FIXME: We should have a convenient shortcut for these repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr() or g() in this class. */ - const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_; + const util::tracked_ptr<typename p_line_graph<P>::graph>& gr = + p_ref_.plg().gr_; // Check whether the edge this iterator points to is adjacent to // the one p_ref points to, by comparing their ajacent nodes. /* FIXME: This is too low-level. Yet another service the graph // should provide. */ - if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() || - gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2()) + if (gr->edge(id_).n1() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n1() == gr->edge(p_ref_.id()).n2() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n1() || + gr->edge(id_).n2() == gr->edge(p_ref_.id()).n2()) return true; }
participants (1)
-
Roland Levillain