Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64645 - in trunk: boost/graph libs/graph/test
From: asutton_at_[hidden]
Date: 2010-08-06 14:13:21


Author: asutton
Date: 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
New Revision: 64645
URL: http://svn.boost.org/trac/boost/changeset/64645

Log:
Implementing bundled properties for graph properties.

The initial checkin supports bundled properties for adjacency list,
matrix, undirected and directed graphs, the labeled graph adaptor
and the reverse graph adaptor. All tests updated, passed.

Documentation should be updated, but isn't yet.

Text files modified:
   trunk/boost/graph/adjacency_list.hpp | 124 ++++++++---------
   trunk/boost/graph/adjacency_matrix.hpp | 109 +++++++--------
   trunk/boost/graph/directed_graph.hpp | 24 ++-
   trunk/boost/graph/graph_traits.hpp | 64 ++++++--
   trunk/boost/graph/labeled_graph.hpp | 7
   trunk/boost/graph/properties.hpp | 92 +++++++++----
   trunk/boost/graph/reverse_graph.hpp | 30 +++-
   trunk/boost/graph/undirected_graph.hpp | 21 ++
   trunk/libs/graph/test/test_graph.hpp | 9 +
   trunk/libs/graph/test/test_graphs.cpp | 269 +++++++++++++++++++++------------------
   trunk/libs/graph/test/test_properties.hpp | 78 +++++++---
   11 files changed, 476 insertions(+), 351 deletions(-)

Modified: trunk/boost/graph/adjacency_list.hpp
==============================================================================
--- trunk/boost/graph/adjacency_list.hpp (original)
+++ trunk/boost/graph/adjacency_list.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -28,6 +28,8 @@
 # endif
 #endif
 
+#include <boost/scoped_ptr.hpp>
+
 #include <boost/graph/graph_traits.hpp>
 #include <boost/graph/graph_mutability_traits.hpp>
 #include <boost/graph/graph_selectors.hpp>
