? libs/graph/doc/a.out
? libs/graph/doc/eg1-iso.cpp.patch
? libs/graph/doc/eg1-iso.ii
? libs/graph/doc/eg1-iso.ti
? libs/graph/test/a.out
? boost/pending/property_fixed.hpp
Index: boost/graph/adjacency_list.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/graph/adjacency_list.hpp,v
retrieving revision 1.35
diff -b -u -r1.35 adjacency_list.hpp
--- boost/graph/adjacency_list.hpp	19 May 2003 19:20:18 -0000	1.35
+++ boost/graph/adjacency_list.hpp	7 May 2004 14:57:33 -0000
@@ -46,6 +46,7 @@
 #include <boost/property_map.hpp>
 #include <boost/pending/ct_if.hpp>
 #include <boost/graph/detail/edge.hpp>
+#include <boost/type_traits/is_same.hpp>
 
 namespace boost {
 
@@ -311,21 +312,54 @@
       adjacency_list<OutEdgeListS,VertexListS,DirectedS,
                      VertexProperty,EdgeProperty,GraphProperty,EdgeListS>,
       VertexListS, OutEdgeListS, DirectedS, 
-      VertexProperty, EdgeProperty, GraphProperty, EdgeListS>::type
+      typename detail::retag_property_list<vertex_bundle_t,
+                                           VertexProperty>::type,
+      typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type,
+      GraphProperty, EdgeListS>::type
   {
+    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;
+
+     struct no_vertex_bundle {};
+     struct no_edge_bundle {};
+
+  public:
+    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 ct_if<(is_same<maybe_vertex_bundled, no_property>::value),
+                           no_vertex_bundle,
+                           maybe_vertex_bundled>::type vertex_bundled;
+
+    typedef typename ct_if<(is_same<maybe_edge_bundled, no_property>::value),
+                           no_edge_bundle,
+                           maybe_edge_bundled>::type edge_bundled;
+
+  private:
     typedef adjacency_list self;
     typedef typename detail::adj_list_gen<
       self, VertexListS, OutEdgeListS, DirectedS, 
-      VertexProperty, EdgeProperty, GraphProperty, EdgeListS
+      vertex_property_type, edge_property_type, GraphProperty, EdgeListS
     >::type Base;
+
   public:
     typedef typename Base::stored_vertex stored_vertex;
     typedef typename Base::vertices_size_type vertices_size_type;
     typedef typename Base::edges_size_type edges_size_type;
     typedef typename Base::degree_size_type degree_size_type;
+    typedef typename Base::vertex_descriptor vertex_descriptor;
+    typedef typename Base::edge_descriptor edge_descriptor;
 
-    typedef EdgeProperty edge_property_type;
-    typedef VertexProperty vertex_property_type;
     typedef GraphProperty graph_property_type;
 
     inline adjacency_list(const GraphProperty& p = GraphProperty()) 
@@ -370,6 +404,56 @@
       *this = tmp;
     }
 
+    // Directly access a vertex or edge bundle
+    vertex_bundled& operator[](vertex_descriptor v)
+    { return get(vertex_bundle, *this)[v]; }
+
+    const vertex_bundled& operator[](vertex_descriptor v) const
+    { return get(vertex_bundle, *this)[v]; }
+
+    edge_bundled& operator[](edge_descriptor e)
+    { return get(edge_bundle, *this)[e]; }
+
+    const edge_bundled& operator[](edge_descriptor e) const
+    { return get(edge_bundle, *this)[e]; }
+
+    // Generate property maps from bundles given a member pointer
+    template<typename T>
+    bundle_property_map<self, vertex_descriptor, vertex_bundled, T>
+    operator->*(T vertex_bundled::* pm)
+    {
+      typedef bundle_property_map<self, vertex_descriptor, vertex_bundled, T>
+        result_type;
+      return result_type(this, pm);
+    }
+
+    template<typename T>
+    bundle_property_map<const self, vertex_descriptor, vertex_bundled, const T>
+    operator->*(T vertex_bundled::* pm) const
+    {
+      typedef bundle_property_map<const self, vertex_descriptor,
+                                  vertex_bundled, const T> result_type;
+      return result_type(this, pm);
+    }
+
+    template<typename T>
+    bundle_property_map<self, edge_descriptor, edge_bundled, T>
+    operator->*(T edge_bundled::* pm)
+    {
+      typedef bundle_property_map<self, edge_descriptor, edge_bundled, T>
+        result_type;
+      return result_type(this, pm);
+    }
+
+    template<typename T>
+    bundle_property_map<const self, edge_descriptor, edge_bundled, const T>
+    operator->*(T edge_bundled::* pm) const
+    {
+      typedef bundle_property_map<const self, edge_descriptor, edge_bundled,
+                                  const T> result_type;
+      return result_type(this, pm);
+    }
+
     //  protected:  (would be protected if friends were more portable)
     GraphProperty m_property;
   };
