Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49849 - in sandbox/SOC/2008/graphs/trunk/libs/graphs: include/boost/graphs include/boost/graphs/adjacency_list include/boost/graphs/adjacency_list/es include/boost/graphs/adjacency_list/vs test
From: asutton_at_[hidden]
Date: 2008-11-20 10:32:47


Author: asutton
Date: 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
New Revision: 49849
URL: http://svn.boost.org/trac/boost/changeset/49849

Log:
Started rewriting the edge store for undirected graphs
Added:
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/association.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/sequence.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/vector.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/edge.hpp (contents, props changed)
   sandbox/SOC/2008/graphs/trunk/libs/graphs/test/edge_store.cpp (contents, props changed)
Text files modified:
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_edge.hpp | 171 ++++++++++++---------------------------
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vertex_store.hpp | 139 ++++++++++++++++++++-----------
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/list.hpp | 6 -
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/map.hpp | 9 +
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp | 4
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/vector.hpp | 6 -
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/label.hpp | 19 ---
   sandbox/SOC/2008/graphs/trunk/libs/graphs/test/CMakeLists.txt | 2
   sandbox/SOC/2008/graphs/trunk/libs/graphs/test/vertex_store.cpp | 61 ++++++++-----
   9 files changed, 192 insertions(+), 225 deletions(-)

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,95 @@
+
+#ifndef BOOST_GRAPH_ADJLIST_EDGE_STORE_TRAITS_HPP
+#define BOOST_GRAPH_ADJLIST_EDGE_STORE_TRAITS_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/containers.hpp>
+#include <boost/descriptors.hpp>
+
+#include <boost/graphs/label.hpp>
+#include <boost/graphs/edge.hpp>
+
+// Include specializations for the label and edge interfaces.
+#include <boost/graphs/adjacency_list/es/sequence.hpp>
+#include <boost/graphs/adjacency_list/es/association.hpp>
+
+// The edge store interface defines generic operations on an edge store for
+// undirected graphs.
+
+// NOTE: Directed graphs do not use a global edge store. They use out and in
+// edge stores and have a completely different interface.
+
+// TODO: There is a significant overlap between the sequence selectors for
+// vertex and edge stores. These could easily be integrated into a kind of
+// general purpose selector mechanism. For now, they're separate.
+
+namespace boost { namespace graphs { namespace adjacency_list {
+
+template <typename Store>
+struct edge_store_traits
+{
+ typedef typename Store::value_type edge_type;
+};
+
+namespace es {
+
+namespace detail {
+ template <typename Store, typename Ends, typename Label>
+ inline typename edge_store_traits<Store>::edge_type
+ make_edge(Store const&, Ends e, Label&& l)
+ { return typename edge_store_traits<Store>::edge_type(e, l); }
+
+ template <typename Store, typename Ends, typename Label>
+ inline typename Store::iterator
+ dispatch_insert(Store& store, Ends e, Label&& l, sequence_tag)
+ { return store.insert(store.end(), make_edge(store, e, l)); }
+
+ // This re-orders the endpoints before inerting in order to guarantee a
+ // canonical ordering edges, and preserving uniqueness, if required.
+ // TODO: Is there a way to convert Comp<pair<VD,VD>> to Comp<VD>? Yeah, but
+ // it's kind of nasty and uses template template parameters.
+ template <typename Store, typename Ends, typename Label>
+ inline typename Store::iterator
+ dispatch_insert(Store& store, Ends e, Label&& l, pair_associative_container_tag)
+ {
+ if(!(e.first < e.second)) swap(e.first, e.second);
+ return container_insert(store, make_edge(store, e, l));
+ }
+}
+
+/** Insert . */
+template <typename Store, typename Ends, typename Label>
+inline typename descriptor_traits<Store>::descriptor_type
+insert(Store& store, Ends e, Label&& l)
+{ return make_descriptor(store, detail::dispatch_insert(store, e, l, container_category(store))); }
+
+/** Return the number of edges in the edge store. */
+template <typename Store>
+typename Store::size_type size(Store const& store)
+{ return store.size(); }
+
+/** @name Edge Label
+ * Return a lable for the given edge.
+ */
+//@{
+template <typename Store>
+inline typename label_traits<typename edge_store_traits<Store>::edge_type>::label_type&
+label(Store& store, typename descriptor_traits<Store>::descriptor_type d)
+{ return graphs::label(*make_iterator(store, d)); }
+
+template <typename Store>
+inline typename label_traits<typename edge_store_traits<Store>::edge_type>::label_type const&
+label(Store const& store, typename descriptor_traits<Store>::descriptor_type d)
+{ return graphs::label(*make_iterator(store, d)); }
+//@}
+
+} /* namespace es */
+
+} } } /* namespace boost::graphs::adjacency_list */
+
+// Type selectors
+#include <boost/graphs/adjacency_list/es/vector.hpp>
+#include <boost/graphs/adjacency_list/es/set.hpp>
+
+#endif

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/association.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/association.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,38 @@
+
+#ifndef BOOST_GRAPHS_ADJLIST_ES_ASSOCIATION_HPP
+#define BOOST_GRAPHS_ADJLIST_ES_ASSOCIATION_HPP
+
+namespace boost { namespace graphs {
+
+// Specializations to support labels for undirected edges for edge vectors,
+// and lists.
+
+template <typename VertexDesc, typename EdgeLabel>
+struct label_traits<std::pair<std::pair<VertexDesc, VertexDesc> const, EdgeLabel>>
+{
+ typedef EdgeLabel label_type;
+};
+
+template <typename VertexDesc, typename EdgeLabel>
+inline EdgeLabel&
+label(std::pair<std::pair<VertexDesc, VertexDesc> const, EdgeLabel>& edge)
+{ return edge.second; }
+
+template <typename VertexDesc, typename EdgeLabel>
+inline EdgeLabel const&
+label(std::pair<std::pair<VertexDesc, VertexDesc> const, EdgeLabel> const& edge)
+{ return edge.second; }
+
+// Specializations of the edge interface for edge sequences (vectors and lists).
+
+// NOTE: I'm un-consting the key type for an associative container. Will this
+// cause problems later? Possibly.
+template <typename VertexDesc, typename EdgeLabel>
+struct edge_traits<std::pair<std::pair<VertexDesc, VertexDesc> const, EdgeLabel>>
+{
+ typedef std::pair<VertexDesc, VertexDesc> end_pair;
+};
+
+} } /* namespace boost::graphs */
+
+#endif

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/sequence.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/sequence.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_GRAPHS_ADJLIST_ES_SEQUENCE_HPP
+#define BOOST_GRAPHS_ADJLIST_ES_SEQUENCE_HPP
+
+namespace boost { namespace graphs {
+
+// Specializations to support labels for undirected edges for edge vectors,
+// and lists.
+
+// TODO: I'm a little worried about the possibility of type collisions with
+// directed graphs. It would be nice if I could specialize on an extra piece
+// of information here. Also, the difference between this and associative
+// specializations is the const-ness of the ends.
+
+template <typename VertexDesc, typename EdgeLabel>
+struct label_traits<std::pair<std::pair<VertexDesc, VertexDesc>, EdgeLabel>>
+{
+ typedef EdgeLabel label_type;
+};
+
+template <typename VertexDesc, typename EdgeLabel>
+inline EdgeLabel&
+label(std::pair<std::pair<VertexDesc, VertexDesc>, EdgeLabel>& edge)
+{ return edge.second; }
+
+template <typename VertexDesc, typename EdgeLabel>
+inline EdgeLabel const&
+label(std::pair<std::pair<VertexDesc, VertexDesc>, EdgeLabel> const& edge)
+{ return edge.second; }
+
+// Specializations of the edge interface for edge sequences (vectors and lists).
+
+template <typename VertexDesc, typename EdgeLabel>
+struct edge_traits<std::pair<std::pair<VertexDesc, VertexDesc>, EdgeLabel>>
+{
+ typedef std::pair<VertexDesc, VertexDesc> end_pair;
+};
+
+} } /* namespace boost::graphs */
+
+#endif

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,40 @@
+
+#ifndef BOOST_GRAPHS_ADJLIST_ES_SET_HPP
+#define BOOST_GRAPHS_ADJLIST_ES_SET_HPP
+
+#include <map>
+
+#include <boost/graphs/edge.hpp>
+
+namespace boost { namespace graphs { namespace adjacency_list {
+
+
+/**
+ * @param Compare A unary template class that compares the ends of edges. The
+ * argument type for this function is Pair<VertexDesc, VertexDesc>.
+ * @param Alloc A unary template class that allocates edges.
+ */
+template <
+ template <typename> class Compare = std::less,
+ template <typename> class Alloc = std::allocator>
+struct edge_set
+{
+ typedef typename descriptor_traits<
+ std::set<int, Compare<int>, Alloc<int>>
+ >::descriptor_type edge_descriptor;
+
+ // This quietly implements a map, not a set because we'll be using the
+ // endpoints as keys to the label.
+ template <typename Ends, typename Label>
+ struct edge_store
+ {
+ typedef Compare<Ends> compare;
+ typedef Alloc<std::pair<Ends, Label>> allocator;
+ public:
+ typedef std::map<Ends, Label, compare, allocator> type;
+ };
+};
+
+} } } /* namespace boost::graphs::adjacency_list */
+
+#endif

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/vector.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/vector.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_GRAPHS_ADJLIST_ES_VECTOR_HPP
+#define BOOST_GRAPHS_ADJLIST_ES_VECTOR_HPP
+
+#include <vector>
+
+namespace boost { namespace graphs { namespace adjacency_list {
+
+/**
+ * @param Alloc A unary template class that will allocate stored vertices.
+ */
+template <template <typename> class Alloc = std::allocator>
+struct edge_vector
+{
+ typedef typename descriptor_traits<
+ std::vector<int, Alloc<int>>
+ >::descriptor_type edge_descriptor;
+
+ // Ends must be a pair of vertices.
+ template <typename Ends, typename Label>
+ struct edge_store
+ {
+ private:
+ typedef std::pair<Ends, Label> edge;
+ typedef Alloc<edge> allocator;
+ public:
+ typedef std::vector<edge, allocator> type;
+ };
+};
+
+} } } /* namespace boost::graphs::adjacency_list */
+
+#endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_edge.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_edge.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_edge.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -4,114 +4,81 @@
 
 #include <iosfwd>
 
