/Src/Dependencies/Boost/boost/graph/properties.hpp

http://hadesmem.googlecode.com/ · C++ Header · 512 lines · 399 code · 59 blank · 54 comment · 1 complexity · 2d1e8c25b7cdc92ca22722aad3b89a71 MD5 · raw file

  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef BOOST_GRAPH_PROPERTIES_HPP
  10. #define BOOST_GRAPH_PROPERTIES_HPP
  11. #include <boost/config.hpp>
  12. #include <boost/assert.hpp>
  13. #include <boost/pending/property.hpp>
  14. #include <boost/detail/workaround.hpp>
  15. // Include the property map library and extensions in the BGL.
  16. #include <boost/property_map/property_map.hpp>
  17. #include <boost/graph/property_maps/constant_property_map.hpp>
  18. #include <boost/graph/property_maps/null_property_map.hpp>
  19. #include <boost/graph/graph_traits.hpp>
  20. #include <boost/type_traits/is_convertible.hpp>
  21. #include <boost/limits.hpp>
  22. #include <boost/mpl/and.hpp>
  23. #include <boost/mpl/not.hpp>
  24. #include <boost/mpl/if.hpp>
  25. #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  26. // Stay out of the way of the concept checking class
  27. # define Graph Graph_
  28. # define RandomAccessContainer RandomAccessContainer_
  29. #endif
  30. namespace boost {
  31. enum default_color_type { white_color, gray_color, green_color, red_color, black_color };
  32. template <class ColorValue>
  33. struct color_traits {
  34. static default_color_type white() { return white_color; }
  35. static default_color_type gray() { return gray_color; }
  36. static default_color_type green() { return green_color; }
  37. static default_color_type red() { return red_color; }
  38. static default_color_type black() { return black_color; }
  39. };
  40. // These functions are now obsolete, replaced by color_traits.
  41. inline default_color_type white(default_color_type) { return white_color; }
  42. inline default_color_type gray(default_color_type) { return gray_color; }
  43. inline default_color_type green(default_color_type) { return green_color; }
  44. inline default_color_type red(default_color_type) { return red_color; }
  45. inline default_color_type black(default_color_type) { return black_color; }
  46. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  47. template <>
  48. struct property_traits<default_color_type*> {
  49. typedef default_color_type value_type;
  50. typedef std::ptrdiff_t key_type;
  51. typedef default_color_type& reference;
  52. typedef lvalue_property_map_tag category;
  53. };
  54. // get/put already defined for T*
  55. #endif
  56. struct graph_property_tag { };
  57. struct vertex_property_tag { };
  58. struct edge_property_tag { };
  59. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  60. // See examples/edge_property.cpp for how to use this.
  61. #define BOOST_INSTALL_PROPERTY(KIND, NAME) \
  62. template <> struct property_kind<KIND##_##NAME##_t> { \
  63. typedef KIND##_property_tag type; \
  64. }
  65. #else
  66. #define BOOST_INSTALL_PROPERTY(KIND, NAME) \
  67. template <> struct property_kind<KIND##_##NAME##_t> { \
  68. typedef KIND##_property_tag type; \
  69. }
  70. #endif
  71. #define BOOST_DEF_PROPERTY(KIND, NAME) \
  72. enum KIND##_##NAME##_t { KIND##_##NAME }; \
  73. BOOST_INSTALL_PROPERTY(KIND, NAME)
  74. BOOST_DEF_PROPERTY(vertex, all);
  75. BOOST_DEF_PROPERTY(edge, all);
  76. BOOST_DEF_PROPERTY(graph, all);
  77. BOOST_DEF_PROPERTY(vertex, index);
  78. BOOST_DEF_PROPERTY(vertex, index1);
  79. BOOST_DEF_PROPERTY(vertex, index2);
  80. BOOST_DEF_PROPERTY(vertex, root);
  81. BOOST_DEF_PROPERTY(edge, index);
  82. BOOST_DEF_PROPERTY(edge, name);
  83. BOOST_DEF_PROPERTY(edge, weight);
  84. BOOST_DEF_PROPERTY(edge, weight2);
  85. BOOST_DEF_PROPERTY(edge, color);
  86. BOOST_DEF_PROPERTY(vertex, name);
  87. BOOST_DEF_PROPERTY(graph, name);
  88. BOOST_DEF_PROPERTY(vertex, distance);
  89. BOOST_DEF_PROPERTY(vertex, distance2);
  90. BOOST_DEF_PROPERTY(vertex, color);
  91. BOOST_DEF_PROPERTY(vertex, degree);
  92. BOOST_DEF_PROPERTY(vertex, in_degree);
  93. BOOST_DEF_PROPERTY(vertex, out_degree);
  94. BOOST_DEF_PROPERTY(vertex, current_degree);
  95. BOOST_DEF_PROPERTY(vertex, priority);
  96. BOOST_DEF_PROPERTY(vertex, discover_time);
  97. BOOST_DEF_PROPERTY(vertex, finish_time);
  98. BOOST_DEF_PROPERTY(vertex, predecessor);
  99. BOOST_DEF_PROPERTY(vertex, rank);
  100. BOOST_DEF_PROPERTY(vertex, centrality);
  101. BOOST_DEF_PROPERTY(vertex, lowpoint);
  102. BOOST_DEF_PROPERTY(vertex, potential);
  103. BOOST_DEF_PROPERTY(vertex, update);
  104. BOOST_DEF_PROPERTY(edge, reverse);
  105. BOOST_DEF_PROPERTY(edge, capacity);
  106. BOOST_DEF_PROPERTY(edge, flow);
  107. BOOST_DEF_PROPERTY(edge, residual_capacity);
  108. BOOST_DEF_PROPERTY(edge, centrality);
  109. BOOST_DEF_PROPERTY(edge, discover_time);
  110. BOOST_DEF_PROPERTY(edge, update);
  111. BOOST_DEF_PROPERTY(edge, finished);
  112. BOOST_DEF_PROPERTY(graph, visitor);
  113. // These tags are used for property bundles
  114. // BOOST_DEF_PROPERTY(graph, bundle); -- needed in graph_traits.hpp, so enum is defined there
  115. BOOST_INSTALL_PROPERTY(graph, bundle);
  116. BOOST_DEF_PROPERTY(vertex, bundle);
  117. BOOST_DEF_PROPERTY(edge, bundle);
  118. // These tags are used to denote the owners and local descriptors
  119. // for the vertices and edges of a distributed graph.
  120. BOOST_DEF_PROPERTY(vertex, global);
  121. BOOST_DEF_PROPERTY(vertex, owner);
  122. BOOST_DEF_PROPERTY(vertex, local);
  123. BOOST_DEF_PROPERTY(edge, global);
  124. BOOST_DEF_PROPERTY(edge, owner);
  125. BOOST_DEF_PROPERTY(edge, local);
  126. BOOST_DEF_PROPERTY(vertex, local_index);
  127. BOOST_DEF_PROPERTY(edge, local_index);
  128. #undef BOOST_DEF_PROPERTY
  129. namespace detail {
  130. struct dummy_edge_property_selector {
  131. template <class Graph, class Property, class Tag>
  132. struct bind_ {
  133. typedef identity_property_map type;
  134. typedef identity_property_map const_type;
  135. };
  136. };
  137. struct dummy_vertex_property_selector {
  138. template <class Graph, class Property, class Tag>
  139. struct bind_ {
  140. typedef identity_property_map type;
  141. typedef identity_property_map const_type;
  142. };
  143. };
  144. } // namespace detail
  145. // Graph classes can either partially specialize property_map
  146. // or they can specialize these two selector classes.
  147. template <class GraphTag>
  148. struct edge_property_selector {
  149. typedef detail::dummy_edge_property_selector type;
  150. };
  151. template <class GraphTag>
  152. struct vertex_property_selector {
  153. typedef detail::dummy_vertex_property_selector type;
  154. };
  155. namespace detail {
  156. template <typename A> struct return_void {typedef void type;};
  157. template <typename Graph, typename Enable = void>
  158. struct graph_tag_or_void {
  159. typedef void type;
  160. };
  161. template <typename Graph>
  162. struct graph_tag_or_void<Graph, typename return_void<typename Graph::graph_tag>::type> {
  163. typedef typename Graph::graph_tag type;
  164. };
  165. template <class Graph, class PropertyTag>
  166. struct edge_property_map {
  167. typedef typename edge_property_type<Graph>::type Property;
  168. typedef typename graph_tag_or_void<Graph>::type graph_tag;
  169. typedef typename edge_property_selector<graph_tag>::type Selector;
  170. typedef typename Selector::template bind_<Graph,Property,PropertyTag>
  171. Bind;
  172. typedef typename Bind::type type;
  173. typedef typename Bind::const_type const_type;
  174. };
  175. template <class Graph, class PropertyTag>
  176. class vertex_property_map {
  177. public:
  178. typedef typename vertex_property_type<Graph>::type Property;
  179. typedef typename graph_tag_or_void<Graph>::type graph_tag;
  180. typedef typename vertex_property_selector<graph_tag>::type Selector;
  181. typedef typename Selector::template bind_<Graph,Property,PropertyTag>
  182. Bind;
  183. public:
  184. typedef typename Bind::type type;
  185. typedef typename Bind::const_type const_type;
  186. };
  187. // This selects the kind of property map, whether is maps from
  188. // edges or from vertices.
  189. //
  190. // It is overly complicated because it's a workaround for
  191. // partial specialization.
  192. struct choose_vertex_property_map {
  193. template <class Graph, class Property>
  194. struct bind_ {
  195. typedef vertex_property_map<Graph, Property> type;
  196. };
  197. };
  198. struct choose_edge_property_map {
  199. template <class Graph, class Property>
  200. struct bind_ {
  201. typedef edge_property_map<Graph, Property> type;
  202. };
  203. };
  204. template <class Kind>
  205. struct property_map_kind_selector {
  206. // VC++ gets confused if this isn't defined, even though
  207. // this never gets used.
  208. typedef choose_vertex_property_map type;
  209. };
  210. template <> struct property_map_kind_selector<vertex_property_tag> {
  211. typedef choose_vertex_property_map type;
  212. };
  213. template <> struct property_map_kind_selector<edge_property_tag> {
  214. typedef choose_edge_property_map type;
  215. };
  216. } // namespace detail
  217. template <class Graph, class Property>
  218. struct property_map {
  219. // private:
  220. typedef typename property_kind<Property>::type Kind;
  221. typedef typename detail::property_map_kind_selector<Kind>::type Selector;
  222. typedef typename Selector::template bind_<Graph, Property> Bind;
  223. typedef typename Bind::type Map;
  224. public:
  225. typedef typename Map::type type;
  226. typedef typename Map::const_type const_type;
  227. };
  228. // shortcut for accessing the value type of the property map
  229. template <class Graph, class Property>
  230. class property_map_value {
  231. typedef typename property_map<Graph, Property>::const_type PMap;
  232. public:
  233. typedef typename property_traits<PMap>::value_type type;
  234. };
  235. template <class Graph, class Property>
  236. class graph_property {
  237. public:
  238. typedef typename property_value<
  239. typename boost::graph_property_type<Graph>::type, Property
  240. >::type type;
  241. };
  242. template <class Graph>
  243. class vertex_property {
  244. public:
  245. typedef typename Graph::vertex_property_type type;
  246. };
  247. template <class Graph>
  248. class edge_property {
  249. public:
  250. typedef typename Graph::edge_property_type type;
  251. };
  252. template <typename Graph>
  253. class degree_property_map
  254. : public put_get_helper<typename graph_traits<Graph>::degree_size_type,
  255. degree_property_map<Graph> >
  256. {
  257. public:
  258. typedef typename graph_traits<Graph>::vertex_descriptor key_type;
  259. typedef typename graph_traits<Graph>::degree_size_type value_type;
  260. typedef value_type reference;
  261. typedef readable_property_map_tag category;
  262. degree_property_map(const Graph& g) : m_g(g) { }
  263. value_type operator[](const key_type& v) const {
  264. return degree(v, m_g);
  265. }
  266. private:
  267. const Graph& m_g;
  268. };
  269. template <typename Graph>
  270. inline degree_property_map<Graph>
  271. make_degree_map(const Graph& g) {
  272. return degree_property_map<Graph>(g);
  273. }
  274. //========================================================================
  275. // Iterator Property Map Generating Functions contributed by
  276. // Kevin Vanhorn. (see also the property map generating functions
  277. // in boost/property_map/property_map.hpp)
  278. #if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
  279. // A helper function for creating a vertex property map out of a
  280. // random access iterator and the internal vertex index map from a
  281. // graph.
  282. template <class PropertyGraph, class RandomAccessIterator>
  283. inline
  284. iterator_property_map<
  285. RandomAccessIterator,
  286. typename property_map<PropertyGraph, vertex_index_t>::type,
  287. typename std::iterator_traits<RandomAccessIterator>::value_type,
  288. typename std::iterator_traits<RandomAccessIterator>::reference
  289. >
  290. make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
  291. {
  292. return make_iterator_property_map(iter, get(vertex_index, g));
  293. }
  294. // Use this next function when vertex_descriptor is known to be an
  295. // integer type, with values ranging from 0 to num_vertices(g).
  296. //
  297. template <class RandomAccessIterator>
  298. inline
  299. iterator_property_map<
  300. RandomAccessIterator,
  301. identity_property_map,
  302. typename std::iterator_traits<RandomAccessIterator>::value_type,
  303. typename std::iterator_traits<RandomAccessIterator>::reference
  304. >
  305. make_iterator_vertex_map(RandomAccessIterator iter)
  306. {
  307. return make_iterator_property_map(iter, identity_property_map());
  308. }
  309. #endif
  310. template <class PropertyGraph, class RandomAccessContainer>
  311. inline
  312. iterator_property_map<
  313. typename RandomAccessContainer::iterator,
  314. typename property_map<PropertyGraph, vertex_index_t>::type,
  315. typename RandomAccessContainer::value_type,
  316. typename RandomAccessContainer::reference
  317. >
  318. make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
  319. {
  320. BOOST_ASSERT(c.size() >= num_vertices(g));
  321. return make_iterator_vertex_map(c.begin(), g);
  322. }
  323. template <class RandomAccessContainer> inline
  324. iterator_property_map<
  325. typename RandomAccessContainer::iterator,
  326. identity_property_map,
  327. typename RandomAccessContainer::value_type,
  328. typename RandomAccessContainer::reference
  329. >
  330. make_container_vertex_map(RandomAccessContainer& c)
  331. {
  332. return make_iterator_vertex_map(c.begin());
  333. }
  334. #if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  335. # define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  336. #endif
  337. #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) && !defined (BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
  338. // This compiler cannot define a partial specialization based on a
  339. // pointer-to-member type, as seen in boost/graph/subgraph.hpp line 985 (as of
  340. // trunk r53912)
  341. # define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  342. #endif
  343. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  344. template<typename Graph, typename Descriptor, typename Bundle, typename T>
  345. struct bundle_property_map
  346. : put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
  347. {
  348. typedef Descriptor key_type;
  349. typedef typename remove_const<T>::type value_type;
  350. typedef T& reference;
  351. typedef lvalue_property_map_tag category;
  352. bundle_property_map() { }
  353. bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {}
  354. reference operator[](key_type k) const { return (*g)[k].*pm; }
  355. private:
  356. Graph* g;
  357. T Bundle::* pm;
  358. };
  359. namespace detail {
  360. template<typename VertexBundle, typename EdgeBundle, typename Bundle>
  361. struct is_vertex_bundle
  362. : mpl::and_<is_convertible<VertexBundle*, Bundle*>,
  363. mpl::and_<mpl::not_<is_void<VertexBundle> >,
  364. mpl::not_<is_same<VertexBundle, no_property> > > >
  365. { };
  366. }
  367. // Specialize the property map template to generate bundled property maps.
  368. template <typename Graph, typename T, typename Bundle>
  369. struct property_map<Graph, T Bundle::*>
  370. {
  371. private:
  372. typedef graph_traits<Graph> traits;
  373. typedef typename Graph::vertex_bundled vertex_bundled;
  374. typedef typename Graph::edge_bundled edge_bundled;
  375. typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
  376. typename traits::vertex_descriptor,
  377. typename traits::edge_descriptor>::type
  378. descriptor;
  379. typedef typename mpl::if_c<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
  380. vertex_bundled,
  381. edge_bundled>::type
  382. actual_bundle;
  383. public:
  384. typedef bundle_property_map<Graph, descriptor, actual_bundle, T> type;
  385. typedef bundle_property_map<const Graph, descriptor, actual_bundle, const T>
  386. const_type;
  387. };
  388. #endif
  389. // These metafunctions help implement the process of determining the vertex
  390. // and edge properties of a graph.
  391. namespace graph_detail {
  392. template<typename Retag>
  393. struct retagged_property {
  394. typedef typename Retag::type type;
  395. };
  396. // Search the normalized PropList (as returned by retagged<>::type) for
  397. // the given bundle. Return the type error if no such bundle can be found.
  398. template <typename PropList, typename Bundle>
  399. struct retagged_bundle {
  400. typedef typename property_value<PropList, Bundle>::type Value;
  401. typedef typename mpl::if_<
  402. is_same<Value, detail::error_property_not_found>, no_bundle, Value
  403. >::type type;
  404. };
  405. template<typename Prop, typename Bundle>
  406. class normal_property {
  407. // Normalize the property into a property list.
  408. typedef detail::retag_property_list<Bundle, Prop> List;
  409. public:
  410. // Extract the normalized property and bundle types.
  411. typedef typename retagged_property<List>::type property;
  412. typedef typename retagged_bundle<property, Bundle>::type bundle;
  413. };
  414. template<typename Prop>
  415. struct graph_prop : normal_property<Prop, graph_bundle_t>
  416. { };
  417. template<typename Prop>
  418. struct vertex_prop : normal_property<Prop, vertex_bundle_t>
  419. { };
  420. template<typename Prop>
  421. struct edge_prop : normal_property<Prop, edge_bundle_t>
  422. { };
  423. } // namespace graph_detail
  424. // NOTE: These functions are declared, but never defined since they need to
  425. // be overloaded by graph implementations. However, we need them to be
  426. // declared for the functions below.
  427. template<typename Graph, typename Tag>
  428. typename graph_property<Graph, graph_bundle_t>::type&
  429. get_property(Graph& g, Tag);
  430. template<typename Graph, typename Tag>
  431. typename graph_property<Graph, graph_bundle_t>::type const&
  432. get_property(Graph const& g, Tag);
  433. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  434. // NOTE: This operation is a simple adaptor over the overloaded get_property
  435. // operations.
  436. template<typename Graph>
  437. inline typename graph_property<Graph, graph_bundle_t>::type&
  438. get_property(Graph& g) {
  439. return get_property(g, graph_bundle);
  440. }
  441. template<typename Graph>
  442. inline typename graph_property<Graph, graph_bundle_t>::type const&
  443. get_property(Graph const& g) {
  444. return get_property(g, graph_bundle);
  445. }
  446. #endif
  447. } // namespace boost
  448. #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  449. // Stay out of the way of the concept checking class
  450. # undef Graph
  451. # undef RandomAccessIterator
  452. #endif
  453. #endif /* BOOST_GRAPH_PROPERTIES_HPPA */