graph_traits.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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_TRAITS_HPP
  10. #define BOOST_GRAPH_TRAITS_HPP
  11. #include <boost/config.hpp>
  12. #include <iterator>
  13. #include <utility> /* Primarily for std::pair */
  14. #include <boost/tuple/tuple.hpp>
  15. #include <boost/mpl/if.hpp>
  16. #include <boost/mpl/eval_if.hpp>
  17. #include <boost/mpl/bool.hpp>
  18. #include <boost/mpl/not.hpp>
  19. #include <boost/mpl/has_xxx.hpp>
  20. #include <boost/mpl/void.hpp>
  21. #include <boost/mpl/identity.hpp>
  22. #include <boost/type_traits/is_same.hpp>
  23. #include <boost/iterator/iterator_categories.hpp>
  24. #include <boost/iterator/iterator_adaptor.hpp>
  25. #include <boost/pending/property.hpp>
  26. #include <boost/detail/workaround.hpp>
  27. namespace boost
  28. {
  29. namespace detail
  30. {
  31. #define BOOST_GRAPH_MEMBER_OR_VOID(name) \
  32. BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
  33. template < typename T > struct BOOST_JOIN(get_member_, name) \
  34. { \
  35. typedef typename T::name type; \
  36. }; \
  37. template < typename T > \
  38. struct BOOST_JOIN(get_opt_member_, name) \
  39. : boost::mpl::eval_if_c< BOOST_JOIN(has_, name) < T >::value, BOOST_JOIN(get_member_, name)< T >, boost::mpl::identity< void > >\
  40. { \
  41. };
  42. BOOST_GRAPH_MEMBER_OR_VOID(adjacency_iterator)
  43. BOOST_GRAPH_MEMBER_OR_VOID(out_edge_iterator)
  44. BOOST_GRAPH_MEMBER_OR_VOID(in_edge_iterator)
  45. BOOST_GRAPH_MEMBER_OR_VOID(vertex_iterator)
  46. BOOST_GRAPH_MEMBER_OR_VOID(edge_iterator)
  47. BOOST_GRAPH_MEMBER_OR_VOID(vertices_size_type)
  48. BOOST_GRAPH_MEMBER_OR_VOID(edges_size_type)
  49. BOOST_GRAPH_MEMBER_OR_VOID(degree_size_type)
  50. }
  51. template < typename G > struct graph_traits
  52. {
  53. #define BOOST_GRAPH_PULL_OPT_MEMBER(name) \
  54. typedef typename detail::BOOST_JOIN(get_opt_member_, name)< G >::type name;
  55. typedef typename G::vertex_descriptor vertex_descriptor;
  56. typedef typename G::edge_descriptor edge_descriptor;
  57. BOOST_GRAPH_PULL_OPT_MEMBER(adjacency_iterator)
  58. BOOST_GRAPH_PULL_OPT_MEMBER(out_edge_iterator)
  59. BOOST_GRAPH_PULL_OPT_MEMBER(in_edge_iterator)
  60. BOOST_GRAPH_PULL_OPT_MEMBER(vertex_iterator)
  61. BOOST_GRAPH_PULL_OPT_MEMBER(edge_iterator)
  62. typedef typename G::directed_category directed_category;
  63. typedef typename G::edge_parallel_category edge_parallel_category;
  64. typedef typename G::traversal_category traversal_category;
  65. BOOST_GRAPH_PULL_OPT_MEMBER(vertices_size_type)
  66. BOOST_GRAPH_PULL_OPT_MEMBER(edges_size_type)
  67. BOOST_GRAPH_PULL_OPT_MEMBER(degree_size_type)
  68. #undef BOOST_GRAPH_PULL_OPT_MEMBER
  69. static inline vertex_descriptor null_vertex();
  70. };
  71. template < typename G >
  72. inline typename graph_traits< G >::vertex_descriptor
  73. graph_traits< G >::null_vertex()
  74. {
  75. return G::null_vertex();
  76. }
  77. // directed_category tags
  78. struct directed_tag
  79. {
  80. };
  81. struct undirected_tag
  82. {
  83. };
  84. struct bidirectional_tag : public directed_tag
  85. {
  86. };
  87. namespace detail
  88. {
  89. inline bool is_directed(directed_tag) { return true; }
  90. inline bool is_directed(undirected_tag) { return false; }
  91. }
  92. /** Return true if the given graph is directed. */
  93. template < typename Graph > bool is_directed(const Graph&)
  94. {
  95. typedef typename graph_traits< Graph >::directed_category Cat;
  96. return detail::is_directed(Cat());
  97. }
  98. /** Return true if the given graph is undirected. */
  99. template < typename Graph > bool is_undirected(const Graph& g)
  100. {
  101. return !is_directed(g);
  102. }
  103. /** @name Directed/Undirected Graph Traits */
  104. //@{
  105. namespace graph_detail
  106. {
  107. template < typename Tag >
  108. struct is_directed_tag
  109. : mpl::bool_< is_convertible< Tag, directed_tag >::value >
  110. {
  111. };
  112. } // namespace graph_detail
  113. template < typename Graph >
  114. struct is_directed_graph
  115. : graph_detail::is_directed_tag<
  116. typename graph_traits< Graph >::directed_category >
  117. {
  118. };
  119. template < typename Graph >
  120. struct is_undirected_graph : mpl::not_< is_directed_graph< Graph > >
  121. {
  122. };
  123. //@}
  124. // edge_parallel_category tags
  125. struct allow_parallel_edge_tag
  126. {
  127. };
  128. struct disallow_parallel_edge_tag
  129. {
  130. };
  131. namespace detail
  132. {
  133. inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
  134. inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
  135. }
  136. template < typename Graph > bool allows_parallel_edges(const Graph&)
  137. {
  138. typedef typename graph_traits< Graph >::edge_parallel_category Cat;
  139. return detail::allows_parallel(Cat());
  140. }
  141. /** @name Parallel Edges Traits */
  142. //@{
  143. /**
  144. * The is_multigraph metafunction returns true if the graph allows
  145. * parallel edges. Technically, a multigraph is a simple graph that
  146. * allows parallel edges, but since there are no traits for the allowance
  147. * or disallowance of loops, this is a moot point.
  148. */
  149. template < typename Graph >
  150. struct is_multigraph
  151. : mpl::bool_< is_same< typename graph_traits< Graph >::edge_parallel_category,
  152. allow_parallel_edge_tag >::value >
  153. {
  154. };
  155. //@}
  156. // traversal_category tags
  157. struct incidence_graph_tag
  158. {
  159. };
  160. struct adjacency_graph_tag
  161. {
  162. };
  163. struct bidirectional_graph_tag : virtual incidence_graph_tag
  164. {
  165. };
  166. struct vertex_list_graph_tag
  167. {
  168. };
  169. struct edge_list_graph_tag
  170. {
  171. };
  172. struct adjacency_matrix_tag
  173. {
  174. };
  175. // Parallel traversal_category tags
  176. struct distributed_graph_tag
  177. {
  178. };
  179. struct distributed_vertex_list_graph_tag
  180. {
  181. };
  182. struct distributed_edge_list_graph_tag
  183. {
  184. };
  185. #define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS // Disable these
  186. // from external
  187. // versions of
  188. // PBGL
  189. /** @name Traversal Category Traits
  190. * These traits classify graph types by their supported methods of
  191. * vertex and edge traversal.
  192. */
  193. //@{
  194. template < typename Graph >
  195. struct is_incidence_graph
  196. : mpl::bool_<
  197. is_convertible< typename graph_traits< Graph >::traversal_category,
  198. incidence_graph_tag >::value >
  199. {
  200. };
  201. template < typename Graph >
  202. struct is_bidirectional_graph
  203. : mpl::bool_<
  204. is_convertible< typename graph_traits< Graph >::traversal_category,
  205. bidirectional_graph_tag >::value >
  206. {
  207. };
  208. template < typename Graph >
  209. struct is_vertex_list_graph
  210. : mpl::bool_<
  211. is_convertible< typename graph_traits< Graph >::traversal_category,
  212. vertex_list_graph_tag >::value >
  213. {
  214. };
  215. template < typename Graph >
  216. struct is_edge_list_graph
  217. : mpl::bool_<
  218. is_convertible< typename graph_traits< Graph >::traversal_category,
  219. edge_list_graph_tag >::value >
  220. {
  221. };
  222. template < typename Graph >
  223. struct is_adjacency_matrix
  224. : mpl::bool_<
  225. is_convertible< typename graph_traits< Graph >::traversal_category,
  226. adjacency_matrix_tag >::value >
  227. {
  228. };
  229. //@}
  230. /** @name Directed Graph Traits
  231. * These metafunctions are used to fully classify directed vs. undirected
  232. * graphs. Recall that an undirected graph is also bidirectional, but it
  233. * cannot be both undirected and directed at the same time.
  234. */
  235. //@{
  236. template < typename Graph >
  237. struct is_directed_unidirectional_graph
  238. : mpl::and_< is_directed_graph< Graph >,
  239. mpl::not_< is_bidirectional_graph< Graph > > >
  240. {
  241. };
  242. template < typename Graph >
  243. struct is_directed_bidirectional_graph
  244. : mpl::and_< is_directed_graph< Graph >, is_bidirectional_graph< Graph > >
  245. {
  246. };
  247. //@}
  248. //?? not the right place ?? Lee
  249. typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
  250. namespace detail
  251. {
  252. BOOST_MPL_HAS_XXX_TRAIT_DEF(graph_property_type)
  253. BOOST_MPL_HAS_XXX_TRAIT_DEF(edge_property_type)
  254. BOOST_MPL_HAS_XXX_TRAIT_DEF(vertex_property_type)
  255. template < typename G > struct get_graph_property_type
  256. {
  257. typedef typename G::graph_property_type type;
  258. };
  259. template < typename G > struct get_edge_property_type
  260. {
  261. typedef typename G::edge_property_type type;
  262. };
  263. template < typename G > struct get_vertex_property_type
  264. {
  265. typedef typename G::vertex_property_type type;
  266. };
  267. }
  268. template < typename G >
  269. struct graph_property_type
  270. : boost::mpl::eval_if< detail::has_graph_property_type< G >,
  271. detail::get_graph_property_type< G >, no_property >
  272. {
  273. };
  274. template < typename G >
  275. struct edge_property_type
  276. : boost::mpl::eval_if< detail::has_edge_property_type< G >,
  277. detail::get_edge_property_type< G >, no_property >
  278. {
  279. };
  280. template < typename G >
  281. struct vertex_property_type
  282. : boost::mpl::eval_if< detail::has_vertex_property_type< G >,
  283. detail::get_vertex_property_type< G >, no_property >
  284. {
  285. };
  286. template < typename G > struct graph_bundle_type
  287. {
  288. typedef typename G::graph_bundled type;
  289. };
  290. template < typename G > struct vertex_bundle_type
  291. {
  292. typedef typename G::vertex_bundled type;
  293. };
  294. template < typename G > struct edge_bundle_type
  295. {
  296. typedef typename G::edge_bundled type;
  297. };
  298. namespace graph
  299. {
  300. namespace detail
  301. {
  302. template < typename Graph, typename Descriptor > class bundled_result
  303. {
  304. typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
  305. typedef typename mpl::if_c< (is_same< Descriptor, Vertex >::value),
  306. vertex_bundle_type< Graph >, edge_bundle_type< Graph > >::type
  307. bundler;
  308. public:
  309. typedef typename bundler::type type;
  310. };
  311. template < typename Graph >
  312. class bundled_result< Graph, graph_bundle_t >
  313. {
  314. typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
  315. typedef graph_bundle_type< Graph > bundler;
  316. public:
  317. typedef typename bundler::type type;
  318. };
  319. }
  320. } // namespace graph::detail
  321. namespace graph_detail
  322. {
  323. // A helper metafunction for determining whether or not a type is
  324. // bundled.
  325. template < typename T >
  326. struct is_no_bundle : mpl::bool_< is_same< T, no_property >::value >
  327. {
  328. };
  329. } // namespace graph_detail
  330. /** @name Graph Property Traits
  331. * These metafunctions (along with those above), can be used to access the
  332. * vertex and edge properties (bundled or otherwise) of vertices and
  333. * edges.
  334. */
  335. //@{
  336. template < typename Graph >
  337. struct has_graph_property
  338. : mpl::not_< typename detail::is_no_property<
  339. typename graph_property_type< Graph >::type >::type >::type
  340. {
  341. };
  342. template < typename Graph >
  343. struct has_bundled_graph_property
  344. : mpl::not_<
  345. graph_detail::is_no_bundle< typename graph_bundle_type< Graph >::type > >
  346. {
  347. };
  348. template < typename Graph >
  349. struct has_vertex_property
  350. : mpl::not_< typename detail::is_no_property<
  351. typename vertex_property_type< Graph >::type > >::type
  352. {
  353. };
  354. template < typename Graph >
  355. struct has_bundled_vertex_property
  356. : mpl::not_<
  357. graph_detail::is_no_bundle< typename vertex_bundle_type< Graph >::type > >
  358. {
  359. };
  360. template < typename Graph >
  361. struct has_edge_property
  362. : mpl::not_< typename detail::is_no_property<
  363. typename edge_property_type< Graph >::type > >::type
  364. {
  365. };
  366. template < typename Graph >
  367. struct has_bundled_edge_property
  368. : mpl::not_<
  369. graph_detail::is_no_bundle< typename edge_bundle_type< Graph >::type > >
  370. {
  371. };
  372. //@}
  373. } // namespace boost
  374. // Since pair is in namespace std, Koenig lookup will find source and
  375. // target if they are also defined in namespace std. This is illegal,
  376. // but the alternative is to put source and target in the global
  377. // namespace which causes name conflicts with other libraries (like
  378. // SUIF).
  379. namespace std
  380. {
  381. /* Some helper functions for dealing with pairs as edges */
  382. template < class T, class G > T source(pair< T, T > p, const G&)
  383. {
  384. return p.first;
  385. }
  386. template < class T, class G > T target(pair< T, T > p, const G&)
  387. {
  388. return p.second;
  389. }
  390. }
  391. #if defined(__GNUC__) && defined(__SGI_STL_PORT)
  392. // For some reason g++ with STLport does not see the above definition
  393. // of source() and target() unless we bring them into the boost
  394. // namespace.
  395. namespace boost
  396. {
  397. using std::source;
  398. using std::target;
  399. }
  400. #endif
  401. #endif // BOOST_GRAPH_TRAITS_HPP