-#include <boost/unordered_pair.hpp>
-#include <boost/graphs/directional_edge.hpp>
+#include <boost/functional/hash.hpp>
+
+#include <boost/graphs/edge.hpp>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
 /**
- * This structure implements an unordered edge - sort of. Because the undirected
- * adjacency list class doesn't ever store a concrete edge type, this edge
- * type simply aggregates descriptors in such a way that it defines an edge.
- * This means that this class can also act (and does) as a descriptor itself.
+ * This structure implements an undirected edge. An undirected edge maintains
+ * a pair of vertices and an edge label.
  */
-template <typename VertexDesc, typename PropDesc>
+template <typename EdgeLabel, typename VertexDesc>
 class undirected_edge
 {
 public:
+ typedef EdgeLabel label_type;
+
     typedef VertexDesc vertex_descriptor;
- typedef PropDesc label_descriptor;
- typedef unordered_pair<vertex_descriptor> edge_pair;
+ typedef std::pair<vertex_descriptor, vertex_descriptor> ends_pair;
 
     /** @name Constructors */
     //@{
- inline undirected_edge()
+ undirected_edge()
         : _ends(), _label()
     { }
 
- inline undirected_edge(vertex_descriptor u, vertex_descriptor v, label_descriptor p)
- : _ends(u, v), _label(p)
+ undirected_edge(vertex_descriptor u, vertex_descriptor v, label_type const& l)
+ : _ends(u, v), _label(l)
     { }
 
- inline undirected_edge(std::pair<vertex_descriptor, vertex_descriptor> const& e, label_descriptor p)
- : _ends(e.first, e.second), _label(p)
+ undirected_edge(ends_pair const& e, label_type const& l)
+ : _ends(e.first, e.second), _label(l)
     { }
-
- inline undirected_edge(unordered_pair<vertex_descriptor, vertex_descriptor> const& e, label_descriptor p)
- : _ends(e), _label(p)
- { }
- //@}
-
- /** @name Descriptor-like Functions
- * These allow you to treat the edge descriptor like a typical descriptor.
- * That is, it can be tested for null status (which defers to the _labelerty
- * descriptor).
- */
- //@{
- inline bool is_null() const
- { return _label.is_null(); }
-
- inline operator bool() const
- { return !is_null(); }
- //@}
-
- inline label_descriptor label() const
- { return _label; }
-
- inline edge_pair const& edge() const
- { return _ends; }
-
- /** @name End Points
- * Provide access to the end points of the undirected edge. Because the
- * _ends of this edge are unordered, they do not provide a source and target
- * interface. See the rooted_undirected_edge class for a variant of this
- * type that imposes a source/target interface on these edges.
- */
- //@{
- inline vertex_descriptor first() const
- { return _ends.first(); }
-
- inline vertex_descriptor second() const
- { return _ends.second(); }
-
- inline vertex_descriptor opposite(vertex_descriptor v) const
- { return v == first() ? second() : first(); }
- //@}
-
- /** Return true if the edge connects the two vertices. */
- inline bool connects(vertex_descriptor u, vertex_descriptor v) const
- { return make_unordered_pair(u, v) == _ends; }
-
-
- /** @name Equality Comparable */
- //@{
- inline bool operator==(undirected_edge const& x) const
- { return (_ends == x._ends) && (_label == x._label); }
-
- inline bool operator!=(undirected_edge const& x) const
- { return !operator==(x); }
     //@}
 
- /** @name Less Than Comparable */
- //@{
- inline bool operator<(undirected_edge const& x) const
- { return std::make_pair(_ends, _label) < std::make_pair(x._ends < x._label); }
-
- inline bool operator>(undirected_edge const& x) const
- { return x.operator<(*this); }
+ label_type& label() { return _label; }
+ label_type const& label() const { return _label; }
 
- inline bool operator<=(undirected_edge const& x) const
- { return !x.operator<(*this); }
-
- inline bool operator>=(undirected_edge const& x) const
- { return !operator<(x); }
- //@}
+ ends_pair const& ends() const { return _ends; }
 
 private:
- edge_pair _ends;
- label_descriptor _label;
+ ends_pair _ends;
+ label_type _label;
 };
 
