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

http://hadesmem.googlecode.com/ · C++ Header · 367 lines · 256 code · 51 blank · 60 comment · 1 complexity · 8ea29af7ae2dddd82430005d1254e67a 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_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/bool.hpp>
  17. #include <boost/mpl/not.hpp>
  18. #include <boost/type_traits/is_same.hpp>
  19. #include <boost/iterator/iterator_categories.hpp>
  20. #include <boost/iterator/iterator_adaptor.hpp>
  21. #include <boost/pending/property.hpp>
  22. #include <boost/detail/workaround.hpp>
  23. namespace boost {
  24. template <typename G>
  25. struct graph_traits {
  26. typedef typename G::vertex_descriptor vertex_descriptor;
  27. typedef typename G::edge_descriptor edge_descriptor;
  28. typedef typename G::adjacency_iterator adjacency_iterator;
  29. typedef typename G::out_edge_iterator out_edge_iterator;
  30. typedef typename G::in_edge_iterator in_edge_iterator;
  31. typedef typename G::vertex_iterator vertex_iterator;
  32. typedef typename G::edge_iterator edge_iterator;
  33. typedef typename G::directed_category directed_category;
  34. typedef typename G::edge_parallel_category edge_parallel_category;
  35. typedef typename G::traversal_category traversal_category;
  36. typedef typename G::vertices_size_type vertices_size_type;
  37. typedef typename G::edges_size_type edges_size_type;
  38. typedef typename G::degree_size_type degree_size_type;
  39. static inline vertex_descriptor null_vertex();
  40. };
  41. template <typename G>
  42. inline typename graph_traits<G>::vertex_descriptor
  43. graph_traits<G>::null_vertex()
  44. { return G::null_vertex(); }
  45. // directed_category tags
  46. struct directed_tag { };
  47. struct undirected_tag { };
  48. struct bidirectional_tag : public directed_tag { };
  49. namespace detail {
  50. inline bool is_directed(directed_tag) { return true; }
  51. inline bool is_directed(undirected_tag) { return false; }
  52. }
  53. /** Return true if the given graph is directed. */
  54. template <typename Graph>
  55. bool is_directed(const Graph&) {
  56. typedef typename graph_traits<Graph>::directed_category Cat;
  57. return detail::is_directed(Cat());
  58. }
  59. /** Return true if the given graph is undirected. */
  60. template <typename Graph>
  61. bool is_undirected(const Graph& g) {
  62. return !is_directed(g);
  63. }
  64. /** @name Directed/Undirected Graph Traits */
  65. //@{
  66. namespace graph_detail {
  67. template <typename Tag>
  68. struct is_directed_tag
  69. : mpl::bool_<is_convertible<Tag, directed_tag>::value>
  70. { };
  71. } // namespace graph_detail
  72. template <typename Graph>
  73. struct is_directed_graph
  74. : graph_detail::is_directed_tag<
  75. typename graph_traits<Graph>::directed_category
  76. >
  77. { };
  78. template <typename Graph>
  79. struct is_undirected_graph
  80. : mpl::not_< is_directed_graph<Graph> >
  81. { };
  82. //@}
  83. // edge_parallel_category tags
  84. struct allow_parallel_edge_tag { };
  85. struct disallow_parallel_edge_tag { };
  86. namespace detail {
  87. inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
  88. inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
  89. }
  90. template <typename Graph>
  91. bool allows_parallel_edges(const Graph&) {
  92. typedef typename graph_traits<Graph>::edge_parallel_category Cat;
  93. return detail::allows_parallel(Cat());
  94. }
  95. /** @name Parallel Edges Traits */
  96. //@{
  97. /**
  98. * The is_multigraph metafunction returns true if the graph allows
  99. * parallel edges. Technically, a multigraph is a simple graph that
  100. * allows parallel edges, but since there are no traits for the allowance
  101. * or disallowance of loops, this is a moot point.
  102. */
  103. template <typename Graph>
  104. struct is_multigraph
  105. : mpl::bool_<
  106. is_same<
  107. typename graph_traits<Graph>::edge_parallel_category,
  108. allow_parallel_edge_tag
  109. >::value
  110. >
  111. { };
  112. //@}
  113. // traversal_category tags
  114. struct incidence_graph_tag { };
  115. struct adjacency_graph_tag { };
  116. struct bidirectional_graph_tag : virtual incidence_graph_tag { };
  117. struct vertex_list_graph_tag { };
  118. struct edge_list_graph_tag { };
  119. struct adjacency_matrix_tag { };
  120. /** @name Taversal Category Traits
  121. * These traits classify graph types by their supported methods of
  122. * vertex and edge traversal.
  123. */
  124. //@{
  125. template <typename Graph>
  126. struct is_incidence_graph
  127. : mpl::bool_<
  128. is_convertible<
  129. typename graph_traits<Graph>::traversal_category,
  130. incidence_graph_tag
  131. >::value
  132. >
  133. { };
  134. template <typename Graph>
  135. struct is_bidirectional_graph
  136. : mpl::bool_<
  137. is_convertible<
  138. typename graph_traits<Graph>::traversal_category,
  139. bidirectional_graph_tag
  140. >::value
  141. >
  142. { };
  143. template <typename Graph>
  144. struct is_vertex_list_graph
  145. : mpl::bool_<
  146. is_convertible<
  147. typename graph_traits<Graph>::traversal_category,
  148. vertex_list_graph_tag
  149. >::value
  150. >
  151. { };
  152. template <typename Graph>
  153. struct is_edge_list_graph
  154. : mpl::bool_<
  155. is_convertible<
  156. typename graph_traits<Graph>::traversal_category,
  157. edge_list_graph_tag
  158. >::value
  159. >
  160. { };
  161. template <typename Graph>
  162. struct is_adjacency_matrix
  163. : mpl::bool_<
  164. is_convertible<
  165. typename graph_traits<Graph>::traversal_category,
  166. adjacency_matrix_tag
  167. >::value
  168. >
  169. { };
  170. //@}
  171. /** @name Directed Graph Traits
  172. * These metafunctions are used to fully classify directed vs. undirected
  173. * graphs. Recall that an undirected graph is also bidirectional, but it
  174. * cannot be both undirected and directed at the same time.
  175. */
  176. //@{
  177. template <typename Graph>
  178. struct is_directed_unidirectional_graph
  179. : mpl::and_<
  180. is_directed_graph<Graph>, mpl::not_< is_bidirectional_graph<Graph> >
  181. >
  182. { };
  183. template <typename Graph>
  184. struct is_directed_bidirectional_graph
  185. : mpl::and_<
  186. is_directed_graph<Graph>, is_bidirectional_graph<Graph>
  187. >
  188. { };
  189. //@}
  190. //?? not the right place ?? Lee
  191. typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
  192. // Forward declare graph_bundle_t property name (from
  193. // boost/graph/properties.hpp, which includes this file) for
  194. // bundled_result.
  195. enum graph_bundle_t {graph_bundle};
  196. template <typename G>
  197. struct graph_property_type {
  198. typedef typename G::graph_property_type type;
  199. };
  200. template <typename G>
  201. struct edge_property_type {
  202. typedef typename G::edge_property_type type;
  203. };
  204. template <typename G>
  205. struct vertex_property_type {
  206. typedef typename G::vertex_property_type type;
  207. };
  208. struct no_bundle { };
  209. struct no_graph_bundle : no_bundle { };
  210. struct no_vertex_bundle : no_bundle { };
  211. struct no_edge_bundle : no_bundle { };
  212. template<typename G>
  213. struct graph_bundle_type {
  214. typedef typename G::graph_bundled type;
  215. };
  216. template<typename G>
  217. struct vertex_bundle_type {
  218. typedef typename G::vertex_bundled type;
  219. };
  220. template<typename G>
  221. struct edge_bundle_type {
  222. typedef typename G::edge_bundled type;
  223. };
  224. namespace graph { namespace detail {
  225. template<typename Graph, typename Descriptor>
  226. class bundled_result {
  227. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  228. typedef typename mpl::if_c<(is_same<Descriptor, Vertex>::value),
  229. vertex_bundle_type<Graph>,
  230. edge_bundle_type<Graph> >::type bundler;
  231. public:
  232. typedef typename bundler::type type;
  233. };
  234. template<typename Graph>
  235. class bundled_result<Graph, graph_bundle_t> {
  236. typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  237. typedef graph_bundle_type<Graph> bundler;
  238. public:
  239. typedef typename bundler::type type;
  240. };
  241. } } // namespace graph::detail
  242. namespace graph_detail {
  243. // A helper metafunction for determining whether or not a type is
  244. // bundled.
  245. template <typename T>
  246. struct is_no_bundle : mpl::bool_<is_convertible<T, no_bundle>::value>
  247. { };
  248. } // namespace graph_detail
  249. /** @name Graph Property Traits
  250. * These metafunctions (along with those above), can be used to access the
  251. * vertex and edge properties (bundled or otherwise) of vertices and
  252. * edges.
  253. */
  254. //@{
  255. template<typename Graph>
  256. struct has_graph_property
  257. : mpl::not_<
  258. typename detail::is_no_property<
  259. typename graph_property_type<Graph>::type
  260. >::type
  261. >::type
  262. { };
  263. template<typename Graph>
  264. struct has_bundled_graph_property
  265. : mpl::not_<
  266. graph_detail::is_no_bundle<typename graph_bundle_type<Graph>::type>
  267. >
  268. { };
  269. template <typename Graph>
  270. struct has_vertex_property
  271. : mpl::not_<
  272. typename detail::is_no_property<typename vertex_property_type<Graph>::type>
  273. >::type
  274. { };
  275. template <typename Graph>
  276. struct has_bundled_vertex_property
  277. : mpl::not_<
  278. graph_detail::is_no_bundle<typename vertex_bundle_type<Graph>::type>
  279. >
  280. { };
  281. template <typename Graph>
  282. struct has_edge_property
  283. : mpl::not_<
  284. typename detail::is_no_property<typename edge_property_type<Graph>::type>
  285. >::type
  286. { };
  287. template <typename Graph>
  288. struct has_bundled_edge_property
  289. : mpl::not_<
  290. graph_detail::is_no_bundle<typename edge_bundle_type<Graph>::type>
  291. >
  292. { };
  293. //@}
  294. } // namespace boost
  295. // Since pair is in namespace std, Koenig lookup will find source and
  296. // target if they are also defined in namespace std. This is illegal,
  297. // but the alternative is to put source and target in the global
  298. // namespace which causes name conflicts with other libraries (like
  299. // SUIF).
  300. namespace std {
  301. /* Some helper functions for dealing with pairs as edges */
  302. template <class T, class G>
  303. T source(pair<T,T> p, const G&) { return p.first; }
  304. template <class T, class G>
  305. T target(pair<T,T> p, const G&) { return p.second; }
  306. }
  307. #if defined(__GNUC__) && defined(__SGI_STL_PORT)
  308. // For some reason g++ with STLport does not see the above definition
  309. // of source() and target() unless we bring them into the boost
  310. // namespace.
  311. namespace boost {
  312. using std::source;
  313. using std::target;
  314. }
  315. #endif
  316. #endif // BOOST_GRAPH_TRAITS_HPP