Index: boost/graph/graph_test.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/graph/graph_test.hpp,v
retrieving revision 1.15
diff -b -u -r1.15 graph_test.hpp
Index: boost/graph/properties.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/graph/properties.hpp,v
retrieving revision 1.48
diff -b -u -r1.48 properties.hpp
--- boost/graph/properties.hpp	7 Mar 2003 16:13:04 -0000	1.48
+++ boost/graph/properties.hpp	7 May 2004 14:57:33 -0000
@@ -113,6 +113,10 @@
   BOOST_DEF_PROPERTY(edge, residual_capacity);
   BOOST_DEF_PROPERTY(graph, visitor);
 
+  // For internal use only: these tags are used for property bundles
+  BOOST_DEF_PROPERTY(vertex, bundle);
+  BOOST_DEF_PROPERTY(edge, bundle);
+
 #undef BOOST_DEF_PROPERTY
 
   namespace detail {
@@ -327,6 +331,23 @@
     return make_iterator_vertex_map(c.begin());
   }
 
+  template<typename Graph, typename Descriptor, typename Bundle, typename T>
+  struct bundle_property_map
+    : put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
+  {
+    typedef Descriptor key_type;
+    typedef T value_type;
+    typedef T& reference;
+    typedef lvalue_property_map_tag category;
+
+    bundle_property_map(Graph* g, T Bundle::* pm) : g(g), pm(pm) {}
+
+    reference operator[](key_type k) const { return (*g)[k].*pm; }
+  private:
+    Graph* g;
+    T Bundle::* pm;
+  };
+
 } // namespace boost
 
 #endif /* BOOST_GRAPH_PROPERTIES_HPPA */
Index: boost/graph/reverse_graph.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/graph/reverse_graph.hpp,v
retrieving revision 1.16
diff -b -u -r1.16 reverse_graph.hpp
--- boost/graph/reverse_graph.hpp	15 Jan 2002 03:33:26 -0000	1.16
+++ boost/graph/reverse_graph.hpp	7 May 2004 14:57:34 -0000
@@ -78,6 +78,8 @@
       vertex_property_type;
     typedef reverse_graph_tag graph_tag;
     
+    static vertex_descriptor null_vertex()
+    { return Traits::null_vertex(); }
 
     // would be private, but template friends aren't portable enough.
  // private:
Index: libs/graph/doc/adjacency_list.html
===================================================================
RCS file: /cvsroot/boost/boost/libs/graph/doc/adjacency_list.html,v
retrieving revision 1.31
diff -b -u -r1.31 adjacency_list.html
--- libs/graph/doc/adjacency_list.html	3 May 2004 20:03:17 -0000	1.31
+++ libs/graph/doc/adjacency_list.html	7 May 2004 14:57:35 -0000
@@ -177,7 +177,8 @@
 Properties </A>. The property maps are objects that implement the
 interface defined in Section <A
 HREF="../../property_map/property_map.html">Property Map
-Concepts</A>. The property maps obtained from the
+Concepts</A> or may be <a href="bundles.html">bundled properties</a>,
+which have a more succinct syntax. The property maps obtained from the
 <TT>adjacency_list</TT> class are models of the <a
 href="../../property_map/LvaluePropertyMap.html">Lvalue Property
 Map</a> concept. If the <TT>adjacency_list</TT> is const,