+/** @name Equality Comparable */
+//@{
+template <typename L, typename VD>
+inline bool operator==(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return (a.ends() == b.ends()) && (a.label() == b.label()); }
+
+template <typename L, typename VD>
+inline bool operator!=(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return !(a == b); }
+//@}
+
+/** @name Less Than Comparable */
+//@{
+template <typename L, typename VD>
+inline bool operator<(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return std::make_pair(a.ends(), a.label()) < std::make_pair(b.ends(), b.label()); }
+
+template <typename L, typename VD>
+inline bool operator>(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return b < a; }
+
+template <typename L, typename VD>
+inline bool operator<=(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return !(b < a); }
+
+template <typename L, typename VD>
+inline bool operator>=(undirected_edge<L,VD> const& a, undirected_edge<L,VD> const& b)
+{ return !(a < b); }
+//@}
+
+
 template <typename V, typename P>
 std::ostream& operator<<(std::ostream& os, undirected_edge<V,P> const& e)
 { return os << "{" << e.first() << " " << e.second() << "}"; }
@@ -124,10 +91,7 @@
 template <typename V, typename P>
 inline std::size_t
 hash_value(undirected_edge<V,P> const& e)
-{
- using boost::hash;
- return hash_value(e.label());
-}
+{ return hash_value(e.label()); }
 
 /**
  * The undirected edge iterator simply wraps the iterator over the global edge
@@ -199,37 +163,6 @@
     iterator iter;
 };
 
-} /* namespace adjacency_list */
-
-namespace detail
-{
- // Provide an implementation of directionality for undirected edges.
- template <typename Vert, typename Prop>
- struct directional_edge_adapter<adjacency_list::undirected_edge<Vert,Prop>>
- : adjacency_list::undirected_edge<Vert,Prop>
- {
- inline directional_edge_adapter()
- : adjacency_list::undirected_edge<Vert, Prop>(), src()
- { }
-
- inline directional_edge_adapter(adjacency_list::undirected_edge<Vert,Prop> e, Vert s)
- : adjacency_list::undirected_edge<Vert,Prop>(e), src(s)
- { }
-
- inline directional_edge_adapter(Vert s, Vert t)
- : adjacency_list::undirected_edge<Vert,Prop>(s, t), src(s)
- { }
-
- inline Vert source() const
- { return src; }
-
- inline Vert target() const
- { return this->opposite(src); }
-
- Vert src;
- };
-}
-
-} } /* namespace boost::graphs */
+} } } /* namespace boost::graphs::adjacency_list */
 
 #endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vertex_store.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vertex_store.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vertex_store.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -8,23 +8,22 @@
 #include <boost/descriptors.hpp>
 
 #include <boost/graphs/label.hpp>