@@ -368,37 +370,24 @@
                                        EdgeListS>::vertex_descriptor,
         VertexProperty>
   {
- public: // TODO Remove me
+ public:
 #if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
- typedef typename detail::retag_property_list<vertex_bundle_t,
- VertexProperty>::retagged
- maybe_vertex_bundled;
-
- typedef typename detail::retag_property_list<edge_bundle_t,
- EdgeProperty>::retagged
- maybe_edge_bundled;
-#endif
+ typedef typename graph_detail::graph_prop<GraphProperty>::property graph_property_type;
+ typedef typename graph_detail::graph_prop<GraphProperty>::bundle graph_bundled;
 
- public:
-#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
- typedef typename detail::retag_property_list<vertex_bundle_t,
- VertexProperty>::type
- vertex_property_type;
- typedef typename detail::retag_property_list<edge_bundle_t,
- EdgeProperty>::type
- edge_property_type;
-
- // The types that are actually bundled
- typedef typename mpl::if_c<(is_same<maybe_vertex_bundled, no_property>::value),
- no_vertex_bundle,
- maybe_vertex_bundled>::type vertex_bundled;
- typedef typename mpl::if_c<(is_same<maybe_edge_bundled, no_property>::value),
- no_edge_bundle,
- maybe_edge_bundled>::type edge_bundled;
+ typedef typename graph_detail::vertex_prop<VertexProperty>::property vertex_property_type;
+ typedef typename graph_detail::vertex_prop<VertexProperty>::bundle vertex_bundled;
+
+ typedef typename graph_detail::edge_prop<EdgeProperty>::property edge_property_type;
+ typedef typename graph_detail::edge_prop<EdgeProperty>::bundle edge_bundled;
 #else
+ typedef GraphProperty graph_property_type;
+ typedef no_graph_bundle graph_bundled;
+
     typedef VertexProperty vertex_property_type;
- typedef EdgeProperty edge_property_type;
     typedef no_vertex_bundle vertex_bundled;
+
+ typedef EdgeProperty edge_property_type;
     typedef no_edge_bundle edge_bundled;
 #endif
 
@@ -421,44 +410,51 @@
     typedef DirectedS directed_selector;
     typedef EdgeListS edge_list_selector;
 
- typedef GraphProperty graph_property_type;
 
- inline adjacency_list(const GraphProperty& p = GraphProperty())
- : m_property(p) { }
+ adjacency_list(const GraphProperty& p = GraphProperty())
+ : m_property(new graph_property_type(p))
+ { }
+
+ adjacency_list(const adjacency_list& x)
+ : Base(x), m_property(new graph_property_type(*x.m_property))
+ { }
 
- inline adjacency_list(const adjacency_list& x)
- : Base(x), m_property(x.m_property) { }
-
- inline adjacency_list& operator=(const adjacency_list& x) {
+ adjacency_list& operator=(const adjacency_list& x) {
       // TBD: probably should give the strong guarantee
       if (&x != this) {
         Base::operator=(x);
- m_property = x.m_property;
+
+ // Copy/swap the ptr since we can't just assign it...
+ property_ptr p(new graph_property_type(*x.m_property));
+ m_property.swap(p);
       }
       return *this;
     }
 
     // Required by Mutable Graph
- inline adjacency_list(vertices_size_type num_vertices,
+ adjacency_list(vertices_size_type num_vertices,
                           const GraphProperty& p = GraphProperty())
- : Base(num_vertices), m_property(p) { }
+ : Base(num_vertices), m_property(new graph_property_type(p))
+ { }
 
 #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1300
     // Required by Iterator Constructible Graph
     template <class EdgeIterator>
- inline adjacency_list(EdgeIterator first, EdgeIterator last,
+ adjacency_list(EdgeIterator first, EdgeIterator last,
                           vertices_size_type n,
                           edges_size_type = 0,
                           const GraphProperty& p = GraphProperty())
- : Base(n, first, last), m_property(p) { }
+ : Base(n, first, last), m_property(new graph_property_type(p))
+ { }
 
     template <class EdgeIterator, class EdgePropertyIterator>
- inline adjacency_list(EdgeIterator first, EdgeIterator last,
+ adjacency_list(EdgeIterator first, EdgeIterator last,
                           EdgePropertyIterator ep_iter,
                           vertices_size_type n,
                           edges_size_type = 0,
                           const GraphProperty& p = GraphProperty())
- : Base(n, first, last, ep_iter), m_property(p) { }
+ : Base(n, first, last, ep_iter), m_property(new graph_property_type(p))
+ { }
 #endif
 
     void swap(adjacency_list& x) {
@@ -487,35 +483,39 @@
 
     const edge_bundled& operator[](edge_descriptor e) const
     { return get(edge_bundle, *this)[e]; }
+
+ graph_bundled& operator[](graph_bundle_t)
+ { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ { return get_property(*this); }
 #endif
 
     // protected: (would be protected if friends were more portable)
- GraphProperty m_property;
+ typedef scoped_ptr<graph_property_type> property_ptr;
+ property_ptr m_property;
   };
 
- template <class OEL, class VL, class DirS, class VP,class EP, class GP,
- class EL, class Tag, class Value>
- inline void
- set_property(adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag,
- const Value& value) {
- get_property_value(g.m_property, Tag()) = value;;
+#define ADJLIST_PARAMS \
+ typename OEL, typename VL, typename D, typename VP, typename EP, \
+ typename GP, typename EL
+#define ADJLIST adjacency_list<OEL,VL,D,VP,EP,GP,EL>
+
+ template<ADJLIST_PARAMS, typename Tag, typename Value>
+ inline void set_property(ADJLIST& g, Tag, Value const& value) {
+ get_property_value(*g.m_property, Tag()) = value;
   }
 
- template <class OEL, class VL, class DirS, class VP, class EP, class GP,
- class Tag, class EL>
- inline
- typename graph_property<adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>, Tag>::type&
- get_property(adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag) {
- return get_property_value(g.m_property, Tag());
+ template<ADJLIST_PARAMS, typename Tag>
+ inline typename graph_property<ADJLIST, Tag>::type&
+ get_property(ADJLIST& g, Tag) {
+ return get_property_value(*g.m_property, Tag());
   }
 
- template <class OEL, class VL, class DirS, class VP, class EP, class GP,
- class Tag, class EL>
- inline
- const
- typename graph_property<adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>, Tag>::type&
- get_property(const adjacency_list<OEL,VL,DirS,VP,EP,GP,EL>& g, Tag) {
- return get_property_value(g.m_property, Tag());
+ template<ADJLIST_PARAMS, typename Tag>
+ inline typename graph_property<ADJLIST, Tag>::type const&
+ get_property(ADJLIST const& g, Tag) {
+ return get_property_value(*g.m_property, Tag());
   }
 
   // dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
@@ -598,10 +598,6 @@
 #endif
 
 // Mutability Traits
-#define ADJLIST_PARAMS \
- typename OEL, typename VL, typename D, typename VP, typename EP, \
- typename GP, typename EL
-#define ADJLIST adjacency_list<OEL,VL,D,VP,EP,GP,EL>
 template <ADJLIST_PARAMS>
 struct graph_mutability_traits<ADJLIST> {
     typedef mutable_property_graph_tag category;

Modified: trunk/boost/graph/adjacency_matrix.hpp
==============================================================================
--- trunk/boost/graph/adjacency_matrix.hpp (original)
+++ trunk/boost/graph/adjacency_matrix.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -80,36 +80,36 @@
     }
 
 
-
+ // NOTE: These functions collide with the get_property function for
+ // accessing bundled graph properties. Be excplicit when using them.
     template <typename EdgeProperty>
     const EdgeProperty&
- get_property(const std::pair<bool, EdgeProperty>& stored_edge) {
+ get_edge_property(const std::pair<bool, EdgeProperty>& stored_edge) {
       return stored_edge.second;
     }
     template <typename EdgeProperty>
     EdgeProperty&
- get_property(std::pair<bool, EdgeProperty>& stored_edge) {
+ get_edge_property(std::pair<bool, EdgeProperty>& stored_edge) {
       return stored_edge.second;
     }
 
     template <typename StoredEdgeProperty, typename EdgeProperty>
     inline void
- set_property(std::pair<bool, StoredEdgeProperty>& stored_edge,
- const EdgeProperty& ep, int) {
+ set_edge_property(std::pair<bool, StoredEdgeProperty>& stored_edge,
+ const EdgeProperty& ep, int) {
       stored_edge.second = ep;
     }
 
- inline const no_property& get_property(const char&) {
+ inline const no_property& get_edge_property(const char&) {
       static no_property s_prop;
       return s_prop;
     }
- inline no_property& get_property(char&) {
+ inline no_property& get_edge_property(char&) {
       static no_property s_prop;
       return s_prop;
     }
     template <typename EdgeProxy, typename EdgeProperty>
- inline void
- set_property(EdgeProxy, const EdgeProperty&, ...) {}
+ inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...) {}
 
     //=======================================================================
     // Directed Out Edge Iterator
@@ -155,8 +155,9 @@
         inline EdgeDescriptor
         dereference() const
         {
- return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ,
- &get_property(*this->base()));
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0),
+ m_src, m_targ,
+ &get_edge_property(*this->base()));
         }
         VertexDescriptor m_src, m_targ;
         VerticesSizeType m_n;
@@ -211,8 +212,9 @@
         inline EdgeDescriptor
         dereference() const
         {
- return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src, m_targ,
- &get_property(*this->base()));
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0),
+ m_src, m_targ,
+ &get_edge_property(*this->base()));
         }
         MatrixIter m_last;
         VertexDescriptor m_src, m_targ;
@@ -276,10 +278,9 @@
         inline EdgeDescriptor
         dereference() const
         {
- return EdgeDescriptor(
- get_edge_exists(*this->base(), 0), m_src, m_targ
- , &get_property(*this->base())
- );
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0),
+ m_src, m_targ,
+ &get_edge_property(*this->base()));
         }
 
         VertexDescriptor m_src, m_inc, m_targ;
@@ -343,10 +344,9 @@
         inline EdgeDescriptor
         dereference() const
         {
- return EdgeDescriptor(
- get_edge_exists(*this->base(), 0), m_targ, m_src
- , &get_property(*this->base())
- );
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0),
+ m_targ, m_src,
+ &get_edge_property(*this->base()));
         }
 
         VertexDescriptor m_src, m_inc, m_targ;
@@ -418,10 +418,9 @@
         inline EdgeDescriptor
         dereference() const
         {
- return EdgeDescriptor(
- get_edge_exists(
- *this->base(), 0), m_src, m_targ, &get_property(*this->base())
- );
+ return EdgeDescriptor(get_edge_exists(*this->base(), 0),
+ m_src, m_targ,
+ &get_edge_property(*this->base()));
         }
 
         MatrixIter m_start;
@@ -485,34 +484,25 @@
     BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
 #endif
 
-#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
- typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::type
- vertex_property_type;
- typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type
- edge_property_type;
-
- private:
- typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::retagged
- maybe_vertex_bundled;
+#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+ typedef typename graph_detail::graph_prop<GraphProperty>::property graph_property_type;
+ typedef typename graph_detail::graph_prop<GraphProperty>::bundle graph_bundled;
 
- typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::retagged
- maybe_edge_bundled;
+ typedef typename graph_detail::vertex_prop<VertexProperty>::property vertex_property_type;
+ typedef typename graph_detail::vertex_prop<VertexProperty>::bundle vertex_bundled;
 
- public:
- // The types that are actually bundled
- typedef typename mpl::if_c<(is_same<maybe_vertex_bundled, no_property>::value),
- no_vertex_bundle,
- maybe_vertex_bundled>::type vertex_bundled;
- typedef typename mpl::if_c<(is_same<maybe_edge_bundled, no_property>::value),
- no_edge_bundle,
- maybe_edge_bundled>::type edge_bundled;
+ typedef typename graph_detail::edge_prop<EdgeProperty>::property edge_property_type;
+ typedef typename graph_detail::edge_prop<EdgeProperty>::bundle edge_bundled;
 #else
- typedef EdgeProperty edge_property_type;
- typedef VertexProperty vertex_property_type;
+ typedef GraphProperty graph_property_type;
+ typedef no_graph_bundle graph_bundled;
+
+ typedef VertexProperty vertex_property_type;
     typedef no_vertex_bundle vertex_bundled;
- typedef no_edge_bundle edge_bundled;
+
+ typedef EdgeProperty edge_property_type;
+ typedef no_edge_bundle edge_bundled;
 #endif
- typedef GraphProperty graph_property_type;
 
   public: // should be private
     typedef typename mpl::if_<typename has_property<edge_property_type>::type,
@@ -660,6 +650,12 @@
 
     const edge_bundled& operator[](edge_descriptor e) const
     { return get(edge_bundle, *this)[e]; }
+
+ graph_bundled& operator[](graph_bundle_t)
+ { return get_property(*this); }
+
+ const graph_bundled& operator[](graph_bundle_t) const
+ { return get_property(*this); }
 #endif
 
     //private: if friends worked, these would be private
@@ -689,7 +685,7 @@
     VertexList m_vertex_set;
     std::vector<vertex_property_type> m_vertex_properties;
     size_type m_num_edges;
- GraphProperty m_property;
+ graph_property_type m_property;
   };
 
   //=========================================================================
@@ -704,7 +700,7 @@
   {
     bool exists = detail::get_edge_exists(g.get_edge(u,v), 0);
     typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
- e(exists, u, v, &detail::get_property(g.get_edge(u,v)));
+ e(exists, u, v, &detail::get_edge_property(g.get_edge(u,v)));
     return std::make_pair(e, exists);
   }
 
@@ -937,14 +933,14 @@
       edge_descriptor;
     if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) {
       ++(g.m_num_edges);
- detail::set_property(g.get_edge(u,v), EP(ep), 0);
+ detail::set_edge_property(g.get_edge(u,v), EP(ep), 0);
       detail::set_edge_exists(g.get_edge(u,v), true, 0);
       return std::make_pair
- (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
+ (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))),
          true);
     } else
       return std::make_pair