Index: libs/graph/doc/bundles.html
===================================================================
RCS file: libs/graph/doc/bundles.html
diff -N libs/graph/doc/bundles.html
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libs/graph/doc/bundles.html	7 May 2004 14:57:35 -0000
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<!--
+--  Copyright Doug Gregor 2004. Use, modification and
+--  distribution is subject to the Boost Software License, Version
+--  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+--  http://www.boost.org/LICENSE_1_0.txt)
+
+-- For more information, see http://www.boost.org
+-->
+  <head>
+    <title>Bundled Properties</title>
+  </head>
+
+  <body BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
+        ALINK="#ff0000">
+    <IMG SRC="../../../c++boost.gif" 
+      ALT="C++ Boost" width="277" height="86"/> 
+    <h1>Bundled Properties</h1>
+
+      <p>Class template <code><a
+      href="adjacency_list.html">adjacency_list</a></code> supports
+      the introduction of named properties via <a
+      href="using_adjacency_list.html#sec:adjacency-list-properties">internal
+      properties</a>. However, this method is cumbersome in many uses,
+      where it would be more intuitive to just specify a structure or
+      class that contains internal properties for edges or
+      vertices. Bundled properties allow one to use
+      <code>adjacency_list</code> in this manner, providing a simple
+      way to introduce and access any number of internal properties
+      for vertices and edges with little effort.</p>
+
+      <p>One can introduce bundled properties into an
+      <code>adjacency_list</code> by providing a user-defined class
+      type for the <code>VertexProperties</code> or
+      <code>EdgeProperties</code> template arguments. The user-defined
+      class may alternatively be placed at the end of a
+      <code>property</code> list, replacing the (implicit)
+      <code>boost::no_property</code> argument.</p>
+
+      <h2>Example: Route planning</h2>
+      <p>Consider the implementation of a simple route planner that
+        should find the shortest directions from one city to another
+        via a set of highways. The vertices of the graph are cities,
+        and we may wish to store several bits of information about the
+        city within each vertex:</p>
+      <pre>
+struct City
+{
+  string name;
+  int population;
+  vector&lt;int&gt; zipcodes;
+};
+      </pre>
+      
+      <p>The edges in the graph represent highways, which also have
+        several interesting attributes:</p>
+
+      <pre>
+struct Highway
+{
+  string name;
+  double miles;
+  int speed_limit;
+  int lanes;
+  bool divided;
+};
+      </pre>
+
+      <p>Without bundled properties, translating this example directly
+      into an instantiation of <code>adjacency_list</code> would
+      involve several custom properties and would result in a type
+      like this:</p>
+      <pre>
+typedef boost::adjacency_list&lt;
+    boost::listS, boost::vecS, boost::bidirectionalS,
+    // Vertex properties
+    boost::property&lt;boost::vertex_name_t, std::string, 
+    boost::property&lt;population_t, int,
+    boost::property&lt;zipcodes_t, std::vector&lt;int&gt; &gt; &gt; &gt;,
+    // Edge properties
+    boost::property&lt;boost::edge_name_t, std::string,
+    boost::property&lt;boost::edge_length_t, double,
+    boost::property&lt;edge_speed_limit_t, int,
+    boost::property&lt;edge_lanes_t, int,
+    boost::property&lt;edge_divided, bool&gt; &gt; &gt; &gt; &gt; &gt;
+  Map;
+      </pre>
+
+      <p>With bundled properties, we can directly use the
+        <code>City</code> and <code>Highway</code> structures:</p>
+      <pre>
+typedef boost::adjacency_list&lt;
+    boost::listS, boost::vecS, boost::bidirectionalS,
+    City, Highway&gt; Map;
+      </pre>
+
+    <h2>Accessing bundled properties</h2>
+    <p>To access a bundled property for a particular edge or vertex,
+        subscript your graph with the descriptor of the edge or vertex
+        whose bundled property you wish to access. For instance:</p>
+    <pre>
+Map map; // load the map
+Map::vertex_descriptor v = *vertices(map).first;
+map[v].name = "Troy";
+map[v].population = 49170;
+map[v].zipcodes.push_back(12180);
+Map::edge_descriptor e = *out_edges(v, map).first;
+map[e].name = "I-87";
+map[e].miles = 10;
+map[e].speed_limit = 65;
+map[e].lanes = 4;
+map[e].divided = true;
+    </pre>
+
+    <h2>Properties maps from bundled properties</h2>
+    <p>Often one needs to create a property map from an internal
+      property for use in a generic algorithm. For instance, using the
+      graph without bundled properties we might invoke <a
+        href="dijkstra_shortest_paths.html">Dijkstra's shortest
+        paths</a> algorithm like this:</p>
+    <pre>
+vector&lt;double&gt; distances(num_vertices(map));
+dijkstra_shortest_paths(map, from,
+      weight_map(get(edge_length, map))
+      .distance_map(make_iterator_property_map(distances.begin(),
+                                               get(vertex_index, map))));
+    </pre>
+
+    <p>With bundled properties, we instead use the overloaded
+      <code>-&gt;*</code> operator, giving it a pointer to the member
+      data we wish to use for the property map. The equivalent example
+      using bundled properties is:</p>
+    <pre>
+vector&lt;double&gt; distances(num_vertices(map));
+dijkstra_shortest_paths(map, from,
+      weight_map(<font color="#ff0000">map-&gt;*&amp;Highway::miles</font>)
+      .distance_map(make_iterator_property_map(distances.begin(),
+                                               get(vertex_index, map))));
+    </pre>
+
+    <h2>Compatibility</h2> <p>Bundled properties will only work
+    properly on compilers that support class template partial
+    specialization.</p>
+
+    <hr>
+Copyright &copy; 2004 <a href="../../../people/doug_gregor.html">Doug Gregor</a>.
+    <address><a href="mailto:gregod@cs.rpi.edu"></a></address>
+<!-- Created: Fri May  7 09:59:21 EDT 2004 -->
+<!-- hhmts start -->
+Last modified: Fri May  7 10:56:01 EDT 2004
+<!-- hhmts end -->
+  </body>
+</html>
Index: libs/graph/test/Jamfile
===================================================================
RCS file: /cvsroot/boost/boost/libs/graph/test/Jamfile,v
retrieving revision 1.12
diff -b -u -r1.12 Jamfile
--- libs/graph/test/Jamfile	5 Feb 2004 20:48:30 -0000	1.12
+++ libs/graph/test/Jamfile	7 May 2004 14:57:35 -0000
@@ -51,6 +51,8 @@
     [ compile copy.cpp : <sysinclude>$(BOOST_ROOT) ]
     
     [ compile property_iter.cpp : <sysinclude>$(BOOST_ROOT) ]    