-#include <boost/graphs/adjacency_list/vs/vector.hpp>
 
 // The Vertex Store defines the generic interface for working with a vertex
 // set for both directed and undirected adjacency lists. Its primary goal is
 // to provide generic interfaces that abstract common operations on these
 // sets. Important kinds of types are:
 // - Store - the selected container. Must model Container.
-// - Iterator - a non-const iterator into the store.
+// - Descriptor - a descriptor into the store
+// - Result - pair<Descriptor, bool>
 // - Size - the size type of the container
 // - Vertex - a type of vertex. Can be labelled.
 // - Label - a vertex label
 // - Key - a key maapping to a vertex.
-// - Result - pair<Iterator, bool>
 //
 // Supported operations are:
-// - Iterator vs_add_vertex (Store, Vertex)
-// - Iterator vs_add_vertex (Store, Key, Vertex)
+// - Descriptor vs_add_vertex (Store, Vertex)
+// - Descriptor vs_add_vertex (Store, Key, Vertex)
 // - Result vs_try_add_vertex (Store, Vertex)
 // - Result vs_try_add_vertex (Store, Key, Vertex)
 // - Iterator vs_find_vertex (Store, Label)
@@ -34,30 +33,25 @@
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
-namespace detail
+/**
+ * The vertex_store_traits relates associated types with a kind of vertex store.
+ * Mostly, this is useful in cases where we have to get the vertex type from
+ * simple and pair associative containers.
+ */
+template <typename Store>
+struct vertex_store_traits
 {
- // Try to add the vertex to an associative container. This is a simple
- // delegation to the container.
- template <typename Store, typename Vertex>
- inline std::pair<typename Store::iterator, bool>
- dispatch_vs_try_add(Store& store, Vertex&& v, associative_container_tag)
- { return store.insert(v); }
+ typedef typename Store::value_type vertex_type;
+};
 
