williamr@2
|
1 |
//=======================================================================
|
williamr@2
|
2 |
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
williamr@2
|
3 |
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
williamr@2
|
4 |
//
|
williamr@2
|
5 |
// Distributed under the Boost Software License, Version 1.0. (See
|
williamr@2
|
6 |
// accompanying file LICENSE_1_0.txt or copy at
|
williamr@2
|
7 |
// http://www.boost.org/LICENSE_1_0.txt)
|
williamr@2
|
8 |
//=======================================================================
|
williamr@2
|
9 |
#ifndef BOOST_GRAPH_PROPERTIES_HPP
|
williamr@2
|
10 |
#define BOOST_GRAPH_PROPERTIES_HPP
|
williamr@2
|
11 |
|
williamr@2
|
12 |
#include <boost/config.hpp>
|
williamr@2
|
13 |
#include <cassert>
|
williamr@2
|
14 |
#include <boost/pending/property.hpp>
|
williamr@2
|
15 |
#include <boost/property_map.hpp>
|
williamr@2
|
16 |
#include <boost/graph/graph_traits.hpp>
|
williamr@2
|
17 |
#include <boost/type_traits/is_convertible.hpp>
|
williamr@2
|
18 |
|
williamr@2
|
19 |
namespace boost {
|
williamr@2
|
20 |
|
williamr@2
|
21 |
enum default_color_type { white_color, gray_color, green_color, red_color, black_color };
|
williamr@2
|
22 |
|
williamr@2
|
23 |
template <class ColorValue>
|
williamr@2
|
24 |
struct color_traits {
|
williamr@2
|
25 |
static default_color_type white() { return white_color; }
|
williamr@2
|
26 |
static default_color_type gray() { return gray_color; }
|
williamr@2
|
27 |
static default_color_type green() { return green_color; }
|
williamr@2
|
28 |
static default_color_type red() { return red_color; }
|
williamr@2
|
29 |
static default_color_type black() { return black_color; }
|
williamr@2
|
30 |
};
|
williamr@2
|
31 |
|
williamr@2
|
32 |
// These functions are now obsolete, replaced by color_traits.
|
williamr@2
|
33 |
inline default_color_type white(default_color_type) { return white_color; }
|
williamr@2
|
34 |
inline default_color_type gray(default_color_type) { return gray_color; }
|
williamr@2
|
35 |
inline default_color_type green(default_color_type) { return green_color; }
|
williamr@2
|
36 |
inline default_color_type red(default_color_type) { return red_color; }
|
williamr@2
|
37 |
inline default_color_type black(default_color_type) { return black_color; }
|
williamr@2
|
38 |
|
williamr@2
|
39 |
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
williamr@2
|
40 |
template <>
|
williamr@2
|
41 |
struct property_traits<default_color_type*> {
|
williamr@2
|
42 |
typedef default_color_type value_type;
|
williamr@2
|
43 |
typedef std::ptrdiff_t key_type;
|
williamr@2
|
44 |
typedef default_color_type& reference;
|
williamr@2
|
45 |
typedef lvalue_property_map_tag category;
|
williamr@2
|
46 |
};
|
williamr@2
|
47 |
// get/put already defined for T*
|
williamr@2
|
48 |
#endif
|
williamr@2
|
49 |
|
williamr@2
|
50 |
struct graph_property_tag { };
|
williamr@2
|
51 |
struct vertex_property_tag { };
|
williamr@2
|
52 |
struct edge_property_tag { };
|
williamr@2
|
53 |
|
williamr@2
|
54 |
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
williamr@2
|
55 |
// See examples/edge_property.cpp for how to use this.
|
williamr@2
|
56 |
#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
|
williamr@2
|
57 |
template <> struct property_kind<KIND##_##NAME##_t> { \
|
williamr@2
|
58 |
typedef KIND##_property_tag type; \
|
williamr@2
|
59 |
}
|
williamr@2
|
60 |
#else
|
williamr@2
|
61 |
#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
|
williamr@2
|
62 |
template <> struct property_kind<KIND##_##NAME##_t> { \
|
williamr@2
|
63 |
typedef KIND##_property_tag type; \
|
williamr@2
|
64 |
}
|
williamr@2
|
65 |
#endif
|
williamr@2
|
66 |
|
williamr@2
|
67 |
#define BOOST_DEF_PROPERTY(KIND, NAME) \
|
williamr@2
|
68 |
enum KIND##_##NAME##_t { KIND##_##NAME }; \
|
williamr@2
|
69 |
BOOST_INSTALL_PROPERTY(KIND, NAME)
|
williamr@2
|
70 |
|
williamr@2
|
71 |
BOOST_DEF_PROPERTY(vertex, all);
|
williamr@2
|
72 |
BOOST_DEF_PROPERTY(edge, all);
|
williamr@2
|
73 |
BOOST_DEF_PROPERTY(graph, all);
|
williamr@2
|
74 |
BOOST_DEF_PROPERTY(vertex, index);
|
williamr@2
|
75 |
BOOST_DEF_PROPERTY(vertex, index1);
|
williamr@2
|
76 |
BOOST_DEF_PROPERTY(vertex, index2);
|
williamr@2
|
77 |
BOOST_DEF_PROPERTY(vertex, root);
|
williamr@2
|
78 |
BOOST_DEF_PROPERTY(edge, index);
|
williamr@2
|
79 |
BOOST_DEF_PROPERTY(edge, name);
|
williamr@2
|
80 |
BOOST_DEF_PROPERTY(edge, weight);
|
williamr@2
|
81 |
BOOST_DEF_PROPERTY(edge, weight2);
|
williamr@2
|
82 |
BOOST_DEF_PROPERTY(edge, color);
|
williamr@2
|
83 |
BOOST_DEF_PROPERTY(vertex, name);
|
williamr@2
|
84 |
BOOST_DEF_PROPERTY(graph, name);
|
williamr@2
|
85 |
BOOST_DEF_PROPERTY(vertex, distance);
|
williamr@2
|
86 |
BOOST_DEF_PROPERTY(vertex, color);
|
williamr@2
|
87 |
BOOST_DEF_PROPERTY(vertex, degree);
|
williamr@2
|
88 |
BOOST_DEF_PROPERTY(vertex, in_degree);
|
williamr@2
|
89 |
BOOST_DEF_PROPERTY(vertex, out_degree);
|
williamr@2
|
90 |
BOOST_DEF_PROPERTY(vertex, current_degree);
|
williamr@2
|
91 |
BOOST_DEF_PROPERTY(vertex, priority);
|
williamr@2
|
92 |
BOOST_DEF_PROPERTY(vertex, discover_time);
|
williamr@2
|
93 |
BOOST_DEF_PROPERTY(vertex, finish_time);
|
williamr@2
|
94 |
BOOST_DEF_PROPERTY(vertex, predecessor);
|
williamr@2
|
95 |
BOOST_DEF_PROPERTY(vertex, rank);
|
williamr@2
|
96 |
BOOST_DEF_PROPERTY(vertex, centrality);
|
williamr@2
|
97 |
BOOST_DEF_PROPERTY(vertex, lowpoint);
|
williamr@2
|
98 |
BOOST_DEF_PROPERTY(edge, reverse);
|
williamr@2
|
99 |
BOOST_DEF_PROPERTY(edge, capacity);
|
williamr@2
|
100 |
BOOST_DEF_PROPERTY(edge, residual_capacity);
|
williamr@2
|
101 |
BOOST_DEF_PROPERTY(edge, centrality);
|
williamr@2
|
102 |
BOOST_DEF_PROPERTY(graph, visitor);
|
williamr@2
|
103 |
|
williamr@2
|
104 |
// These tags are used for property bundles
|
williamr@2
|
105 |
BOOST_DEF_PROPERTY(vertex, bundle);
|
williamr@2
|
106 |
BOOST_DEF_PROPERTY(edge, bundle);
|
williamr@2
|
107 |
|
williamr@2
|
108 |
#undef BOOST_DEF_PROPERTY
|
williamr@2
|
109 |
|
williamr@2
|
110 |
namespace detail {
|
williamr@2
|
111 |
|
williamr@2
|
112 |
struct dummy_edge_property_selector {
|
williamr@2
|
113 |
template <class Graph, class Property, class Tag>
|
williamr@2
|
114 |
struct bind_ {
|
williamr@2
|
115 |
typedef identity_property_map type;
|
williamr@2
|
116 |
typedef identity_property_map const_type;
|
williamr@2
|
117 |
};
|
williamr@2
|
118 |
};
|
williamr@2
|
119 |
struct dummy_vertex_property_selector {
|
williamr@2
|
120 |
template <class Graph, class Property, class Tag>
|
williamr@2
|
121 |
struct bind_ {
|
williamr@2
|
122 |
typedef identity_property_map type;
|
williamr@2
|
123 |
typedef identity_property_map const_type;
|
williamr@2
|
124 |
};
|
williamr@2
|
125 |
};
|
williamr@2
|
126 |
|
williamr@2
|
127 |
} // namespace detail
|
williamr@2
|
128 |
|
williamr@2
|
129 |
// Graph classes can either partially specialize property_map
|
williamr@2
|
130 |
// or they can specialize these two selector classes.
|
williamr@2
|
131 |
template <class GraphTag>
|
williamr@2
|
132 |
struct edge_property_selector {
|
williamr@2
|
133 |
typedef detail::dummy_edge_property_selector type;
|
williamr@2
|
134 |
};
|
williamr@2
|
135 |
|
williamr@2
|
136 |
template <class GraphTag>
|
williamr@2
|
137 |
struct vertex_property_selector {
|
williamr@2
|
138 |
typedef detail::dummy_vertex_property_selector type;
|
williamr@2
|
139 |
};
|
williamr@2
|
140 |
|
williamr@2
|
141 |
namespace detail {
|
williamr@2
|
142 |
|
williamr@2
|
143 |
template <class Graph, class PropertyTag>
|
williamr@2
|
144 |
struct edge_property_map {
|
williamr@2
|
145 |
typedef typename Graph::edge_property_type Property;
|
williamr@2
|
146 |
typedef typename Graph::graph_tag graph_tag;
|
williamr@2
|
147 |
typedef typename edge_property_selector<graph_tag>::type Selector;
|
williamr@2
|
148 |
typedef typename Selector::template bind_<Graph,Property,PropertyTag>
|
williamr@2
|
149 |
Bind;
|
williamr@2
|
150 |
typedef typename Bind::type type;
|
williamr@2
|
151 |
typedef typename Bind::const_type const_type;
|
williamr@2
|
152 |
};
|
williamr@2
|
153 |
template <class Graph, class PropertyTag>
|
williamr@2
|
154 |
class vertex_property_map {
|
williamr@2
|
155 |
typedef typename Graph::vertex_property_type Property;
|
williamr@2
|
156 |
typedef typename Graph::graph_tag graph_tag;
|
williamr@2
|
157 |
typedef typename vertex_property_selector<graph_tag>::type Selector;
|
williamr@2
|
158 |
typedef typename Selector::template bind_<Graph,Property,PropertyTag>
|
williamr@2
|
159 |
Bind;
|
williamr@2
|
160 |
public:
|
williamr@2
|
161 |
typedef typename Bind::type type;
|
williamr@2
|
162 |
typedef typename Bind::const_type const_type;
|
williamr@2
|
163 |
};
|
williamr@2
|
164 |
|
williamr@2
|
165 |
// This selects the kind of property map, whether is maps from
|
williamr@2
|
166 |
// edges or from vertices.
|
williamr@2
|
167 |
//
|
williamr@2
|
168 |
// It is overly complicated because it's a workaround for
|
williamr@2
|
169 |
// partial specialization.
|
williamr@2
|
170 |
struct choose_vertex_property_map {
|
williamr@2
|
171 |
template <class Graph, class Property>
|
williamr@2
|
172 |
struct bind_ {
|
williamr@2
|
173 |
typedef vertex_property_map<Graph, Property> type;
|
williamr@2
|
174 |
};
|
williamr@2
|
175 |
};
|
williamr@2
|
176 |
struct choose_edge_property_map {
|
williamr@2
|
177 |
template <class Graph, class Property>
|
williamr@2
|
178 |
struct bind_ {
|
williamr@2
|
179 |
typedef edge_property_map<Graph, Property> type;
|
williamr@2
|
180 |
};
|
williamr@2
|
181 |
};
|
williamr@2
|
182 |
template <class Kind>
|
williamr@2
|
183 |
struct property_map_kind_selector {
|
williamr@2
|
184 |
// VC++ gets confused if this isn't defined, even though
|
williamr@2
|
185 |
// this never gets used.
|
williamr@2
|
186 |
typedef choose_vertex_property_map type;
|
williamr@2
|
187 |
};
|
williamr@2
|
188 |
template <> struct property_map_kind_selector<vertex_property_tag> {
|
williamr@2
|
189 |
typedef choose_vertex_property_map type;
|
williamr@2
|
190 |
};
|
williamr@2
|
191 |
template <> struct property_map_kind_selector<edge_property_tag> {
|
williamr@2
|
192 |
typedef choose_edge_property_map type;
|
williamr@2
|
193 |
};
|
williamr@2
|
194 |
} // namespace detail
|
williamr@2
|
195 |
|
williamr@2
|
196 |
template <class Graph, class Property>
|
williamr@2
|
197 |
struct property_map {
|
williamr@2
|
198 |
private:
|
williamr@2
|
199 |
typedef typename property_kind<Property>::type Kind;
|
williamr@2
|
200 |
typedef typename detail::property_map_kind_selector<Kind>::type Selector;
|
williamr@2
|
201 |
typedef typename Selector::template bind_<Graph, Property> Bind;
|
williamr@2
|
202 |
typedef typename Bind::type Map;
|
williamr@2
|
203 |
public:
|
williamr@2
|
204 |
typedef typename Map::type type;
|
williamr@2
|
205 |
typedef typename Map::const_type const_type;
|
williamr@2
|
206 |
};
|
williamr@2
|
207 |
|
williamr@2
|
208 |
// shortcut for accessing the value type of the property map
|
williamr@2
|
209 |
template <class Graph, class Property>
|
williamr@2
|
210 |
class property_map_value {
|
williamr@2
|
211 |
typedef typename property_map<Graph, Property>::const_type PMap;
|
williamr@2
|
212 |
public:
|
williamr@2
|
213 |
typedef typename property_traits<PMap>::value_type type;
|
williamr@2
|
214 |
};
|
williamr@2
|
215 |
|
williamr@2
|
216 |
template <class Graph, class Property>
|
williamr@2
|
217 |
class graph_property {
|
williamr@2
|
218 |
public:
|
williamr@2
|
219 |
typedef typename property_value<typename Graph::graph_property_type,
|
williamr@2
|
220 |
Property>::type type;
|
williamr@2
|
221 |
};
|
williamr@2
|
222 |
|
williamr@2
|
223 |
template <class Graph>
|
williamr@2
|
224 |
class vertex_property {
|
williamr@2
|
225 |
public:
|
williamr@2
|
226 |
typedef typename Graph::vertex_property_type type;
|
williamr@2
|
227 |
};
|
williamr@2
|
228 |
template <class Graph>
|
williamr@2
|
229 |
class edge_property {
|
williamr@2
|
230 |
public:
|
williamr@2
|
231 |
typedef typename Graph::edge_property_type type;
|
williamr@2
|
232 |
};
|
williamr@2
|
233 |
|
williamr@2
|
234 |
template <typename Graph>
|
williamr@2
|
235 |
class degree_property_map
|
williamr@2
|
236 |
: public put_get_helper<typename graph_traits<Graph>::degree_size_type,
|
williamr@2
|
237 |
degree_property_map<Graph> >
|
williamr@2
|
238 |
{
|
williamr@2
|
239 |
public:
|
williamr@2
|
240 |
typedef typename graph_traits<Graph>::vertex_descriptor key_type;
|
williamr@2
|
241 |
typedef typename graph_traits<Graph>::degree_size_type value_type;
|
williamr@2
|
242 |
typedef value_type reference;
|
williamr@2
|
243 |
typedef readable_property_map_tag category;
|
williamr@2
|
244 |
degree_property_map(const Graph& g) : m_g(g) { }
|
williamr@2
|
245 |
value_type operator[](const key_type& v) const {
|
williamr@2
|
246 |
return degree(v, m_g);
|
williamr@2
|
247 |
}
|
williamr@2
|
248 |
private:
|
williamr@2
|
249 |
const Graph& m_g;
|
williamr@2
|
250 |
};
|
williamr@2
|
251 |
template <typename Graph>
|
williamr@2
|
252 |
inline degree_property_map<Graph>
|
williamr@2
|
253 |
make_degree_map(const Graph& g) {
|
williamr@2
|
254 |
return degree_property_map<Graph>(g);
|
williamr@2
|
255 |
}
|
williamr@2
|
256 |
|
williamr@2
|
257 |
//========================================================================
|
williamr@2
|
258 |
// Iterator Property Map Generating Functions contributed by
|
williamr@2
|
259 |
// Kevin Vanhorn. (see also the property map generating functions
|
williamr@2
|
260 |
// in boost/property_map.hpp)
|
williamr@2
|
261 |
|
williamr@2
|
262 |
#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
williamr@2
|
263 |
// A helper function for creating a vertex property map out of a
|
williamr@2
|
264 |
// random access iterator and the internal vertex index map from a
|
williamr@2
|
265 |
// graph.
|
williamr@2
|
266 |
template <class PropertyGraph, class RandomAccessIterator>
|
williamr@2
|
267 |
inline
|
williamr@2
|
268 |
iterator_property_map<
|
williamr@2
|
269 |
RandomAccessIterator,
|
williamr@2
|
270 |
typename property_map<PropertyGraph, vertex_index_t>::type,
|
williamr@2
|
271 |
typename std::iterator_traits<RandomAccessIterator>::value_type,
|
williamr@2
|
272 |
typename std::iterator_traits<RandomAccessIterator>::reference
|
williamr@2
|
273 |
>
|
williamr@2
|
274 |
make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
|
williamr@2
|
275 |
{
|
williamr@2
|
276 |
return make_iterator_property_map(iter, get(vertex_index, g));
|
williamr@2
|
277 |
}
|
williamr@2
|
278 |
|
williamr@2
|
279 |
// Use this next function when vertex_descriptor is known to be an
|
williamr@2
|
280 |
// integer type, with values ranging from 0 to num_vertices(g).
|
williamr@2
|
281 |
//
|
williamr@2
|
282 |
template <class RandomAccessIterator>
|
williamr@2
|
283 |
inline
|
williamr@2
|
284 |
iterator_property_map<
|
williamr@2
|
285 |
RandomAccessIterator,
|
williamr@2
|
286 |
identity_property_map,
|
williamr@2
|
287 |
typename std::iterator_traits<RandomAccessIterator>::value_type,
|
williamr@2
|
288 |
typename std::iterator_traits<RandomAccessIterator>::reference
|
williamr@2
|
289 |
>
|
williamr@2
|
290 |
make_iterator_vertex_map(RandomAccessIterator iter)
|
williamr@2
|
291 |
{
|
williamr@2
|
292 |
return make_iterator_property_map(iter, identity_property_map());
|
williamr@2
|
293 |
}
|
williamr@2
|
294 |
#endif
|
williamr@2
|
295 |
|
williamr@2
|
296 |
template <class PropertyGraph, class RandomAccessContainer>
|
williamr@2
|
297 |
inline
|
williamr@2
|
298 |
iterator_property_map<
|
williamr@2
|
299 |
typename RandomAccessContainer::iterator,
|
williamr@2
|
300 |
typename property_map<PropertyGraph, vertex_index_t>::type,
|
williamr@2
|
301 |
typename RandomAccessContainer::value_type,
|
williamr@2
|
302 |
typename RandomAccessContainer::reference
|
williamr@2
|
303 |
>
|
williamr@2
|
304 |
make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
|
williamr@2
|
305 |
{
|
williamr@2
|
306 |
assert(c.size() >= num_vertices(g));
|
williamr@2
|
307 |
return make_iterator_vertex_map(c.begin(), g);
|
williamr@2
|
308 |
}
|
williamr@2
|
309 |
|
williamr@2
|
310 |
template <class RandomAccessContainer> inline
|
williamr@2
|
311 |
iterator_property_map<
|
williamr@2
|
312 |
typename RandomAccessContainer::iterator,
|
williamr@2
|
313 |
identity_property_map,
|
williamr@2
|
314 |
typename RandomAccessContainer::value_type,
|
williamr@2
|
315 |
typename RandomAccessContainer::reference
|
williamr@2
|
316 |
>
|
williamr@2
|
317 |
make_container_vertex_map(RandomAccessContainer& c)
|
williamr@2
|
318 |
{
|
williamr@2
|
319 |
return make_iterator_vertex_map(c.begin());
|
williamr@2
|
320 |
}
|
williamr@2
|
321 |
|
williamr@2
|
322 |
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
williamr@2
|
323 |
# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
williamr@2
|
324 |
#endif
|
williamr@2
|
325 |
|
williamr@2
|
326 |
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
williamr@2
|
327 |
template<typename Graph, typename Descriptor, typename Bundle, typename T>
|
williamr@2
|
328 |
struct bundle_property_map
|
williamr@2
|
329 |
: put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
|
williamr@2
|
330 |
{
|
williamr@2
|
331 |
typedef Descriptor key_type;
|
williamr@2
|
332 |
typedef T value_type;
|
williamr@2
|
333 |
typedef T& reference;
|
williamr@2
|
334 |
typedef lvalue_property_map_tag category;
|
williamr@2
|
335 |
|
williamr@2
|
336 |
bundle_property_map() { }
|
williamr@2
|
337 |
bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {}
|
williamr@2
|
338 |
|
williamr@2
|
339 |
reference operator[](key_type k) const { return (*g)[k].*pm; }
|
williamr@2
|
340 |
private:
|
williamr@2
|
341 |
Graph* g;
|
williamr@2
|
342 |
T Bundle::* pm;
|
williamr@2
|
343 |
};
|
williamr@2
|
344 |
|
williamr@2
|
345 |
namespace detail {
|
williamr@2
|
346 |
template<typename VertexBundle, typename EdgeBundle, typename Bundle>
|
williamr@2
|
347 |
struct is_vertex_bundle : is_convertible<VertexBundle*, Bundle*> {};
|
williamr@2
|
348 |
}
|
williamr@2
|
349 |
|
williamr@2
|
350 |
template <typename Graph, typename T, typename Bundle>
|
williamr@2
|
351 |
struct property_map<Graph, T Bundle::*>
|
williamr@2
|
352 |
{
|
williamr@2
|
353 |
private:
|
williamr@2
|
354 |
typedef graph_traits<Graph> traits;
|
williamr@2
|
355 |
typedef typename Graph::vertex_bundled vertex_bundled;
|
williamr@2
|
356 |
typedef typename Graph::edge_bundled edge_bundled;
|
williamr@2
|
357 |
typedef typename ct_if<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
|
williamr@2
|
358 |
typename traits::vertex_descriptor,
|
williamr@2
|
359 |
typename traits::edge_descriptor>::type
|
williamr@2
|
360 |
descriptor;
|
williamr@2
|
361 |
typedef typename ct_if<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
|
williamr@2
|
362 |
vertex_bundled,
|
williamr@2
|
363 |
edge_bundled>::type
|
williamr@2
|
364 |
actual_bundle;
|
williamr@2
|
365 |
|
williamr@2
|
366 |
public:
|
williamr@2
|
367 |
typedef bundle_property_map<Graph, descriptor, actual_bundle, T> type;
|
williamr@2
|
368 |
typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T>
|
williamr@2
|
369 |
const_type;
|
williamr@2
|
370 |
};
|
williamr@2
|
371 |
#endif
|
williamr@2
|
372 |
|
williamr@2
|
373 |
} // namespace boost
|
williamr@2
|
374 |
|
williamr@2
|
375 |
#endif /* BOOST_GRAPH_PROPERTIES_HPPA */
|