properties.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  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.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. namespace boost
  26. {
  27. enum default_color_type
  28. {
  29. white_color,
  30. gray_color,
  31. green_color,
  32. red_color,
  33. black_color
  34. };
  35. template < class ColorValue > struct color_traits
  36. {
  37. static default_color_type white() { return white_color; }
  38. static default_color_type gray() { return gray_color; }
  39. static default_color_type green() { return green_color; }
  40. static default_color_type red() { return red_color; }
  41. static default_color_type black() { return black_color; }
  42. };
  43. // These functions are now obsolete, replaced by color_traits.
  44. inline default_color_type white(default_color_type) { return white_color; }
  45. inline default_color_type gray(default_color_type) { return gray_color; }
  46. inline default_color_type green(default_color_type) { return green_color; }
  47. inline default_color_type red(default_color_type) { return red_color; }
  48. inline default_color_type black(default_color_type) { return black_color; }
  49. struct graph_property_tag
  50. {
  51. };
  52. struct vertex_property_tag
  53. {
  54. };
  55. struct edge_property_tag
  56. {
  57. };
  58. // See examples/edge_property.cpp for how to use this.
  59. #define BOOST_INSTALL_PROPERTY(KIND, NAME) \
  60. template <> struct property_kind< KIND##_##NAME##_t > \
  61. { \
  62. typedef KIND##_property_tag type; \
  63. }
  64. #define BOOST_DEF_PROPERTY(KIND, NAME) \
  65. enum KIND##_##NAME##_t { KIND##_##NAME }; \
  66. BOOST_INSTALL_PROPERTY(KIND, NAME)
  67. // These three are defined in boost/pending/property.hpp
  68. BOOST_INSTALL_PROPERTY(vertex, all);
  69. BOOST_INSTALL_PROPERTY(edge, all);
  70. BOOST_INSTALL_PROPERTY(graph, all);
  71. BOOST_DEF_PROPERTY(vertex, index);
  72. BOOST_DEF_PROPERTY(vertex, index1);
  73. BOOST_DEF_PROPERTY(vertex, index2);
  74. BOOST_DEF_PROPERTY(vertex, root);
  75. BOOST_DEF_PROPERTY(edge, index);
  76. BOOST_DEF_PROPERTY(edge, name);
  77. BOOST_DEF_PROPERTY(edge, weight);
  78. BOOST_DEF_PROPERTY(edge, weight2);
  79. BOOST_DEF_PROPERTY(edge, color);
  80. BOOST_DEF_PROPERTY(vertex, name);
  81. BOOST_DEF_PROPERTY(graph, name);
  82. BOOST_DEF_PROPERTY(vertex, distance);
  83. BOOST_DEF_PROPERTY(vertex, distance2);
  84. BOOST_DEF_PROPERTY(vertex, color);
  85. BOOST_DEF_PROPERTY(vertex, degree);
  86. BOOST_DEF_PROPERTY(vertex, in_degree);
  87. BOOST_DEF_PROPERTY(vertex, out_degree);
  88. BOOST_DEF_PROPERTY(vertex, current_degree);
  89. BOOST_DEF_PROPERTY(vertex, priority);
  90. BOOST_DEF_PROPERTY(vertex, discover_time);
  91. BOOST_DEF_PROPERTY(vertex, finish_time);
  92. BOOST_DEF_PROPERTY(vertex, predecessor);
  93. BOOST_DEF_PROPERTY(vertex, rank);
  94. BOOST_DEF_PROPERTY(vertex, centrality);
  95. BOOST_DEF_PROPERTY(vertex, lowpoint);
  96. BOOST_DEF_PROPERTY(vertex, potential);
  97. BOOST_DEF_PROPERTY(vertex, update);
  98. BOOST_DEF_PROPERTY(vertex, underlying);
  99. BOOST_DEF_PROPERTY(edge, reverse);
  100. BOOST_DEF_PROPERTY(edge, capacity);
  101. BOOST_DEF_PROPERTY(edge, flow);
  102. BOOST_DEF_PROPERTY(edge, residual_capacity);
  103. BOOST_DEF_PROPERTY(edge, centrality);
  104. BOOST_DEF_PROPERTY(edge, discover_time);
  105. BOOST_DEF_PROPERTY(edge, update);
  106. BOOST_DEF_PROPERTY(edge, finished);
  107. BOOST_DEF_PROPERTY(edge, underlying);
  108. BOOST_DEF_PROPERTY(graph, visitor);
  109. // These tags are used for property bundles
  110. // These three are defined in boost/pending/property.hpp
  111. BOOST_INSTALL_PROPERTY(graph, bundle);
  112. BOOST_INSTALL_PROPERTY(vertex, bundle);
  113. BOOST_INSTALL_PROPERTY(edge, bundle);
  114. // These tags are used to denote the owners and local descriptors
  115. // for the vertices and edges of a distributed graph.
  116. BOOST_DEF_PROPERTY(vertex, global);
  117. BOOST_DEF_PROPERTY(vertex, owner);
  118. BOOST_DEF_PROPERTY(vertex, local);
  119. BOOST_DEF_PROPERTY(edge, global);
  120. BOOST_DEF_PROPERTY(edge, owner);
  121. BOOST_DEF_PROPERTY(edge, local);
  122. BOOST_DEF_PROPERTY(vertex, local_index);
  123. BOOST_DEF_PROPERTY(edge, local_index);
  124. #undef BOOST_DEF_PROPERTY
  125. namespace detail
  126. {
  127. template < typename G, typename Tag >
  128. struct property_kind_from_graph : property_kind< Tag >
  129. {
  130. };
  131. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  132. template < typename G, typename R, typename T >
  133. struct property_kind_from_graph< G, R T::* >
  134. {
  135. typedef typename boost::mpl::if_<
  136. boost::is_base_of< T, typename vertex_bundle_type< G >::type >,
  137. vertex_property_tag,
  138. typename boost::mpl::if_<
  139. boost::is_base_of< T, typename edge_bundle_type< G >::type >,
  140. edge_property_tag,
  141. typename boost::mpl::if_<
  142. boost::is_base_of< T,
  143. typename graph_bundle_type< G >::type >,
  144. graph_property_tag, void >::type >::type >::type type;
  145. };
  146. #endif
  147. struct dummy_edge_property_selector
  148. {
  149. template < class Graph, class Property, class Tag > struct bind_
  150. {
  151. typedef identity_property_map type;
  152. typedef identity_property_map const_type;
  153. };
  154. };
  155. struct dummy_vertex_property_selector
  156. {
  157. template < class Graph, class Property, class Tag > struct bind_
  158. {
  159. typedef identity_property_map type;
  160. typedef identity_property_map const_type;
  161. };
  162. };
  163. } // namespace detail
  164. // Graph classes can either partially specialize property_map
  165. // or they can specialize these two selector classes.
  166. template < class GraphTag > struct edge_property_selector
  167. {
  168. typedef detail::dummy_edge_property_selector type;
  169. };
  170. template < class GraphTag > struct vertex_property_selector
  171. {
  172. typedef detail::dummy_vertex_property_selector type;
  173. };
  174. namespace detail
  175. {
  176. template < typename A > struct return_void
  177. {
  178. typedef void type;
  179. };
  180. template < typename Graph, typename Enable = void > struct graph_tag_or_void
  181. {
  182. typedef void type;
  183. };
  184. template < typename Graph >
  185. struct graph_tag_or_void< Graph,
  186. typename return_void< typename Graph::graph_tag >::type >
  187. {
  188. typedef typename Graph::graph_tag type;
  189. };
  190. template < class Graph, class PropertyTag >
  191. struct edge_property_map
  192. : edge_property_selector< typename graph_tag_or_void< Graph >::type >::
  193. type::template bind_< Graph,
  194. typename edge_property_type< Graph >::type, PropertyTag >
  195. {
  196. };
  197. template < class Graph, class PropertyTag >
  198. struct vertex_property_map
  199. : vertex_property_selector< typename graph_tag_or_void< Graph >::type >::
  200. type::template bind_< Graph,
  201. typename vertex_property_type< Graph >::type, PropertyTag >
  202. {
  203. };
  204. } // namespace detail
  205. template < class Graph, class Property, class Enable = void >
  206. struct property_map
  207. : mpl::if_< is_same< typename detail::property_kind_from_graph< Graph,
  208. Property >::type,
  209. edge_property_tag >,
  210. detail::edge_property_map< Graph, Property >,
  211. detail::vertex_property_map< Graph, Property > >::type
  212. {
  213. };
  214. // shortcut for accessing the value type of the property map
  215. template < class Graph, class Property > class property_map_value
  216. {
  217. typedef typename property_map< Graph, Property >::const_type PMap;
  218. public:
  219. typedef typename property_traits< PMap >::value_type type;
  220. };
  221. template < class Graph, class Property > class graph_property
  222. {
  223. public:
  224. typedef typename property_value<
  225. typename boost::graph_property_type< Graph >::type, Property >::type
  226. type;
  227. };
  228. template < typename Graph >
  229. struct vertex_property : vertex_property_type< Graph >
  230. {
  231. };
  232. template < typename Graph > struct edge_property : edge_property_type< Graph >
  233. {
  234. };
  235. template < typename Graph >
  236. class degree_property_map
  237. : public put_get_helper< typename graph_traits< Graph >::degree_size_type,
  238. degree_property_map< Graph > >
  239. {
  240. public:
  241. typedef typename graph_traits< Graph >::vertex_descriptor key_type;
  242. typedef typename graph_traits< Graph >::degree_size_type value_type;
  243. typedef value_type reference;
  244. typedef readable_property_map_tag category;
  245. degree_property_map(const Graph& g) : m_g(g) {}
  246. value_type operator[](const key_type& v) const { return degree(v, m_g); }
  247. private:
  248. const Graph& m_g;
  249. };
  250. template < typename Graph >
  251. inline degree_property_map< Graph > make_degree_map(const Graph& g)
  252. {
  253. return degree_property_map< Graph >(g);
  254. }
  255. //========================================================================
  256. // Iterator Property Map Generating Functions contributed by
  257. // Kevin Vanhorn. (see also the property map generating functions
  258. // in boost/property_map/property_map.hpp)
  259. #if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
  260. // A helper function for creating a vertex property map out of a
  261. // random access iterator and the internal vertex index map from a
  262. // graph.
  263. template < class PropertyGraph, class RandomAccessIterator >
  264. inline iterator_property_map< RandomAccessIterator,
  265. typename property_map< PropertyGraph, vertex_index_t >::type,
  266. typename std::iterator_traits< RandomAccessIterator >::value_type,
  267. typename std::iterator_traits< RandomAccessIterator >::reference >
  268. make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
  269. {
  270. return make_iterator_property_map(iter, get(vertex_index, g));
  271. }
  272. // Use this next function when vertex_descriptor is known to be an
  273. // integer type, with values ranging from 0 to num_vertices(g).
  274. //
  275. template < class RandomAccessIterator >
  276. inline iterator_property_map< RandomAccessIterator, identity_property_map,
  277. typename std::iterator_traits< RandomAccessIterator >::value_type,
  278. typename std::iterator_traits< RandomAccessIterator >::reference >
  279. make_iterator_vertex_map(RandomAccessIterator iter)
  280. {
  281. return make_iterator_property_map(iter, identity_property_map());
  282. }
  283. #endif
  284. template < class PropertyGraph, class RandomAccessContainer >
  285. inline iterator_property_map< typename RandomAccessContainer::iterator,
  286. typename property_map< PropertyGraph, vertex_index_t >::type,
  287. typename RandomAccessContainer::value_type,
  288. typename RandomAccessContainer::reference >
  289. make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
  290. {
  291. BOOST_ASSERT(c.size() >= num_vertices(g));
  292. return make_iterator_vertex_map(c.begin(), g);
  293. }
  294. template < class RandomAccessContainer >
  295. inline iterator_property_map< typename RandomAccessContainer::iterator,
  296. identity_property_map, typename RandomAccessContainer::value_type,
  297. typename RandomAccessContainer::reference >
  298. make_container_vertex_map(RandomAccessContainer& c)
  299. {
  300. return make_iterator_vertex_map(c.begin());
  301. }
  302. // NOTE: These functions are declared, but never defined since they need to
  303. // be overloaded by graph implementations. However, we need them to be
  304. // declared for the functions below.
  305. template < typename Graph, typename Tag >
  306. typename graph_property< Graph, graph_bundle_t >::type& get_property(
  307. Graph& g, Tag);
  308. template < typename Graph, typename Tag >
  309. typename graph_property< Graph, graph_bundle_t >::type const& get_property(
  310. Graph const& g, Tag);
  311. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  312. // NOTE: This operation is a simple adaptor over the overloaded get_property
  313. // operations.
  314. template < typename Graph >
  315. inline typename graph_property< Graph, graph_bundle_t >::type& get_property(
  316. Graph& g)
  317. {
  318. return get_property(g, graph_bundle);
  319. }
  320. template < typename Graph >
  321. inline typename graph_property< Graph, graph_bundle_t >::type const&
  322. get_property(const Graph& g)
  323. {
  324. return get_property(g, graph_bundle);
  325. }
  326. #endif
  327. } // namespace boost
  328. #endif /* BOOST_GRAPH_PROPERTIES_HPP */