- // Try to add the vertex to a sequential container. Here, we want to search
- // for the vertex (linear time operation) and either insert at the end
- // or return an existing iterator.
- template <typename Store, typename Vertex>
- inline std::pair<typename Store::iterator, bool>
- dispatch_vs_try_add(Store& store, Vertex&& v, sequence_tag)
- {
- typename Store::iterator i = vs_find_vertex(store, label(v));
- return std::make_pair(i, i == store.end());
- }
+namespace vs {
+
+namespace detail {
 
     // Iterate and compare for sequences.
     template <typename Store, typename Label>
     inline typename Store::iterator
- dispatch_vs_find(Store& store, Label const& l, sequence_tag)
+ dispatch_find(Store& store, Label const& l, sequence_tag)
     {
         return std::find_if(
             store.begin(),
@@ -69,20 +63,38 @@
     // have to use the basic find command.
     template <typename Store, typename Label>
     inline typename Store::iterator
- dispatch_vs_find(Store& store, Label const& l, associative_container_tag)
+ dispatch_find(Store& store, Label const& l, associative_container_tag)
     { return store.find(l); }
 
+
+ // Try to add the vertex to an associative container. This is a simple
+ // delegation to the container.
+ template <typename Store, typename Vertex>
+ inline std::pair<typename Store::iterator, bool>
+ dispatch_try_insert(Store& store, Vertex&& v, associative_container_tag)
+ { return store.insert(v); }
+
+ // Try to add the vertex to a sequential container. Here, we want to search
+ // for the vertex (linear time operation) and either insert at the end
+ // or return an existing iterator.
+ template <typename Store, typename Vertex>
+ inline std::pair<typename Store::iterator, bool>
+ dispatch_try_insert(Store& store, Vertex&& v, sequence_tag)
+ {
+ typename Store::iterator i = dispatch_find(store, label(v), sequence_tag());
+ return std::make_pair(i, i == store.end());
+ }
+
     // Explicitly remove the ability use this function, by failing a concept
     // check when it is instantiated.
     template <typename Store>
- void dispatch_vs_remove(Store&, typename Store::iterator, vector_tag)
+ void dispatch_remove(Store&, typename Store::iterator, vector_tag)
     { function_requires(Integer<Store>()); }
 
     template <typename Store, typename Tag>
- void dispatch_vs_remove(Store& store, typename Store::iterator i, Tag)
+ void dispatch_remove(Store& store, typename Store::iterator i, Tag)
     { store.erase(i); }
 
-
 } /* namespace detail */
 
 /** @name Add Vertex
@@ -93,15 +105,15 @@
 //@{
 /** Insert a vertex into the container. */
 template <typename Store, typename Vertex>
-inline typename Store::iterator
-vs_add_vertex(Store& store, Vertex&& v)
-{ return container_insert(store, v); }
+inline typename descriptor_traits<Store>::descriptor_type
+insert(Store& store, Vertex&& v)
+{ return make_descriptor(store, container_insert(store, v)); }
 
 /** Insert a vertex into the container, mapped to the given key. */
 template <typename Store, typename Key, typename Vertex>
-inline typename Store::iterator
-vs_add_vertex(Store& store, Key const& k, Vertex&& v)
-{ return container_insert(store, std::make_pair(k, v)); }
+inline typename descriptor_traits<Store>::descriptor_type
+insert(Store& store, Key const& k, Vertex&& v)
+{ return make_descriptor(store, container_insert(store, std::make_pair(k, v))); }
 //@}
 
 /** @name Try to Add Vertex
@@ -112,35 +124,47 @@
  */
 //@{
 template <typename Store, typename Vertex>
-inline std::pair<typename Store::iterator, bool>
-vs_try_add_vertex(Store& store, Vertex&& v)
-{ return detail::dispatch_vs_try_add(store, v, container_category(store)); }
+inline std::pair<typename descriptor_traits<Store>::descriptor_type, bool>
+try_insert(Store& store, Vertex&& v)
+{
+ std::pair<typename Store::iterator, bool> x =
+ detail::dispatch_try_insert(store, v, container_category(store));
+ return std::make_pair(make_descriptor(store, x.first), x.second);
+}
 
 // There are no mapped linear sequences, so we can just rely on the fact that
 // this is a pair associative container. In fact, this actually requires that
 // Store model the UniqueAssociativeContainer concept.
 template <typename Store, typename Key, typename Vertex>
-inline std::pair<typename Store::iterator, bool>
-vs_try_add_vertex(Store& store, Key const& k, Vertex&& v)
-{ return store.insert(std::make_pair(k, v)); }
+inline std::pair<typename descriptor_traits<Store>::descriptor_type, bool>
+try_insert(Store& store, Key const& k, Vertex&& v)
+{
+ std::pair<typename Store::iterator, bool> x =
+ store.insert(std::make_pair(k, v));
+ return std::make_pair(make_descriptor(store, x.first), x.second);
+}
 //@}
 
 /** @name Find Vertex
  * Return an iterator to the vertex that matches the given label. This is
  * only applicable to labelled vertex types. The returned iterator will be
  * equivalent to store.end() if no such vertex is found.
+ *
+ * If the store is a pair associative container (e.g., map), then this function
+ * will find the vertex mapped to the given key. Otherwise, it tries to find
+ * the vertex with the given label.
  */
 //@{
-template <typename Store, typename Label>
-inline typename Store::iterator
-vs_find_vertex(Store& store, Label const& l)
-{ return detail::dispatch_vs_find(store, l, container_category(store)); }
+template <typename Store, typename LabelOrKey>
+inline typename descriptor_traits<Store>::descriptor_type
+find(Store& store, LabelOrKey const& lk)
+{ return make_descriptor(store, detail::dispatch_find(store, lk, container_category(store))); }
 
 // Does not return a const iterator!
-template <typename Store, typename Label>
-inline typename Store::iterator
-vs_find_vertex(Store const& store, Label const& l)
-{ return detail::dispatch_vs_find(const_cast<Store&>(store), l, container_category(store)); }
+template <typename Store, typename LabelOrKey>
+inline typename descriptor_traits<Store>::descriptor_type
+find(Store const& store, LabelOrKey const& lk)
+{ return find(const_cast<Store&>(store), lk, container_category(store)); }
 //@}
 
 /**
@@ -150,20 +174,33 @@
  */
 //@{
 template <typename Store>
-void vs_remove_vertex(Store& store, typename Store::iterator i)
-{ detail::dispatch_vs_remove(store, i, container_category(store)); }
+void remove(Store& store, typename descriptor_traits<Store>::descriptor_type d)
+{ detail::dispatch_remove(store, make_iterator(store, d), container_category(store)); }
 //@}
 
 /** Return the number of elements in the vertex store. */
 template <typename Store>
-typename Store::size_type vs_size(Store const& store)
+typename Store::size_type size(Store const& store)
 { return store.size(); }
 
 /** Return true if the store is empty. */
 template <typename Store>
-bool vs_empty(Store const& store)
+bool empty(Store const& store)
 { return store.empty(); }
 
+/** Clear the vertex store. */
+template <typename Store>
+void clear(Store& store)
+{ store.clear(); }
+
+} /* namespace vs */
+
 } } } /* namespace boost::graphs::adjacency_list */
 
