File indexing completed on 2025-09-13 08:36:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GRAPH_TRAITS_HPP
0011 #define BOOST_GRAPH_TRAITS_HPP
0012
0013 #include <boost/config.hpp>
0014 #include <iterator>
0015 #include <utility> /* Primarily for std::pair */
0016 #include <boost/tuple/tuple.hpp>
0017 #include <boost/mpl/if.hpp>
0018 #include <boost/mpl/eval_if.hpp>
0019 #include <boost/mpl/bool.hpp>
0020 #include <boost/mpl/not.hpp>
0021 #include <boost/mpl/has_xxx.hpp>
0022 #include <boost/mpl/void.hpp>
0023 #include <boost/mpl/identity.hpp>
0024 #include <boost/mpl/and.hpp>
0025 #include <boost/type_traits/is_same.hpp>
0026 #include <boost/iterator/iterator_categories.hpp>
0027 #include <boost/iterator/iterator_adaptor.hpp>
0028 #include <boost/pending/property.hpp>
0029 #include <boost/detail/workaround.hpp>
0030
0031 namespace boost
0032 {
0033
0034 namespace detail
0035 {
0036 #define BOOST_GRAPH_MEMBER_OR_VOID(name) \
0037 BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
0038 template < typename T > struct BOOST_JOIN(get_member_, name) \
0039 { \
0040 typedef typename T::name type; \
0041 }; \
0042 template < typename T > \
0043 struct BOOST_JOIN(get_opt_member_, name) \
0044 : boost::mpl::eval_if_c< BOOST_JOIN(has_, name) < T >::value, BOOST_JOIN(get_member_, name)< T >, boost::mpl::identity< void > >\
0045 { \
0046 };
0047 BOOST_GRAPH_MEMBER_OR_VOID(adjacency_iterator)
0048 BOOST_GRAPH_MEMBER_OR_VOID(out_edge_iterator)
0049 BOOST_GRAPH_MEMBER_OR_VOID(in_edge_iterator)
0050 BOOST_GRAPH_MEMBER_OR_VOID(vertex_iterator)
0051 BOOST_GRAPH_MEMBER_OR_VOID(edge_iterator)
0052 BOOST_GRAPH_MEMBER_OR_VOID(vertices_size_type)
0053 BOOST_GRAPH_MEMBER_OR_VOID(edges_size_type)
0054 BOOST_GRAPH_MEMBER_OR_VOID(degree_size_type)
0055 }
0056
0057 template < typename G > struct graph_traits
0058 {
0059 #define BOOST_GRAPH_PULL_OPT_MEMBER(name) \
0060 typedef typename detail::BOOST_JOIN(get_opt_member_, name)< G >::type name;
0061
0062 typedef typename G::vertex_descriptor vertex_descriptor;
0063 typedef typename G::edge_descriptor edge_descriptor;
0064 BOOST_GRAPH_PULL_OPT_MEMBER(adjacency_iterator)
0065 BOOST_GRAPH_PULL_OPT_MEMBER(out_edge_iterator)
0066 BOOST_GRAPH_PULL_OPT_MEMBER(in_edge_iterator)
0067 BOOST_GRAPH_PULL_OPT_MEMBER(vertex_iterator)
0068 BOOST_GRAPH_PULL_OPT_MEMBER(edge_iterator)
0069
0070 typedef typename G::directed_category directed_category;
0071 typedef typename G::edge_parallel_category edge_parallel_category;
0072 typedef typename G::traversal_category traversal_category;
0073
0074 BOOST_GRAPH_PULL_OPT_MEMBER(vertices_size_type)
0075 BOOST_GRAPH_PULL_OPT_MEMBER(edges_size_type)
0076 BOOST_GRAPH_PULL_OPT_MEMBER(degree_size_type)
0077 #undef BOOST_GRAPH_PULL_OPT_MEMBER
0078
0079 static inline vertex_descriptor null_vertex();
0080 };
0081
0082 template < typename G >
0083 inline typename graph_traits< G >::vertex_descriptor
0084 graph_traits< G >::null_vertex()
0085 {
0086 return G::null_vertex();
0087 }
0088
0089
0090 struct directed_tag
0091 {
0092 };
0093 struct undirected_tag
0094 {
0095 };
0096 struct bidirectional_tag : public directed_tag
0097 {
0098 };
0099
0100 namespace detail
0101 {
0102 inline bool is_directed(directed_tag) { return true; }
0103 inline bool is_directed(undirected_tag) { return false; }
0104 }
0105
0106
0107 template < typename Graph > bool is_directed(const Graph&)
0108 {
0109 typedef typename graph_traits< Graph >::directed_category Cat;
0110 return detail::is_directed(Cat());
0111 }
0112
0113
0114 template < typename Graph > bool is_undirected(const Graph& g)
0115 {
0116 return !is_directed(g);
0117 }
0118
0119
0120
0121 namespace graph_detail
0122 {
0123 template < typename Tag >
0124 struct is_directed_tag
0125 : mpl::bool_< is_convertible< Tag, directed_tag >::value >
0126 {
0127 };
0128 }
0129
0130 template < typename Graph >
0131 struct is_directed_graph
0132 : graph_detail::is_directed_tag<
0133 typename graph_traits< Graph >::directed_category >
0134 {
0135 };
0136
0137 template < typename Graph >
0138 struct is_undirected_graph : mpl::not_< is_directed_graph< Graph > >
0139 {
0140 };
0141
0142
0143
0144 struct allow_parallel_edge_tag
0145 {
0146 };
0147 struct disallow_parallel_edge_tag
0148 {
0149 };
0150
0151 namespace detail
0152 {
0153 inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
0154 inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
0155 }
0156
0157 template < typename Graph > bool allows_parallel_edges(const Graph&)
0158 {
0159 typedef typename graph_traits< Graph >::edge_parallel_category Cat;
0160 return detail::allows_parallel(Cat());
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 template < typename Graph >
0172 struct is_multigraph
0173 : mpl::bool_< is_same< typename graph_traits< Graph >::edge_parallel_category,
0174 allow_parallel_edge_tag >::value >
0175 {
0176 };
0177
0178
0179
0180 struct incidence_graph_tag
0181 {
0182 };
0183 struct adjacency_graph_tag
0184 {
0185 };
0186 struct bidirectional_graph_tag : virtual incidence_graph_tag
0187 {
0188 };
0189 struct vertex_list_graph_tag
0190 {
0191 };
0192 struct edge_list_graph_tag
0193 {
0194 };
0195 struct adjacency_matrix_tag
0196 {
0197 };
0198
0199
0200 struct distributed_graph_tag
0201 {
0202 };
0203 struct distributed_vertex_list_graph_tag
0204 {
0205 };
0206 struct distributed_edge_list_graph_tag
0207 {
0208 };
0209 #define BOOST_GRAPH_SEQUENTIAL_TRAITS_DEFINES_DISTRIBUTED_TAGS
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 template < typename Graph >
0220 struct is_incidence_graph
0221 : mpl::bool_<
0222 is_convertible< typename graph_traits< Graph >::traversal_category,
0223 incidence_graph_tag >::value >
0224 {
0225 };
0226
0227 template < typename Graph >
0228 struct is_bidirectional_graph
0229 : mpl::bool_<
0230 is_convertible< typename graph_traits< Graph >::traversal_category,
0231 bidirectional_graph_tag >::value >
0232 {
0233 };
0234
0235 template < typename Graph >
0236 struct is_vertex_list_graph
0237 : mpl::bool_<
0238 is_convertible< typename graph_traits< Graph >::traversal_category,
0239 vertex_list_graph_tag >::value >
0240 {
0241 };
0242
0243 template < typename Graph >
0244 struct is_edge_list_graph
0245 : mpl::bool_<
0246 is_convertible< typename graph_traits< Graph >::traversal_category,
0247 edge_list_graph_tag >::value >
0248 {
0249 };
0250
0251 template < typename Graph >
0252 struct is_adjacency_matrix
0253 : mpl::bool_<
0254 is_convertible< typename graph_traits< Graph >::traversal_category,
0255 adjacency_matrix_tag >::value >
0256 {
0257 };
0258
0259
0260
0261
0262
0263
0264
0265
0266 template < typename Graph >
0267 struct is_directed_unidirectional_graph
0268 : mpl::and_< is_directed_graph< Graph >,
0269 mpl::not_< is_bidirectional_graph< Graph > > >
0270 {
0271 };
0272
0273 template < typename Graph >
0274 struct is_directed_bidirectional_graph
0275 : mpl::and_< is_directed_graph< Graph >, is_bidirectional_graph< Graph > >
0276 {
0277 };
0278
0279
0280
0281 typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
0282
0283 namespace detail
0284 {
0285 BOOST_MPL_HAS_XXX_TRAIT_DEF(graph_property_type)
0286 BOOST_MPL_HAS_XXX_TRAIT_DEF(edge_property_type)
0287 BOOST_MPL_HAS_XXX_TRAIT_DEF(vertex_property_type)
0288
0289 template < typename G > struct get_graph_property_type
0290 {
0291 typedef typename G::graph_property_type type;
0292 };
0293 template < typename G > struct get_edge_property_type
0294 {
0295 typedef typename G::edge_property_type type;
0296 };
0297 template < typename G > struct get_vertex_property_type
0298 {
0299 typedef typename G::vertex_property_type type;
0300 };
0301 }
0302
0303 template < typename G >
0304 struct graph_property_type
0305 : boost::mpl::eval_if< detail::has_graph_property_type< G >,
0306 detail::get_graph_property_type< G >, no_property >
0307 {
0308 };
0309 template < typename G >
0310 struct edge_property_type
0311 : boost::mpl::eval_if< detail::has_edge_property_type< G >,
0312 detail::get_edge_property_type< G >, no_property >
0313 {
0314 };
0315 template < typename G >
0316 struct vertex_property_type
0317 : boost::mpl::eval_if< detail::has_vertex_property_type< G >,
0318 detail::get_vertex_property_type< G >, no_property >
0319 {
0320 };
0321
0322 template < typename G > struct graph_bundle_type
0323 {
0324 typedef typename G::graph_bundled type;
0325 };
0326
0327 template < typename G > struct vertex_bundle_type
0328 {
0329 typedef typename G::vertex_bundled type;
0330 };
0331
0332 template < typename G > struct edge_bundle_type
0333 {
0334 typedef typename G::edge_bundled type;
0335 };
0336
0337 namespace graph
0338 {
0339 namespace detail
0340 {
0341 template < typename Graph, typename Descriptor > class bundled_result
0342 {
0343 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0344 typedef typename mpl::if_c< (is_same< Descriptor, Vertex >::value),
0345 vertex_bundle_type< Graph >, edge_bundle_type< Graph > >::type
0346 bundler;
0347
0348 public:
0349 typedef typename bundler::type type;
0350 };
0351
0352 template < typename Graph >
0353 class bundled_result< Graph, graph_bundle_t >
0354 {
0355 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0356 typedef graph_bundle_type< Graph > bundler;
0357
0358 public:
0359 typedef typename bundler::type type;
0360 };
0361
0362 }
0363 }
0364
0365 namespace graph_detail
0366 {
0367
0368
0369 template < typename T >
0370 struct is_no_bundle : mpl::bool_< is_same< T, no_property >::value >
0371 {
0372 };
0373 }
0374
0375
0376
0377
0378
0379
0380
0381 template < typename Graph >
0382 struct has_graph_property
0383 : mpl::not_< typename detail::is_no_property<
0384 typename graph_property_type< Graph >::type >::type >::type
0385 {
0386 };
0387
0388 template < typename Graph >
0389 struct has_bundled_graph_property
0390 : mpl::not_<
0391 graph_detail::is_no_bundle< typename graph_bundle_type< Graph >::type > >
0392 {
0393 };
0394
0395 template < typename Graph >
0396 struct has_vertex_property
0397 : mpl::not_< typename detail::is_no_property<
0398 typename vertex_property_type< Graph >::type > >::type
0399 {
0400 };
0401
0402 template < typename Graph >
0403 struct has_bundled_vertex_property
0404 : mpl::not_<
0405 graph_detail::is_no_bundle< typename vertex_bundle_type< Graph >::type > >
0406 {
0407 };
0408
0409 template < typename Graph >
0410 struct has_edge_property
0411 : mpl::not_< typename detail::is_no_property<
0412 typename edge_property_type< Graph >::type > >::type
0413 {
0414 };
0415
0416 template < typename Graph >
0417 struct has_bundled_edge_property
0418 : mpl::not_<
0419 graph_detail::is_no_bundle< typename edge_bundle_type< Graph >::type > >
0420 {
0421 };
0422
0423
0424 }
0425
0426
0427
0428
0429
0430
0431 namespace std
0432 {
0433
0434
0435 template < class T, class G > T source(pair< T, T > p, const G&)
0436 {
0437 return p.first;
0438 }
0439
0440 template < class T, class G > T target(pair< T, T > p, const G&)
0441 {
0442 return p.second;
0443 }
0444
0445 }
0446
0447 #if defined(__GNUC__) && defined(__SGI_STL_PORT)
0448
0449
0450
0451 namespace boost
0452 {
0453 using std::source;
0454 using std::target;
0455 }
0456 #endif
0457
0458 #endif