+
+    [ run bundled_properties.cpp ]
     ;
 
 # Run SDB tests only when -sSDB= is set.
Index: libs/graph/test/bundled_properties.cpp
===================================================================
RCS file: libs/graph/test/bundled_properties.cpp
diff -N libs/graph/test/bundled_properties.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libs/graph/test/bundled_properties.cpp	7 May 2004 14:57:35 -0000
@@ -0,0 +1,62 @@
+// Boost Graph library
+
+//  Copyright Doug Gregor 2004. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/minimal.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+struct City
+{
+  string name;
+  int population;
+  vector<int> zipcodes;
+};
+
+struct Highway
+{
+  string name;
+  double miles;
+  int speed_limit;
+  int lanes;
+  bool divided;
+};
+
+typedef boost::adjacency_list<
+    boost::listS, boost::vecS, boost::bidirectionalS,
+    City, Highway> Map;
+
+int test_main(int, char*[])
+{
+  Map map(2);
+
+  Map::vertex_iterator vi = vertices(map).first;
+  Map::vertex_descriptor v = *vi;
+  map[v].name = "Troy";
+  map[v].population = 49170;
+  map[v].zipcodes.push_back(12180);
+
+  ++vi;
+  Map::vertex_descriptor u = *vi;
+  map[u].name = "Albany";
+  map[u].population = 95658;
+  map[u].zipcodes.push_back(12201);
+
+  Map::edge_descriptor e = add_edge(v, u, map).first;
+  map[e].name = "I-87";
+  map[e].miles = 10;
+  map[e].speed_limit = 65;
+  map[e].lanes = 4;
+  map[e].divided = true;
+
+  BOOST_TEST(get(map->*&City::name, v) == "Troy");
+  BOOST_TEST(get(map->*&Highway::name, e) == "I-87");
+
+  return 0;
+}
Index: boost/pending/property.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/pending/property.hpp,v
retrieving revision 1.15
diff -b -u -r1.15 property.hpp
--- boost/pending/property.hpp	17 Feb 2003 07:58:00 -0000	1.15
+++ boost/pending/property.hpp	7 May 2004 14:57:36 -0000
@@ -88,6 +88,41 @@
     return Dispatcher::const_get_value(p, t2, tag2);
   }
 
+ namespace detail {
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+   template<typename FinalTag, typename FinalType>
+   struct retag_property_list
+   {
+     typedef property<FinalTag, FinalType> type;
+     typedef FinalType retagged;
+   };
+
+   template<typename FinalTag, typename Tag, typename T, typename Base>
+   struct retag_property_list<FinalTag, property<Tag, T, Base> >
+   {
+   private:
+     typedef retag_property_list<FinalTag, Base> next;
+
+   public:
+     typedef property<Tag, T, typename next::type> type;
+     typedef typename next::retagged retagged;
+   };
+
+   template<typename FinalTag>
+   struct retag_property_list<FinalTag, no_property>
+   {
+     typedef no_property type;
+     typedef no_property retagged;
+   };
+#else
+  template<typename FinalTag, typename Property>
+  struct retag_property_list
+  {
+    typedef Property property;
+    typedef no_property retagged;
+  };
+#endif
+  }
 } // namesapce boost
 
 #endif /* BOOST_PROPERTY_HPP */