+// Include type selectors for the different vertex store implementations
+#include <boost/graphs/adjacency_list/vs/vector.hpp>
+#include <boost/graphs/adjacency_list/vs/list.hpp>
+#include <boost/graphs/adjacency_list/vs/set.hpp>
+#include <boost/graphs/adjacency_list/vs/map.hpp>
+
 #endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/list.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/list.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/list.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -2,11 +2,7 @@
 #ifndef BOOST_GRAPHS_ADJLIST_VS_LIST_HPP
 #define BOOST_GRAPHS_ADJLIST_VS_LIST_HPP
 
-#include <list>
-
-#include <boost/none.hpp>
 #include <boost/counted_list.hpp>
-#include <boost/graphs/adjacency_list/vertex_store.hpp>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
@@ -16,7 +12,7 @@
 template <template <typename> class Alloc = std::allocator>
 struct vertex_list
 {
- typedef unused key_type;
+ typedef void key_type;
 
     typedef typename descriptor_traits<
         std::list<int, Alloc<int>>

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/map.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/map.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/map.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -5,7 +5,6 @@
 #include <map>
 
 #include <boost/none.hpp>
-#include <boost/graphs/adjacency_list/vertex_store.hpp>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
@@ -35,6 +34,14 @@
     };
 };
 
+// Specialize the vertex store traits to refer to the mapped type instead
+// of the value type.
+template <typename Key, typename Value, typename Compare, typename Alloc>
+struct vertex_store_traits<std::map<Key, Value, Compare, Alloc>>
+{
+ typedef typename std::map<Key, Value, Compare, Alloc>::mapped_type vertex_type;
+};
+
 } } } /* namespace boost::graphs::adjacency_list */
 
 #endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -4,9 +4,7 @@
 
 #include <set>
 
