https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Fix bgraph_image construction bug.
* tests/core/bgraph_image.cc,
* tests/core/p_bgraph.cc: update the tests.
* mln/core/p_bgraph_piter.hh,
* mln/core/bgraph_image.hh,
* mln/core/p_bgraph.hh,
* mln/core/bgraph_psite.hh: fix the bug (thanks to Theo).
mln/core/bgraph_image.hh | 29 ++++++++++-------------------
mln/core/bgraph_psite.hh | 4 +---
mln/core/p_bgraph.hh | 37 ++++++++++++++++++-------------------
mln/core/p_bgraph_piter.hh | 22 ++++++++++++----------
tests/core/bgraph_image.cc | 23 ++++++++++++++++++-----
tests/core/p_bgraph.cc | 2 +-
6 files changed, 60 insertions(+), 57 deletions(-)
Index: tests/core/bgraph_image.cc
--- tests/core/bgraph_image.cc (revision 1764)
+++ tests/core/bgraph_image.cc (working copy)
@@ -29,8 +29,13 @@
/// \brief Tests on mln::bgraph_image.
#include <vector>
-#include <mln/core/point2d.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/core/image2d.hh>
#include <mln/core/bgraph_image.hh>
+#include <mln/level/fill.hh>
+#include <mln/level/paste.hh>
+#include <mln/debug/println.hh>
@@ -56,7 +61,7 @@
const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
// declare a graph object
- Graph g(num_vertices);
+ Graph& g = *new Graph(num_vertices);
// add the edges to the graph object
for (int i = 0; i < num_edges; ++i)
@@ -85,10 +90,18 @@
values.push_back(4);
values.push_back(5);
- ima_type ima(g, values);
+ ima_type ima(&g, values);
mln_piter_(ima_type) p(ima.domain());
for_all(p)
- std::cout << ima(p) << std::endl;
+ std::cout << p << ' ' << ima(p) << std::endl;
+
+ {
+ using value::int_u8;
+ image2d<int_u8> ima_(ima.bbox());
+ level::fill(ima_, 0);
+ level::paste(ima, ima_);
+ debug::println(ima_);
+ }
- return 0;
+ delete &g;
}
Index: tests/core/p_bgraph.cc
--- tests/core/p_bgraph.cc (revision 1764)
+++ tests/core/p_bgraph.cc (working copy)
@@ -73,7 +73,7 @@
`-----------*/
/// Creation
- p_bgraph<point2d> pset(g);
+ p_bgraph<point2d> pset(&g);
/// Iterator
p_bgraph_piter_<point2d> p(pset);
Index: mln/core/p_bgraph_piter.hh
--- mln/core/p_bgraph_piter.hh (revision 1764)
+++ mln/core/p_bgraph_piter.hh (working copy)
@@ -106,6 +106,7 @@
private:
iterators_type_ iterators_;
+ typename p_bgraph<P>::node_iterator cur_;
};
@@ -120,9 +121,7 @@
psite_(pg, pg_.npoints()),
p_()
{
- // Initialize the iterators
- start();
-
+ iterators_ = boost::vertices(pg_.to_graph());
// Invalidate id_.
invalidate();
}
@@ -140,7 +139,7 @@
bool
p_bgraph_piter_<P>::is_valid() const
{
- return iterators_.first != iterators_.second;
+ return cur_ != iterators_.second;
}
template<typename P>
@@ -148,7 +147,7 @@
void
p_bgraph_piter_<P>::invalidate()
{
- iterators_.first == iterators_.second;
+ cur_ = iterators_.second; // Past the end iterator.
}
template<typename P>
@@ -156,8 +155,9 @@
void
p_bgraph_piter_<P>::start()
{
+ cur_ = iterators_.first;
/// FIXME: Hide implementation details?
- iterators_ = boost::vertices(pg_.to_graph());
+ if (is_valid())
update_();
}
@@ -166,7 +166,8 @@
void
p_bgraph_piter_<P>::next_()
{
- ++iterators_.first;
+ ++cur_;
+ if (is_valid())
update_();
}
@@ -176,9 +177,9 @@
p_bgraph_piter_<P>::update_()
{
// Update psite_.
- psite_ = bgraph_psite<P>(pg_, *iterators_.first);
+ psite_ = bgraph_psite<P>(pg_, *cur_);
// Update p_.
- p_ = pg_.point_from_id(*iterators_.first);
+ p_ = pg_.point_from_id(*cur_);
}
template<typename P>
@@ -233,7 +234,8 @@
p_bgraph_piter_<P>::operator bgraph_psite<P>() const
{
mln_precondition(is_valid());
- return psite_;
+ bgraph_psite<P> tmp(pg_, *cur_);
+ return tmp; // psite_;
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/bgraph_image.hh
--- mln/core/bgraph_image.hh (revision 1764)
+++ mln/core/bgraph_image.hh (working copy)
@@ -53,15 +53,15 @@
template <typename P, typename V>
struct data_< bgraph_image<P, V> >
{
+ /// Data stores a **copy** of the pset g.
+ /// But, the pset g and the data_ copy will shared the same
+ /// underlaying graph.
data_(const p_bgraph<P>& g, const std::vector<V>& val);
+
+ p_bgraph<P> pg_;
+
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_bgraph<P>& pg_;
};
} // end of namespace mln::internal
@@ -76,7 +76,6 @@
{
typedef trait::image::category::primary category;
- // FIXME: Is that right?
typedef trait::image::access::random access;
typedef typename trait::image::space_from_point<P>::ret space;
typedef trait::image::size::regular size;
@@ -85,7 +84,6 @@
typedef trait::image::border::none border;
typedef trait::image::data::stored data;
typedef trait::image::io::read_write io;
- // FIXME: Is that right?
typedef trait::image::speed::fast speed;
};
@@ -150,8 +148,6 @@
const std::vector<V>& node_values() const;
/// \}
- /* FIXME: Do we want to provide these two methods? (at least, in
- the interface of the class? */
/// Return the point of the first node adjacent to the edge with
/// id \a e.
@@ -191,8 +187,8 @@
inline
data_< bgraph_image<P, V> >::data_(const p_bgraph<P>& g,
const std::vector<V>& val)
- : val_ (val),
- pg_ (g)
+ : pg_ (g),
+ val_ (val)
{
}
@@ -228,11 +224,6 @@
void
bgraph_image<P, V>::init_(const p_bgraph<P>& g, const
std::vector<V>& val)
{
- /* FIXME: We leak memory here: calling init_ twice loses the
- previous content pointed by data_.
-
- We should definitely write down formal guidelines on
- initialization and memory management in general! */
this->data_ = new internal::data_< bgraph_image<P, V> > (g, val);
}
@@ -245,7 +236,7 @@
typename bgraph_image<P, V>::rvalue
bgraph_image<P, V>::operator()(const bgraph_psite<P>& p) const
{
- mln_precondition(&p.pg() == &this->data_->pg_);
+ mln_precondition(&p.pg().to_graph() == &this->data_->pg_.to_graph());
mln_precondition(p.id() < this->data_->val_.size());
return this->data_->val_[p.id()];
}
@@ -255,7 +246,7 @@
typename bgraph_image<P, V>::lvalue
bgraph_image<P, V>::operator()(const bgraph_psite<P>& p)
{
- mln_precondition(&p.pg() == &this->data_->pg_);
+ mln_precondition(&p.pg().to_graph() == &this->data_->pg_.to_graph());
mln_precondition(p.id() < this->data_->val_.size());
return this->data_->val_[p.id()];
}
Index: mln/core/p_bgraph.hh
--- mln/core/p_bgraph.hh (revision 1764)
+++ mln/core/p_bgraph.hh (working copy)
@@ -53,9 +53,6 @@
{
typedef util::internal::boost_graph<P, util::empty> graph;
- /// Construct a graph psite set from a graph of points.
- p_bgraph (graph& gr);
-
/// Point_Site associated type.
typedef bgraph_psite<P> psite;
@@ -75,6 +72,11 @@
typedef std::pair<node_iterator, node_iterator> node_iterators;
+ /// Construct a graph psite set from a graph of points.
+ /// \p gr is a pointer on a boost graph.
+ /// This boost graph must have been allocated dynamically.
+ p_bgraph (graph* gr);
+
/// Return The number of points (i.e., nodes) in the graph.
std::size_t npoints() const;
@@ -103,11 +105,7 @@
private:
- 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
- bounding box? */
+ graph* gr_;
box_<P> bb_;
};
@@ -115,17 +113,18 @@
template<typename P>
inline
- p_bgraph<P>::p_bgraph (typename p_bgraph<P>::graph& gr)
+ p_bgraph<P>::p_bgraph (typename p_bgraph<P>::graph* gr)
: gr_ (gr)
{
+ mln_precondition(gr != 0);
// FIXME: Warning: if the underlying graph is updated later, this
// won't be taken into account by this p_bgraph!
accu::bbox<P> a;
- for (node_iterators iter = boost::vertices(gr_);
+ for (node_iterators iter = boost::vertices(*gr_);
iter.first != iter.second;
++iter.first)
- a.take(gr_[*iter.first]);
+ a.take((*gr_)[*iter.first]);
bb_ = a.to_result();
}
@@ -134,7 +133,7 @@
std::size_t
p_bgraph<P>::npoints() const
{
- return boost::num_vertices((gr_));
+ return boost::num_vertices(*gr_);
}
template<typename P>
@@ -142,7 +141,7 @@
std::size_t
p_bgraph<P>::nlines() const
{
- return boost::num_edges(gr_.nedges());
+ return boost::num_edges(gr_->nedges());
}
template<typename P>
@@ -170,14 +169,14 @@
const P&
p_bgraph<P>::point_from_id(const typename p_bgraph<P>::node_id& id)
const
{
- return this->gr_[id];
+ return this->gr_->operator[](id);
}
template <typename P>
P&
p_bgraph<P>::point_from_id(const typename p_bgraph<P>::node_id& id)
{
- return this->gr_[id];
+ return this->gr_->operator[](id);
}
@@ -187,7 +186,7 @@
const P&
p_bgraph<P>::node1(const typename p_bgraph<P>::edge_id& e) const
{
- return this->point_from_id(source(e, this->gr_));
+ return this->point_from_id(source(e, *this->gr_));
}
/// FIXME: same as node1...
@@ -195,21 +194,21 @@
const P&
p_bgraph<P>::node2(const typename p_bgraph<P>::edge_id& e) const
{
- return this->point_from_id(target(e, this->gr_));
+ return this->point_from_id(target(e, *this->gr_));
}
template <typename P>
const typename p_bgraph<P>::graph&
p_bgraph<P>::to_graph() const
{
- return this->gr_;
+ return *this->gr_;
}
template <typename P>
typename p_bgraph<P>::graph&
p_bgraph<P>::to_graph()
{
- return this->gr_;
+ return *this->gr_;
}
Index: mln/core/bgraph_psite.hh
--- mln/core/bgraph_psite.hh (revision 1764)
+++ mln/core/bgraph_psite.hh (working copy)
@@ -85,8 +85,6 @@
typename p_bgraph<P>::node_id id_;
};
-
-
# ifndef MLN_INCLUDE_ONLY
template<typename P>
@@ -118,7 +116,7 @@
return *this;
// Assigning a psite from a graph point set to a psite from
// another graph point set is meaningless.
- mln_assertion(&pg_ == &rhs.pg_);
+ mln_assertion(&pg_.to_graph() == &rhs.pg_.to_graph());
id_ = rhs.id_;
return *this;
}