https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Have graph vertex and edge creation return the created identifier.
* mln/util/internal/graph_base.hh:
(mln::util::internal::graph_base<N, E>::add_node_)
(mln::util::internal::graph_base<N, E>::add_edge_)
* mln/util/graph.hh
(mln::util::graph<void, void>::add_node)
(mln::util::graph<void, void>::add_edge)
(mln::util::graph<N, void>::add_node)
(mln::util::graph<N, void>::add_edge)
(mln::util::graph<N, E>::add_node)
(mln::util::graph<N, E>::add_edge):
Return the id of the newly created node or edge.
* mln/morpho/line_gradient.hh (mln::morpho::line_gradient):
Adjust.
morpho/line_gradient.hh | 10 ++-----
util/graph.hh | 57 +++++++++++++++++++++++++-------------------
util/internal/graph_base.hh | 36 +++++++++++++++++++++++----
3 files changed, 66 insertions(+), 37 deletions(-)
Index: mln/util/internal/graph_base.hh
--- mln/util/internal/graph_base.hh (revision 1973)
+++ mln/util/internal/graph_base.hh (working copy)
@@ -53,7 +53,14 @@
(not just typedefs), at least to prevent the user from using a
node_id where an edge_id is expected (and vice versa).
Conversion to and from unsigned would still be useful, but it
- might be safer to turn them into explicit ones. */
+ might be safer to turn them into explicit ones.
+
+ See what the Vaucanson team did for the handles of
+ vertices/states in their graphs/automata implemenations here:
+
+
https://trac.lrde.org/vaucanson/browser/trunk/include/vaucanson/automata/co…
+
+ We /might/ want to integrate this into Milena's value system. */
/// \brief The type used to identify nodes.
///
@@ -211,8 +218,15 @@
protected:
/// Shortcuts factoring the insertion of nodes and edges.
/// \{
- void add_node_(util::node<N>* node);
- void add_edge_(util::edge<E>* edge);
+ /// \brief Add a node.
+ ///
+ /// \return The id of the new node.
+ node_id add_node_(util::node<N>* node);
+ /// \brief Add an edge.
+ ///
+ /// \return The id of the new edge if it does not exist yet;
+ /// otherwise, return <tt>mln_max(edge_id)</tt>.
+ edge_id add_edge_(util::edge<E>* edge);
/// \}
protected:
@@ -414,16 +428,18 @@
template<typename N, typename E>
inline
- void
+ node_id
graph_base<N, E>::add_node_(util::node<N>* node)
{
+ /* FIXME: This is not thread-proof (these two lines should
+ form an atomic section). */
nodes_.push_back (node);
+ return nodes_.size() - 1;
}
- // FIXME: Return the (new) edge id.
template<typename N, typename E>
inline
- void
+ edge_id
graph_base<N, E>::add_edge_(util::edge<E>* edge)
{
// Does this edge already exist in the graph?
@@ -432,15 +448,23 @@
// Remove the previously allocated data for EDGE.
delete edge;
edge = 0;
+ // Return the erroneous value.
+ return mln_max(edge_id);
}
else
{
// Otherwise insert it into the graph.
+ /* FIXME: This is not thread-proof (these two lines should
+ form an atomic section). */
edges_.push_back(edge);
edge_id id = edges_.size() - 1;
+
+ // Update the set of edges.
edges_set_.insert(edge);
nodes_[edge->n1()]->edges.push_back(id);
nodes_[edge->n2()]->edges.push_back(id);
+
+ return id;
}
}
Index: mln/util/graph.hh
--- mln/util/graph.hh (revision 1973)
+++ mln/util/graph.hh (working copy)
@@ -61,12 +61,15 @@
/// The super class.
typedef internal::graph_base<void, void> super;
- // FIXME: We should return the id of the newly created node.
/// \brief Add a node.
- void add_node();
- // FIXME: We should return the id of the newly created edge.
+ ///
+ /// \return The id of the new node.
+ node_id add_node();
/// \brief Add an edge between nodes with ids \p n1 and \p n2.
- void add_edge(node_id n1, node_id n2);
+ ///
+ /// \return The id of the new edge if it does not exist yet;
+ /// otherwise, return <tt>mln_max(edge_id)</tt>.
+ edge_id add_edge(node_id n1, node_id n2);
};
/*-----------------.
@@ -81,12 +84,15 @@
/// The super class.
typedef internal::graph_base<N, void> super;
- // FIXME: We should return the id of the newly created node.
/// \brief Add a node.
- void add_node(const N& data);
- // FIXME: We should return the id of the newly created edge.
+ ///
+ /// \return The id of the new node.
+ node_id add_node(const N& data);
/// \brief Add an edge between nodes with ids \p n1 and \p n2.
- void add_edge(node_id n1, node_id n2);
+ ///
+ /// \return The id of the new edge if it does not exist yet;
+ /// otherwise, return <tt>mln_max(edge_id)</tt>.
+ edge_id add_edge(node_id n1, node_id n2);
/// Return the data associated to node with id \a n.
/// \{
@@ -108,12 +114,15 @@
/// The super class.
typedef internal::graph_base<N, E> super;
- // FIXME: We should return the id of the newly created node.
/// \brief Add a node.
- void add_node(const N& data);
+ ///
+ /// \return The id of the new node.
+ node_id add_node(const N& data);
/// \brief Add an edge between nodes with ids \p n1 and \p n2.
- // FIXME: We should return the id of the newly created edge.
- void add_edge(node_id n1, node_id n2, const E& data);
+ ///
+ /// \return The id of the new edge if it does not exist yet;
+ /// otherwise, return <tt>mln_max(edge_id)</tt>.
+ edge_id add_edge(node_id n1, node_id n2, const E& data);
/// Return the data associated to node with id \a n.
/// \{
@@ -146,21 +155,21 @@
/* Note that ddefinition of members from fully specialized
template classes are not preceded by `template<>'. */
inline
- void
+ node_id
graph<void, void>::add_node()
{
- super::add_node_(new util::node<void>);
+ return super::add_node_(new util::node<void>);
}
/* Note that ddefinition of members from fully specialized
template classes are not preceded by `template<>'. */
inline
- void
+ edge_id
graph<void, void>::add_edge(node_id n1, node_id n2)
{
mln_assertion(n1 < this->nnodes());
mln_assertion(n2 < this->nnodes());
- super::add_edge_(new util::edge<void>(n1, n2));
+ return super::add_edge_(new util::edge<void>(n1, n2));
}
/*-----------------.
@@ -169,20 +178,20 @@
template<typename N>
inline
- void
+ node_id
graph<N, void>::add_node(const N& data)
{
- super::add_node_(new util::node<N>(data));
+ return super::add_node_(new util::node<N>(data));
}
template<typename N>
inline
- void
+ edge_id
graph<N, void>::add_edge(node_id n1, node_id n2)
{
mln_assertion(n1 < this->nnodes());
mln_assertion(n2 < this->nnodes());
- super::add_edge_(new util::edge<void>(n1, n2));
+ return super::add_edge_(new util::edge<void>(n1, n2));
}
template <class N>
@@ -210,20 +219,20 @@
template<typename N, typename E>
inline
- void
+ node_id
graph<N, E>::add_node(const N& data)
{
- super::add_node_(new util::node<N>(data));
+ return super::add_node_(new util::node<N>(data));
}
template<typename N, typename E>
inline
- void
+ edge_id
graph<N, E>::add_edge(node_id n1, node_id n2, const E& data)
{
mln_assertion(n1 < this->nnodes());
mln_assertion(n2 < this->nnodes());
- super::add_edge_(new util::edge<E>(n1, n2, data));
+ return super::add_edge_(new util::edge<E>(n1, n2, data));
}
template<typename N, typename E>
Index: mln/morpho/line_gradient.hh
--- mln/morpho/line_gradient.hh (revision 1973)
+++ mln/morpho/line_gradient.hh (working copy)
@@ -73,20 +73,15 @@
missing tool) regarding the retrieval of nodes' ids from
points. */
std::map<mln::point2d, util::node_id> points;
- util::node_id id = 0;
// Nodes.
std::vector<value_t> node_values;
mln_fwd_piter(image2d<value_t>) p(ima.domain());
for_all (p)
{
- g.add_node (p);
+ util::node_id id = g.add_node (p);
node_values.push_back (ima(p));
- /* FIXME: ``Guessing'' the id of the point just being inserted
- is bad. util:graph<N,E>::add_node should return this
- id. */
points[p] = id;
- ++id;
}
// Edges.
@@ -99,9 +94,10 @@
for_all (q)
if (ima.has(q))
{
- g.add_edge(points[p], points[q]);
+ util::edge_id id = g.add_edge(points[p], points[q]);
// The computed value is a norm of the gradient between P and Q.
edge_values.push_back(math::abs(ima(p) - ima(q)));
+ assert(id != mln_max(util::edge_id));
}
// Line graph point set.