- (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))),
+ (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))),
          false);
   }
   // O(1)
@@ -1050,8 +1046,7 @@
 
   template <typename D, typename VP, typename EP, typename GP, typename A,
             typename Tag>
- inline
- typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
+ inline typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
   get_property(adjacency_matrix<D,VP,EP,GP,A>& g, Tag)
   {
       return get_property_value(g.m_property, Tag());
@@ -1059,9 +1054,7 @@
 
   template <typename D, typename VP, typename EP, typename GP, typename A,
             typename Tag>
- inline
- const
- typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
+ inline const typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
   get_property(const adjacency_matrix<D,VP,EP,GP,A>& g, Tag)
   {
       return get_property_value(g.m_property, Tag());

Modified: trunk/boost/graph/directed_graph.hpp
==============================================================================
--- trunk/boost/graph/directed_graph.hpp (original)
+++ trunk/boost/graph/directed_graph.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -33,9 +33,13 @@
 class directed_graph
 {
 public:
- typedef typename graph_detail::vertex_prop<VertexProp>::type vertex_property_type;
+ typedef typename graph_detail::graph_prop<GraphProp>::property graph_property_type;
+ typedef typename graph_detail::graph_prop<GraphProp>::bundle graph_bundled;
+
+ typedef typename graph_detail::vertex_prop<VertexProp>::property vertex_property_type;
     typedef typename graph_detail::vertex_prop<VertexProp>::bundle vertex_bundled;
- typedef typename graph_detail::edge_prop<EdgeProp>::type edge_property_type;
+
+ typedef typename graph_detail::edge_prop<EdgeProp>::property edge_property_type;
     typedef typename graph_detail::edge_prop<EdgeProp>::bundle edge_bundled;
 
 private:
@@ -58,9 +62,6 @@
     typedef typename graph_type::directed_selector directed_selector;
 
 public:
- typedef directed_graph_tag graph_tag;
- typedef typename graph_type::graph_property_type graph_property_type;
-
     // more commonly used graph types
     typedef typename graph_type::stored_vertex stored_vertex;
     typedef typename graph_type::vertices_size_type vertices_size_type;
@@ -77,6 +78,7 @@
     typedef typename graph_type::adjacency_iterator adjacency_iterator;
 
     // miscellaneous types
+ typedef directed_graph_tag graph_tag;
     typedef typename graph_type::directed_category directed_category;
     typedef typename graph_type::edge_parallel_category edge_parallel_category;
     typedef typename graph_type::traversal_category traversal_category;
@@ -283,6 +285,12 @@
 
     edge_bundled const& operator[](edge_descriptor e) const
     { return m_graph[e]; }
+
+ graph_bundled& operator[](graph_bundle_t)
+ { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ { return get_property(*this); }
 #endif
 
     // Graph concepts
@@ -345,14 +353,12 @@
 // IncidenceGraph concepts
 template <DIRECTED_GRAPH_PARAMS>
 inline typename DIRECTED_GRAPH::vertex_descriptor
-source(typename DIRECTED_GRAPH::edge_descriptor e,
- DIRECTED_GRAPH const& g)
+source(typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g)
 { return source(e, g.impl()); }
 
 template <DIRECTED_GRAPH_PARAMS>
 inline typename DIRECTED_GRAPH::vertex_descriptor
-target(typename DIRECTED_GRAPH::edge_descriptor e,
- DIRECTED_GRAPH const& g)
+target(typename DIRECTED_GRAPH::edge_descriptor e, DIRECTED_GRAPH const& g)
 { return target(e, g.impl()); }
 
 template <DIRECTED_GRAPH_PARAMS>

Modified: trunk/boost/graph/graph_traits.hpp
==============================================================================
--- trunk/boost/graph/graph_traits.hpp (original)
+++ trunk/boost/graph/graph_traits.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -218,30 +218,36 @@
     typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
 
     template <typename G>
- struct edge_property_type {
- typedef typename G::edge_property_type type;
+ struct graph_property_type {
+ typedef typename G::graph_property_type type;
     };
     template <typename G>
- struct vertex_property_type {
- typedef typename G::vertex_property_type type;
+ struct edge_property_type {
+ typedef typename G::edge_property_type type;
     };
     template <typename G>
- struct graph_property_type {
- typedef typename G::graph_property_type type;
+ struct vertex_property_type {
+ typedef typename G::vertex_property_type type;
     };
 
     struct no_bundle { };
+ struct no_graph_bundle : no_bundle { };
     struct no_vertex_bundle : no_bundle { };
     struct no_edge_bundle : no_bundle { };
 
     template<typename G>
+ struct graph_bundle_type {
+ typedef typename G::graph_bundled type;
+ };
+
+ template<typename G>
     struct vertex_bundle_type {
- typedef typename G::vertex_bundled type;
+ typedef typename G::vertex_bundled type;
     };
 
     template<typename G>
     struct edge_bundle_type {
- typedef typename G::edge_bundled type;
+ typedef typename G::edge_bundled type;
     };
 
     namespace graph { namespace detail {
@@ -258,12 +264,11 @@
     } } // namespace graph::detail
 
     namespace graph_detail {
- // A helper metafunction for determining whether or not a type is
- // bundled.
- template <typename T>
- struct is_no_bundle
- : mpl::bool_<is_convertible<T, no_bundle>::value>
- { };
+ // A helper metafunction for determining whether or not a type is
+ // bundled.
+ template <typename T>
+ struct is_no_bundle : mpl::bool_<is_convertible<T, no_bundle>::value>
+ { };
     } // namespace graph_detail
 
     /** @name Graph Property Traits
@@ -272,24 +277,43 @@
      * edges.
      */
     //@{
- template <typename Graph>
- struct has_vertex_property
- : mpl::not_<
- typename detail::is_no_property<typename vertex_property_type<Graph>::type>
+ template<typename Graph>
+ struct has_graph_property
+ : mpl::not_<
+ typename detail::is_no_property<
+ typename graph_property_type<Graph>::type
>::type
+ >::type
+ { };
+
+ template<typename Graph>
+ struct has_bundled_graph_property
+ : mpl::not_<
+ graph_detail::is_no_bundle<typename graph_bundle_type<Graph>::type>
+ >
     { };
+
     template <typename Graph>
- struct has_edge_property
+ struct has_vertex_property
         : mpl::not_<
- typename detail::is_no_property<typename edge_property_type<Graph>::type>
+ typename detail::is_no_property<typename vertex_property_type<Graph>::type>
>::type
     { };
+
     template <typename Graph>
     struct has_bundled_vertex_property
         : mpl::not_<
             graph_detail::is_no_bundle<typename vertex_bundle_type<Graph>::type>
>
     { };
+
+ template <typename Graph>
+ struct has_edge_property
+ : mpl::not_<
+ typename detail::is_no_property<typename edge_property_type<Graph>::type>
+ >::type
+ { };
+
     template <typename Graph>
     struct has_bundled_edge_property
         : mpl::not_<

Modified: trunk/boost/graph/labeled_graph.hpp
==============================================================================
--- trunk/boost/graph/labeled_graph.hpp (original)
+++ trunk/boost/graph/labeled_graph.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -278,10 +278,13 @@
     typedef typename graph_traits<graph_type>::edge_iterator edge_iterator;
     typedef typename graph_traits<graph_type>::edges_size_type edges_size_type;
 
- typedef typename graph_type::vertex_property_type vertex_property_type;
- typedef typename graph_type::edge_property_type edge_property_type;
     typedef typename graph_type::graph_property_type graph_property_type;
+ typedef typename graph_type::graph_bundled graph_bundled;
+
+ typedef typename graph_type::vertex_property_type vertex_property_type;
     typedef typename graph_type::vertex_bundled vertex_bundled;
+
+ typedef typename graph_type::edge_property_type edge_property_type;
     typedef typename graph_type::edge_bundled edge_bundled;
 
     typedef typename Base::label_type label_type;

Modified: trunk/boost/graph/properties.hpp
==============================================================================
--- trunk/boost/graph/properties.hpp (original)
+++ trunk/boost/graph/properties.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -126,6 +126,7 @@
   BOOST_DEF_PROPERTY(graph, visitor);
 
   // These tags are used for property bundles
+ BOOST_DEF_PROPERTY(graph, bundle);
   BOOST_DEF_PROPERTY(vertex, bundle);
   BOOST_DEF_PROPERTY(edge, bundle);
 
@@ -199,6 +200,7 @@
     };
     template <class Graph, class PropertyTag>
     class vertex_property_map {
+ public:
       typedef typename vertex_property_type<Graph>::type Property;
       typedef typename graph_tag_or_void<Graph>::type graph_tag;
       typedef typename vertex_property_selector<graph_tag>::type Selector;
@@ -242,7 +244,7 @@
 
   template <class Graph, class Property>
   struct property_map {
- private:
+ // private:
     typedef typename property_kind<Property>::type Kind;
     typedef typename detail::property_map_kind_selector<Kind>::type Selector;
     typedef typename Selector::template bind_<Graph, Property> Bind;
@@ -263,8 +265,9 @@
   template <class Graph, class Property>
   class graph_property {
   public:
- typedef typename property_value<typename Graph::graph_property_type,
- Property>::type type;
+ typedef typename property_value<
+ typename Graph::graph_property_type, Property
+ >::type type;
   };
 
   template <class Graph>
@@ -432,44 +435,71 @@
 // These metafunctions help implement the process of determining the vertex
 // and edge properties of a graph.
 namespace graph_detail {
- template <typename Retag>
+ template<typename Retag>
     struct retagged_property {
         typedef typename Retag::type type;
     };
 
- template <typename Retag, typename With, typename Without>
+ // Search the normalized PropList (as returned by retagged<>::type) for
+ // the given bundle. Return the type error if no such bundle can be found.
+ template <typename PropList, typename Bundle>
     struct retagged_bundle {
- typedef typename mpl::if_<
- is_same<typename Retag::retagged, no_property>,
- Without,
- With
- >::type type;
- };
-
- template <typename Prop>
- struct vertex_prop {
- private:
- typedef detail::retag_property_list<vertex_bundle_t, Prop> Retag;
- public:
- typedef typename retagged_property<Retag>::type type;
- typedef typename retagged_bundle<
- Retag, Prop, no_vertex_bundle
- >::type bundle;
+ typedef typename property_value<PropList, Bundle>::type Value;
+ typedef typename mpl::if_<
+ is_same<Value, detail::error_property_not_found>, no_bundle, Value
+ >::type type;
     };
 
- template <typename Prop>
- struct edge_prop {
-// private:
- typedef detail::retag_property_list<edge_bundle_t, Prop> Retag;
+ template<typename Prop, typename Bundle>
+ class normal_property {
+ // Normalize the property into a property list.
+ typedef detail::retag_property_list<Bundle, Prop> List;
     public:
- typedef typename Retag::retagged retagged;
- typedef typename retagged_property<Retag>::type type;
- typedef typename retagged_bundle<
- Retag, Prop, no_edge_bundle
- >::type bundle;
- };
+ // Extract the normalized property and bundle types.
+ typedef typename retagged_property<List>::type property;
+ typedef typename retagged_bundle<property, Bundle>::type bundle;
+ };
+
+ template<typename Prop>
+ struct graph_prop : normal_property<Prop, graph_bundle_t>
+ { };
+
+ template<typename Prop>
+ struct vertex_prop : normal_property<Prop, vertex_bundle_t>
+ { };
+
+ template<typename Prop>
+ struct edge_prop : normal_property<Prop, edge_bundle_t>
+ { };
 } // namespace graph_detail
 
+// NOTE: These functions are declared, but never defined since they need to
+// be overloaded by graph implementations. However, we need them to be
+// declared for the functions below.
+template<typename Graph, typename Tag>
+typename graph_property<Graph, graph_bundle_t>::type&
+get_property(Graph& g, Tag);
+
+template<typename Graph, typename Tag>
+typename graph_property<Graph, graph_bundle_t>::type const&
+get_property(Graph const& g, Tag);
+
+#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+// NOTE: This operation is a simple adaptor over the overloaded get_property
+// operations.
+template<typename Graph>
+inline typename graph_property<Graph, graph_bundle_t>::type&
+get_property(Graph& g) {
+ return get_property(g, graph_bundle);
+}
+
+template<typename Graph>
+inline typename graph_property<Graph, graph_bundle_t>::type const&
+get_property(Graph const& g) {
+ return get_property(g, graph_bundle);
+}
+#endif
+
 } // namespace boost
 
 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)

Modified: trunk/boost/graph/reverse_graph.hpp
==============================================================================
--- trunk/boost/graph/reverse_graph.hpp (original)
+++ trunk/boost/graph/reverse_graph.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -79,19 +79,33 @@
 
     typedef reverse_graph_tag graph_tag;
 
+ // Graph, vertex, and edge properties
+ typedef typename graph_property_type<base_type>::type graph_property_type;
+ typedef typename graph_bundle_type<base_type>::type graph_bundled;
+
+ typedef typename vertex_property_type<base_type>::type vertex_property_type;
+ typedef typename vertex_bundle_type<base_type>::type vertex_bundled;
+
+ typedef typename edge_property_type<base_type>::type edge_property_type;
+ typedef typename edge_bundle_type<base_type>::type edge_bundled;
+
 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
     // Bundled properties support
     template<typename Descriptor>
- typename graph::detail::bundled_result<BidirectionalGraph,
- Descriptor>::type&
+ typename graph::detail::bundled_result<BidirectionalGraph, Descriptor>::type&
     operator[](Descriptor x)
     { return m_g[x]; }
 
     template<typename Descriptor>
- typename graph::detail::bundled_result<BidirectionalGraph,
- Descriptor>::type const&
+ typename graph::detail::bundled_result<BidirectionalGraph, Descriptor>::type const&
     operator[](Descriptor x) const
     { return m_g[x]; }
+
+ graph_bundled& operator[](graph_bundle_t)
+ { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ { return get_property(*this); }
 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
 
     static vertex_descriptor null_vertex()
@@ -116,11 +130,11 @@
 
 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
   template<typename Graph, typename GraphRef>
- struct vertex_bundle_type<reverse_graph<Graph, GraphRef> >
+ struct vertex_bundle_type<reverse_graph<Graph, GraphRef> >
     : vertex_bundle_type<Graph> { };
 
   template<typename Graph, typename GraphRef>
- struct edge_bundle_type<reverse_graph<Graph, GraphRef> >
+ struct edge_bundle_type<reverse_graph<Graph, GraphRef> >
     : edge_bundle_type<Graph> { };
 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
 
@@ -194,7 +208,7 @@
 }
 
 template <class BidirectionalGraph, class GRef>
-inline std::pair<typename graph_traits<BidirectionalGraph>::edge_descriptor,
+inline std::pair<typename graph_traits<BidirectionalGraph>::edge_descriptor,
                  bool>
 edge(const typename graph_traits<BidirectionalGraph>::vertex_descriptor u,
      const typename graph_traits<BidirectionalGraph>::vertex_descriptor v,
@@ -318,7 +332,7 @@
 template<typename BidirectionalGraph, typename GRef, typename Tag,
          typename Value>
 inline void
-set_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag,
+set_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag,
              const Value& value)
 {
   set_property(g.m_g, tag, value);

Modified: trunk/boost/graph/undirected_graph.hpp
==============================================================================
--- trunk/boost/graph/undirected_graph.hpp (original)
+++ trunk/boost/graph/undirected_graph.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -33,17 +33,22 @@
  */
 template <
     typename VertexProp = no_property,
- typename EdgeProp= no_property,
+ typename EdgeProp = no_property,
     typename GraphProp = no_property>
 class undirected_graph
 {
 public:
- typedef typename graph_detail::vertex_prop<VertexProp>::type vertex_property_type;
+ typedef typename graph_detail::graph_prop<GraphProp>::property graph_property_type;
+ typedef typename graph_detail::graph_prop<GraphProp>::bundle graph_bundled;
+
+ typedef typename graph_detail::vertex_prop<VertexProp>::property vertex_property_type;
     typedef typename graph_detail::vertex_prop<VertexProp>::bundle vertex_bundled;
- typedef typename graph_detail::edge_prop<EdgeProp>::type edge_property_type;
+
+ typedef typename graph_detail::edge_prop<EdgeProp>::property edge_property_type;
     typedef typename graph_detail::edge_prop<EdgeProp>::bundle edge_bundled;
 
 private:
+ // Embed indices into the vertex type.
     typedef property<vertex_index_t, unsigned, vertex_property_type> vertex_property;
     typedef property<edge_index_t, unsigned, edge_property_type> edge_property;
 public:
@@ -62,9 +67,6 @@
     typedef typename graph_type::directed_selector directed_selector;
 
 public:
- typedef undirected_graph_tag graph_tag;
- typedef typename graph_type::graph_property_type graph_property_type;
-
     // more commonly used graph types
     typedef typename graph_type::stored_vertex stored_vertex;
     typedef typename graph_type::vertices_size_type vertices_size_type;
@@ -81,6 +83,7 @@
     typedef typename graph_type::adjacency_iterator adjacency_iterator;
 
     // miscellaneous types
+ typedef undirected_graph_tag graph_tag;
     typedef typename graph_type::directed_category directed_category;
     typedef typename graph_type::edge_parallel_category edge_parallel_category;
     typedef typename graph_type::traversal_category traversal_category;
@@ -276,6 +279,12 @@
 
     edge_bundled const& operator[](edge_descriptor e) const
     { return m_graph[e]; }
+
+ graph_bundled& operator[](graph_bundle_t)
+ { return get_property(*this); }
+
+ graph_bundled const& operator[](graph_bundle_t) const
+ { return get_property(*this); }
 #endif
 
     // Graph concepts

Modified: trunk/libs/graph/test/test_graph.hpp
==============================================================================
--- trunk/libs/graph/test/test_graph.hpp (original)
+++ trunk/libs/graph/test/test_graph.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -60,6 +60,12 @@
  * generator to define property maps.
  */
 //@{
+// This is really just a place holder to make sure that bundled graph
+// properties actually work. There are no semantics to this type.
+struct GraphBundle {
+ int value;
+};
+
 struct VertexBundle {
     VertexBundle() : value() { }
     VertexBundle(int n) : value(n) { }
@@ -105,6 +111,7 @@
     // Test constrution and vertex list.
     build_graph(g, can_add_vertex, is_labeled);
     build_property_graph(g, can_add_vertex, is_labeled);
+
     test_vertex_list_graph(g);
 
     // Collect the vertices for an easy method of "naming" them.
@@ -118,7 +125,7 @@
 
     // Test connection and edge list
     connect_graph(g, verts, is_labeled);
-// connect_property_graph(g, verts, is_labeld);
+ // connect_property_graph(g, verts, is_labeld);
     test_edge_list_graph(g);
 
     // Test properties

Modified: trunk/libs/graph/test/test_graphs.cpp
==============================================================================
--- trunk/libs/graph/test/test_graphs.cpp (original)
+++ trunk/libs/graph/test/test_graphs.cpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -1,4 +1,4 @@
-// (C) Copyright 2009 Andrew Sutton
+// (C) Copyright 2009-2010 Andrew Sutton
 //
 // Use, modification and distribution are subject to the
 // Boost Software License, Version 1.0 (See accompanying file
@@ -24,130 +24,147 @@
 
 int main()
 {
- // Bootstrap all of the tests by declaring a kind graph and asserting some
- // basic properties about it.
- {
- typedef undirected_graph<VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_undirected_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_mutable_graph<Graph>);
- BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
- Graph g;
- test_graph(g);
- }
- {
- typedef directed_graph<VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_mutable_graph<Graph>);
- BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
- Graph g;
- test_graph(g);
- }
- {
- typedef adjacency_list<vecS, vecS, undirectedS, VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_undirected_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
- Graph g;
- test_graph(g);
- }
- {
- typedef adjacency_list<vecS, vecS, directedS, VertexBundle, EdgeBundle> Graph;
- Graph g;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(!is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_directed_unidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
- test_graph(g);
- }
- {
- // Common bidi adjlist
- typedef adjacency_list<vecS, vecS, bidirectionalS, VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
- Graph g;
- test_graph(g);
- }
- {
- // Same as above, but testing VL==listS
- typedef adjacency_list<vecS, listS, bidirectionalS, VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
- Graph g;
- test_graph(g);
- }
- {
- // TODO: What other kinds of graphs do we have here...
- typedef adjacency_matrix<directedS, VertexBundle, EdgeBundle> Graph;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(!is_multigraph<Graph>);
- BOOST_META_ASSERT(has_vertex_property<Graph>);
- BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(has_edge_property<Graph>);
- BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_mutable_edge_graph<Graph>);
- BOOST_META_ASSERT(is_mutable_edge_property_graph<Graph>);
- Graph g(N);
- test_graph(g);
- }
- {
- typedef labeled_graph<directed_graph<>, unsigned> Graph;
- BOOST_META_ASSERT(is_directed_graph<Graph>);
- BOOST_META_ASSERT(is_multigraph<Graph>);
- BOOST_META_ASSERT(is_incidence_graph<Graph>);
- BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
- BOOST_META_ASSERT(is_labeled_mutable_property_graph<Graph>);
- BOOST_META_ASSERT(is_labeled_graph<Graph>);
- BOOST_META_ASSERT(!has_vertex_property<Graph>);
- BOOST_META_ASSERT(!has_bundled_vertex_property<Graph>);
- BOOST_META_ASSERT(!has_edge_property<Graph>);
- BOOST_META_ASSERT(!has_bundled_edge_property<Graph>);
- BOOST_META_ASSERT(is_labeled_mutable_graph<Graph>);
- Graph g;
- test_graph(g);
- }
+ // Bootstrap all of the tests by declaring a kind graph and asserting some
+ // basic properties about it.
+ {
+ typedef undirected_graph<VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_undirected_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_mutable_graph<Graph>);
+ BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ {
+ typedef directed_graph<VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_mutable_graph<Graph>);
+ BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ {
+ typedef adjacency_list<vecS, vecS, undirectedS, VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_undirected_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ {
+ typedef adjacency_list<vecS, vecS, directedS, VertexBundle, EdgeBundle, GraphBundle> Graph;
+ Graph g;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(!is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_directed_unidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
+ test_graph(g);
+ }
+ {
+ // Common bidi adjlist
+ typedef adjacency_list<vecS, vecS, bidirectionalS, VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_add_only_property_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ {
+ // Same as above, but testing VL==listS
+ typedef adjacency_list<vecS, listS, bidirectionalS, VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_mutable_property_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ {
+ typedef adjacency_matrix<directedS, VertexBundle, EdgeBundle, GraphBundle> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(!is_multigraph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_mutable_edge_graph<Graph>);
+ BOOST_META_ASSERT(is_mutable_edge_property_graph<Graph>);
+ Graph g(N);
+ test_graph(g);
+ }
+ {
+ typedef adjacency_matrix<directedS, VertexBundle, EdgeBundle> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(!is_multigraph<Graph>);
+ BOOST_META_ASSERT(has_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(has_edge_property<Graph>);
+ BOOST_META_ASSERT(has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_mutable_edge_graph<Graph>);
+ BOOST_META_ASSERT(is_mutable_edge_property_graph<Graph>);
+ Graph g(N);
+ test_graph(g);
+ }
+ /*
+ {
+ typedef labeled_graph<directed_graph<>, unsigned> Graph;
+ BOOST_META_ASSERT(is_directed_graph<Graph>);
+ BOOST_META_ASSERT(is_multigraph<Graph>);
+ BOOST_META_ASSERT(is_incidence_graph<Graph>);
+ BOOST_META_ASSERT(is_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_directed_bidirectional_graph<Graph>);
+ BOOST_META_ASSERT(is_labeled_mutable_property_graph<Graph>);
+ BOOST_META_ASSERT(is_labeled_graph<Graph>);
+ BOOST_META_ASSERT(!has_vertex_property<Graph>);
+ BOOST_META_ASSERT(!has_bundled_vertex_property<Graph>);
+ BOOST_META_ASSERT(!has_edge_property<Graph>);
+ BOOST_META_ASSERT(!has_bundled_edge_property<Graph>);
+ BOOST_META_ASSERT(is_labeled_mutable_graph<Graph>);
+ Graph g;
+ test_graph(g);
+ }
+ */
+
+ // TODO: What other kinds of graphs do we have here...
+
 }
 

Modified: trunk/libs/graph/test/test_properties.hpp
==============================================================================
--- trunk/libs/graph/test/test_properties.hpp (original)
+++ trunk/libs/graph/test/test_properties.hpp 2010-08-06 14:13:16 EDT (Fri, 06 Aug 2010)
@@ -7,6 +7,30 @@
 #ifndef TEST_PROPERTIES_HPP
 #define TEST_PROPERTIES_HPP
 
+template<typename T> T const& as_const(T& x) { return x; }
+template<typename T> void ignore(T const&) { }
+
+template<typename Graph>
+void test_graph_bundle(Graph& g, boost::mpl::true_) {
+ using namespace boost;
+ std::cout << "...test_graph_bundle\n";
+
+ typedef typename graph_property_type<Graph>::type Property;
+ typedef typename graph_bundle_type<Graph>::type Bundle;
+
+ GraphBundle& b1 = g[graph_bundle];
+ GraphBundle& b2 = get_property(g);
+ ignore(b1); ignore(b2);
+
+ GraphBundle const& cb1 = as_const(g)[graph_bundle];
+ GraphBundle const& cb2 = get_property(g);
+ ignore(cb1); ignore(cb2);
+}
+
+template<typename Graph>
+void test_graph_bundle(Graph& g, boost::mpl::false_)
+{ }
+
 /** @name Test Vertex Bundle
  * Exercise the vertex bundle. Note that this is expected to be of type
  * VertexBundle.
@@ -14,30 +38,28 @@
 //@{
 template <typename Graph, typename VertexSet>
 void test_vertex_bundle(Graph& g, VertexSet const& verts, boost::mpl::true_) {
- using namespace boost;
- BOOST_CONCEPT_ASSERT((GraphConcept<Graph>));
- typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
- BOOST_CONCEPT_ASSERT((PropertyGraphConcept<Graph, Vertex, vertex_bundle_t>));
-
- std::cout << "...test_vertex_bundle\n";
+ using namespace boost;
+ BOOST_CONCEPT_ASSERT((GraphConcept<Graph>));
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ BOOST_CONCEPT_ASSERT((PropertyGraphConcept<Graph, Vertex, vertex_bundle_t>));
 
     // Test bundling via the graph object on the lollipop vertex.
- Vertex v = verts[5];
- VertexBundle& b = g[v];
- b.value = 10;
- BOOST_ASSERT(g[v].value == 10);
-
- // Test bundling via the property map.
- typedef typename property_map<Graph, int VertexBundle::*>::type BundleMap;
- BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept<BundleMap, Vertex>));
- BundleMap map = get(&VertexBundle::value, g);
- put(map, v, 5);
- BOOST_ASSERT(get(map, v) == 5);
-
- typedef typename property_map<Graph, int VertexBundle::*>::const_type ConstBundleMap;
- BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept<ConstBundleMap, Vertex>));
- ConstBundleMap cmap = get(&VertexBundle::value, (Graph const&)g);
- BOOST_ASSERT(get(cmap, v) == 5);
+ Vertex v = verts[5];
+ VertexBundle& b = g[v];
+ b.value = 10;
+ BOOST_ASSERT(g[v].value == 10);
+
+ // Test bundling via the property map.
+ typedef typename property_map<Graph, int VertexBundle::*>::type BundleMap;
+ BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept<BundleMap, Vertex>));
+ BundleMap map = get(&VertexBundle::value, g);
+ put(map, v, 5);
+ BOOST_ASSERT(get(map, v) == 5);
+
+ typedef typename property_map<Graph, int VertexBundle::*>::const_type ConstBundleMap;
+ BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept<ConstBundleMap, Vertex>));
+ ConstBundleMap cmap = get(&VertexBundle::value, (Graph const&)g);
+ BOOST_ASSERT(get(cmap, v) == 5);
 }
 
 template <typename Graph, typename VertexSet>
@@ -90,11 +112,15 @@
  */
 template <typename Graph, typename VertexSet>
 void test_properties(Graph& g, VertexSet const& verts) {
- typename boost::has_bundled_vertex_property<Graph>::type vertex_bundled;
- typename boost::has_bundled_edge_property<Graph>::type edge_bundled;
+ using namespace boost;
 
- test_vertex_bundle(g, verts, vertex_bundled);
- test_edge_bundle(g, verts, edge_bundled);
+ typename has_bundled_graph_property<Graph>::type graph_bundled;
+ typename has_bundled_vertex_property<Graph>::type vertex_bundled;
+ typename has_bundled_edge_property<Graph>::type edge_bundled;
+
+ test_graph_bundle(g, graph_bundled);
+ test_vertex_bundle(g, verts, vertex_bundled);
+ test_edge_bundle(g, verts, edge_bundled);
 }
 //@}
 


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