-#include <boost/none.hpp>
 #include <boost/graphs/label.hpp>
-#include <boost/graphs/adjacency_list/vertex_store.hpp>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
@@ -20,7 +18,7 @@
     template <typename> class Alloc = std::allocator>
 struct vertex_set
 {
- typedef unused key_type;
+ typedef void key_type;
 
     typedef typename descriptor_traits<
         std::set<int, Compare<int>, Alloc<int>>

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/vector.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/vector.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/vector.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -3,10 +3,6 @@
 #define BOOST_GRAPHS_ADJLIST_VS_VECTOR_HPP
 
 #include <vector>
-#include <algorithm>
-
-#include <boost/none.hpp>
-#include <boost/graphs/adjacency_list/vertex_store.hpp>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
@@ -16,7 +12,7 @@
 template <template <typename> class Alloc = std::allocator>
 struct vertex_vector
 {
- typedef unused key_type;
+ typedef void key_type;
 
     typedef typename descriptor_traits<
         std::vector<int, Alloc<int>>

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/edge.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/edge.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_GRAPHS_EDGE_HPP
+#define BOOST_GRAPHS_EDGE_HPP
+
+#include <boost/none.hpp>
+
+namespace boost { namespace graphs {
+
+// The edge interface...
+
+/**
+ * The edge traits class provides information about the end points and semantics
+ * of edges, but not their labels.
+ */
+template <typename Edge>
+struct edge_traits
+{
+ typedef typename Edge::end_pair end_pair;
+};
+
+} } /* namespace boost::graphs */
+
+
+#endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/label.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/label.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/label.hpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -20,32 +20,19 @@
     typedef typename Object::label_type label_type;
 };
 
-/**
- * Metafunction that returns true if the labeled objects type is none. This
- * should actually be significantly better adapted - for example with arbitrary
- * types for which label_traits does not exist.
- */
-template <typename Object>
-struct has_label
-{
- enum { value = is_same<typename label_traits<Object>::label_type, none>::value };
-};
-
-/**
+/** @name Label Access
  * Return a reference to the object's label. The generic implementation requires
  * the object to have a non-const label() member.
  */
+//@{
 template <typename Object>
 typename label_traits<Object>::label_type& label(Object& x)
 { return x.label(); }
 
-/**
- * Return a const reference to the object's label. The generic implementation
- * requires the object to have a const label() member.
- */
 template <typename Object>
 typename label_traits<Object>::label_type const& label(Object const& x)
 { return x.label(); }
+//@}
 
 /**
  * This is a simple template wrapper for building comparison functors for

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/test/CMakeLists.txt
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/test/CMakeLists.txt (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/test/CMakeLists.txt 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -1,5 +1,5 @@
 
 include_directories(${Graphs_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 
-add_exec(hello hello.cpp)
 add_exec(vertex_store vertex_store.cpp)
+add_exec(edge_store edge_store.cpp)

Added: sandbox/SOC/2008/graphs/trunk/libs/graphs/test/edge_store.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/test/edge_store.cpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -0,0 +1,41 @@
+
+#include <iostream>
+#include <string>
+
+#include <boost/graphs/adjacency_list/vertex_store.hpp>
+#include <boost/graphs/adjacency_list/edge_store.hpp>
+
+#include "typestr.hpp"
+
+using namespace std;
+using namespace boost;
+using namespace boost::graphs;
+using namespace boost::graphs::adjacency_list;
+
+template <typename Store>
+void test()
+{
+ typedef typename edge_store_traits<Store>::edge_type Edge;
+ typedef typename edge_traits<Edge>::end_pair Ends;
+ typedef typename descriptor_traits<Store>::descriptor_type EdgeDesc;
+
+ Store store;
+
+ EdgeDesc e1 = es::insert(store, Ends(0, 1), 0.5);
+ EdgeDesc e2 = es::insert(store, Ends(0, 2), 1.5);
+ BOOST_ASSERT(es::size(store) == 2u);
+ cout << es::label(store, e1) << endl;
+ cout << es::label(store, e2) << endl;
+}
+
+int main()
+{
+ typedef vertex_vector<>::vertex_descriptor VertexDesc;
+ typedef std::pair<VertexDesc, VertexDesc> Ends;
+
+ typedef edge_vector<>::edge_store<Ends, double>::type EV;
+ typedef edge_set<>::edge_store<Ends, double>::type EM;
+
+ test<EV>();
+ test<EM>();
+}

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/test/vertex_store.cpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/test/vertex_store.cpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/test/vertex_store.cpp 2008-11-20 10:32:46 EST (Thu, 20 Nov 2008)
@@ -3,14 +3,9 @@
 #include <string>
 
 #include <boost/graphs/adjacency_list/vertex_store.hpp>
-#include <boost/graphs/adjacency_list/vertex_vector.hpp>
-#include <boost/graphs/adjacency_list/vertex_list.hpp>
-#include <boost/graphs/adjacency_list/vertex_set.hpp>
-#include <boost/graphs/adjacency_list/vertex_map.hpp>
 
 #include "typestr.hpp"
 
-
 using namespace std;
 using namespace boost;
 using namespace boost::graphs::adjacency_list;
@@ -44,45 +39,63 @@
 template <typename Store>
 void add_verts(Store& store, simple_container_tag)
 {
- typedef typename Store::iterator Iterator;
- typedef typename Store::value_type Vertex;
- vs_add_vertex(store, Vertex("b"));
- Iterator iter = vs_add_vertex(store, Vertex("a"));
-
- vs_remove_vertex(store, iter);
+ typedef typename descriptor_traits<Store>::descriptor_type Descriptor;
+ typedef typename vertex_store_traits<Store>::vertex_type Vertex;
+ vs::insert(store, Vertex("b"));
+ vs::insert(store, Vertex("a"));
 
     // Try to re-add a vertex.
- pair<Iterator, bool> i = vs_try_add_vertex(store, Vertex("b"));
- cout << "re-add: " << i.second << "\n";
+ pair<Descriptor, bool> i = vs::try_insert(store, Vertex("b"));
+ BOOST_ASSERT(!i.second);
 }
 
 template <typename Store>
 void add_verts(Store& store, pair_container_tag)
 {
- typedef typename Store::iterator Iterator;
- typedef typename Store::mapped_type Vertex;
- vs_add_vertex(store, "a", Vertex());
- vs_add_vertex(store, "b", Vertex());
+ typedef typename descriptor_traits<Store>::descriptor_type Descriptor;
+ typedef typename vertex_store_traits<Store>::vertex_type Vertex;
+ vs::insert(store, "a", Vertex());
+ vs::insert(store, "b", Vertex());
 
     // Try to re-add a vertex.
- pair<Iterator, bool> i = vs_try_add_vertex(store, string("b"), Vertex());
- cout << "re-add: " << i.second << "\n";
+ pair<Descriptor, bool> i = vs::try_insert(store, string("b"), Vertex());
+ BOOST_ASSERT(!i.second);
 }
 
+template <typename Store, typename Tag>
+void remove_vert(Store& store, Tag t)
+{
+ typedef typename descriptor_traits<Store>::descriptor_type Descriptor;
+ Descriptor d = vs::find(store, string("b"));
+ BOOST_ASSERT(d);
+ size_t n = vs::size(store);
+ vs::remove(store, d);
+ BOOST_ASSERT(vs::size(store) == n - 1);
+}
+
+// No-op for vectors... Can't remove vertices.
+template <typename Store>
+void remove_vert(Store& store, vector_tag)
+{ }
+
 template <typename Store>
 void test()
 {
     typedef typename Store::value_type Vertex;
- typedef typename descriptor_traits<Store>::descriptor_type VertexDesc;
- typedef typename Store::iterator StoreIterator;
+ typedef typename descriptor_traits<Store>::descriptor_type Descriptor;
 
     Store store;
 
     add_verts(store, container_arity(container_category(store)));
+ BOOST_ASSERT(!vs::empty(store));
+ BOOST_ASSERT(vs::size(store));
 
     // Find a verts
- StoreIterator i = vs_find_vertex(store, string("b"));
- cout << "test: " << distance(store.begin(), i) << endl;
+ Descriptor d = vs::find(store, string("b"));
+ BOOST_ASSERT(d);
+
+ // Check the removal of vertices
+ remove_vert(store, container_category(store));
 }
 
 int main()
@@ -92,7 +105,7 @@
     typedef vertex_set<>::vertex_store<my_vertex>::type VS;
     typedef vertex_map<string>::vertex_store<my_vertex>::type VM;
 
- // test<VV>();
+ test<VV>();
     test<VL>();
     test<VS>();
     test<VM>();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk