1 // 2 //======================================================================= 3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. 4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek 5 // 6 // Copyright 2009, Andrew Sutton 7 // 8 // Distributed under the Boost Software License, Version 1.0. (See 9 // accompanying file LICENSE_1_0.txt or copy at 10 // http://www.boost.org/LICENSE_1_0.txt) 11 //======================================================================= 12 // 13 #ifndef BOOST_GRAPH_CONCEPTS_HPP 14 #define BOOST_GRAPH_CONCEPTS_HPP 15 16 #include <boost/config.hpp> 17 #include <boost/property_map/property_map.hpp> 18 #include <boost/graph/graph_traits.hpp> 19 #include <boost/graph/properties.hpp> 20 #include <boost/graph/numeric_values.hpp> 21 #include <boost/graph/buffer_concepts.hpp> 22 #include <boost/concept_check.hpp> 23 #include <boost/type_traits/is_same.hpp> 24 #include <boost/mpl/not.hpp> 25 #include <boost/static_assert.hpp> 26 #include <boost/detail/workaround.hpp> 27 #include <boost/concept/assert.hpp> 28 29 #include <boost/concept/detail/concept_def.hpp> 30 namespace boost 31 { 32 // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if 33 // you want to use vector_as_graph, it is! I'm sure the graph 34 // library leaves these out all over the place. Probably a 35 // redesign involving specializing a template with a static 36 // member function is in order :( 37 // 38 // It is needed in order to allow us to write using boost::vertices as 39 // needed for ADL when using vector_as_graph below. 40 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ 41 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 42 #define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK 43 #endif 44 45 #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK 46 template < class T > 47 typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); 48 #endif 49 50 namespace concepts 51 { BOOST_CONCEPT_USAGE(MultiPassInputIterator)52 BOOST_concept(MultiPassInputIterator, (T)) { BOOST_CONCEPT_USAGE( 53 MultiPassInputIterator) { BOOST_CONCEPT_ASSERT((InputIterator< T >)); 54 } 55 }; 56 57 BOOST_concept(Graph, (G)) 58 { 59 typedef typename graph_traits< G >::vertex_descriptor vertex_descriptor; 60 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 61 typedef typename graph_traits< G >::directed_category directed_category; 62 typedef typename graph_traits< G >::edge_parallel_category 63 edge_parallel_category; 64 typedef typename graph_traits< G >::traversal_category traversal_category; 65 BOOST_CONCEPT_USAGE(Graph)66 BOOST_CONCEPT_USAGE(Graph) 67 { 68 BOOST_CONCEPT_ASSERT((DefaultConstructible< vertex_descriptor >)); 69 BOOST_CONCEPT_ASSERT((EqualityComparable< vertex_descriptor >)); 70 BOOST_CONCEPT_ASSERT((Assignable< vertex_descriptor >)); 71 } 72 G g; 73 }; 74 75 BOOST_concept(IncidenceGraph, (G)) : Graph< G > 76 { 77 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 78 typedef typename graph_traits< G >::out_edge_iterator out_edge_iterator; 79 typedef typename graph_traits< G >::degree_size_type degree_size_type; 80 typedef typename graph_traits< G >::traversal_category traversal_category; 81 82 BOOST_STATIC_ASSERT( 83 (boost::mpl::not_< boost::is_same< out_edge_iterator, void > >::value)); 84 BOOST_STATIC_ASSERT( 85 (boost::mpl::not_< boost::is_same< degree_size_type, void > >::value)); 86 BOOST_CONCEPT_USAGE(IncidenceGraph)87 BOOST_CONCEPT_USAGE(IncidenceGraph) 88 { 89 BOOST_CONCEPT_ASSERT((MultiPassInputIterator< out_edge_iterator >)); 90 BOOST_CONCEPT_ASSERT((DefaultConstructible< edge_descriptor >)); 91 BOOST_CONCEPT_ASSERT((EqualityComparable< edge_descriptor >)); 92 BOOST_CONCEPT_ASSERT((Assignable< edge_descriptor >)); 93 BOOST_CONCEPT_ASSERT( 94 (Convertible< traversal_category, incidence_graph_tag >)); 95 96 p = out_edges(u, g); 97 n = out_degree(u, g); 98 e = *p.first; 99 u = source(e, g); 100 v = target(e, g); 101 const_constraints(g); 102 } const_constraints(const G & cg)103 void const_constraints(const G& cg) 104 { 105 p = out_edges(u, cg); 106 n = out_degree(u, cg); 107 e = *p.first; 108 u = source(e, cg); 109 v = target(e, cg); 110 } 111 std::pair< out_edge_iterator, out_edge_iterator > p; 112 typename graph_traits< G >::vertex_descriptor u, v; 113 typename graph_traits< G >::edge_descriptor e; 114 typename graph_traits< G >::degree_size_type n; 115 G g; 116 }; 117 118 BOOST_concept(BidirectionalGraph, (G)) : IncidenceGraph< G > 119 { 120 typedef typename graph_traits< G >::in_edge_iterator in_edge_iterator; 121 typedef typename graph_traits< G >::traversal_category traversal_category; 122 BOOST_CONCEPT_USAGE(BidirectionalGraph)123 BOOST_CONCEPT_USAGE(BidirectionalGraph) 124 { 125 BOOST_CONCEPT_ASSERT((MultiPassInputIterator< in_edge_iterator >)); 126 BOOST_CONCEPT_ASSERT( 127 (Convertible< traversal_category, bidirectional_graph_tag >)); 128 129 BOOST_STATIC_ASSERT((boost::mpl::not_< 130 boost::is_same< in_edge_iterator, void > >::value)); 131 132 p = in_edges(v, g); 133 n = in_degree(v, g); 134 n = degree(v, g); 135 e = *p.first; 136 const_constraints(g); 137 } const_constraints(const G & cg)138 void const_constraints(const G& cg) 139 { 140 p = in_edges(v, cg); 141 n = in_degree(v, cg); 142 n = degree(v, cg); 143 e = *p.first; 144 } 145 std::pair< in_edge_iterator, in_edge_iterator > p; 146 typename graph_traits< G >::vertex_descriptor v; 147 typename graph_traits< G >::edge_descriptor e; 148 typename graph_traits< G >::degree_size_type n; 149 G g; 150 }; 151 152 BOOST_concept(AdjacencyGraph, (G)) : Graph< G > 153 { 154 typedef typename graph_traits< G >::adjacency_iterator adjacency_iterator; 155 typedef typename graph_traits< G >::traversal_category traversal_category; 156 BOOST_CONCEPT_USAGE(AdjacencyGraph)157 BOOST_CONCEPT_USAGE(AdjacencyGraph) 158 { 159 BOOST_CONCEPT_ASSERT((MultiPassInputIterator< adjacency_iterator >)); 160 BOOST_CONCEPT_ASSERT( 161 (Convertible< traversal_category, adjacency_graph_tag >)); 162 163 BOOST_STATIC_ASSERT((boost::mpl::not_< 164 boost::is_same< adjacency_iterator, void > >::value)); 165 166 p = adjacent_vertices(v, g); 167 v = *p.first; 168 const_constraints(g); 169 } const_constraints(const G & cg)170 void const_constraints(const G& cg) { p = adjacent_vertices(v, cg); } 171 std::pair< adjacency_iterator, adjacency_iterator > p; 172 typename graph_traits< G >::vertex_descriptor v; 173 G g; 174 }; 175 176 BOOST_concept(VertexListGraph, (G)) : Graph< G > 177 { 178 typedef typename graph_traits< G >::vertex_iterator vertex_iterator; 179 typedef typename graph_traits< G >::vertices_size_type vertices_size_type; 180 typedef typename graph_traits< G >::traversal_category traversal_category; 181 BOOST_CONCEPT_USAGE(VertexListGraph)182 BOOST_CONCEPT_USAGE(VertexListGraph) 183 { 184 BOOST_CONCEPT_ASSERT((MultiPassInputIterator< vertex_iterator >)); 185 BOOST_CONCEPT_ASSERT( 186 (Convertible< traversal_category, vertex_list_graph_tag >)); 187 188 BOOST_STATIC_ASSERT((boost::mpl::not_< 189 boost::is_same< vertex_iterator, void > >::value)); 190 BOOST_STATIC_ASSERT((boost::mpl::not_< 191 boost::is_same< vertices_size_type, void > >::value)); 192 193 #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK 194 // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if 195 // you want to use vector_as_graph, it is! I'm sure the graph 196 // library leaves these out all over the place. Probably a 197 // redesign involving specializing a template with a static 198 // member function is in order :( 199 using boost::vertices; 200 #endif 201 p = vertices(g); 202 v = *p.first; 203 const_constraints(g); 204 } const_constraints(const G & cg)205 void const_constraints(const G& cg) 206 { 207 #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK 208 // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if 209 // you want to use vector_as_graph, it is! I'm sure the graph 210 // library leaves these out all over the place. Probably a 211 // redesign involving specializing a template with a static 212 // member function is in order :( 213 using boost::vertices; 214 #endif 215 216 p = vertices(cg); 217 v = *p.first; 218 V = num_vertices(cg); 219 } 220 std::pair< vertex_iterator, vertex_iterator > p; 221 typename graph_traits< G >::vertex_descriptor v; 222 G g; 223 vertices_size_type V; 224 }; 225 226 BOOST_concept(EdgeListGraph, (G)) : Graph< G > 227 { 228 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 229 typedef typename graph_traits< G >::edge_iterator edge_iterator; 230 typedef typename graph_traits< G >::edges_size_type edges_size_type; 231 typedef typename graph_traits< G >::traversal_category traversal_category; 232 BOOST_CONCEPT_USAGE(EdgeListGraph)233 BOOST_CONCEPT_USAGE(EdgeListGraph) 234 { 235 BOOST_CONCEPT_ASSERT((MultiPassInputIterator< edge_iterator >)); 236 BOOST_CONCEPT_ASSERT((DefaultConstructible< edge_descriptor >)); 237 BOOST_CONCEPT_ASSERT((EqualityComparable< edge_descriptor >)); 238 BOOST_CONCEPT_ASSERT((Assignable< edge_descriptor >)); 239 BOOST_CONCEPT_ASSERT( 240 (Convertible< traversal_category, edge_list_graph_tag >)); 241 242 BOOST_STATIC_ASSERT( 243 (boost::mpl::not_< boost::is_same< edge_iterator, void > >::value)); 244 BOOST_STATIC_ASSERT((boost::mpl::not_< 245 boost::is_same< edges_size_type, void > >::value)); 246 247 p = edges(g); 248 e = *p.first; 249 u = source(e, g); 250 v = target(e, g); 251 const_constraints(g); 252 } const_constraints(const G & cg)253 void const_constraints(const G& cg) 254 { 255 p = edges(cg); 256 E = num_edges(cg); 257 e = *p.first; 258 u = source(e, cg); 259 v = target(e, cg); 260 } 261 std::pair< edge_iterator, edge_iterator > p; 262 typename graph_traits< G >::vertex_descriptor u, v; 263 typename graph_traits< G >::edge_descriptor e; 264 edges_size_type E; 265 G g; 266 }; 267 268 BOOST_concept(VertexAndEdgeListGraph, (G)) 269 : VertexListGraph< G >, EdgeListGraph< G > {}; 270 271 // Where to put the requirement for this constructor? 272 // G g(n_vertices); 273 // Not in mutable graph, then LEDA graph's can't be models of 274 // MutableGraph. 275 BOOST_concept(EdgeMutableGraph, (G)) 276 { 277 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 278 BOOST_CONCEPT_USAGE(EdgeMutableGraph)279 BOOST_CONCEPT_USAGE(EdgeMutableGraph) 280 { 281 p = add_edge(u, v, g); 282 remove_edge(u, v, g); 283 remove_edge(e, g); 284 clear_vertex(v, g); 285 } 286 G g; 287 edge_descriptor e; 288 std::pair< edge_descriptor, bool > p; 289 typename graph_traits< G >::vertex_descriptor u, v; 290 }; 291 292 BOOST_concept(VertexMutableGraph, (G)) 293 { 294 BOOST_CONCEPT_USAGE(VertexMutableGraph)295 BOOST_CONCEPT_USAGE(VertexMutableGraph) 296 { 297 v = add_vertex(g); 298 remove_vertex(v, g); 299 } 300 G g; 301 typename graph_traits< G >::vertex_descriptor u, v; 302 }; 303 304 BOOST_concept(MutableGraph, (G)) 305 : EdgeMutableGraph< G >, VertexMutableGraph< G > {}; 306 307 template < class edge_descriptor > struct dummy_edge_predicate 308 { operator ()boost::concepts::dummy_edge_predicate309 bool operator()(const edge_descriptor&) const { return false; } 310 }; 311 312 BOOST_concept(MutableIncidenceGraph, (G)) : MutableGraph< G > 313 { BOOST_CONCEPT_USAGE(MutableIncidenceGraph)314 BOOST_CONCEPT_USAGE(MutableIncidenceGraph) 315 { 316 remove_edge(iter, g); 317 remove_out_edge_if(u, p, g); 318 } 319 G g; 320 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 321 dummy_edge_predicate< edge_descriptor > p; 322 typename boost::graph_traits< G >::vertex_descriptor u; 323 typename boost::graph_traits< G >::out_edge_iterator iter; 324 }; 325 326 BOOST_concept(MutableBidirectionalGraph, (G)) : MutableIncidenceGraph< G > 327 { BOOST_CONCEPT_USAGE(MutableBidirectionalGraph)328 BOOST_CONCEPT_USAGE(MutableBidirectionalGraph) 329 { 330 remove_in_edge_if(u, p, g); 331 } 332 G g; 333 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 334 dummy_edge_predicate< edge_descriptor > p; 335 typename boost::graph_traits< G >::vertex_descriptor u; 336 }; 337 338 BOOST_concept(MutableEdgeListGraph, (G)) : EdgeMutableGraph< G > 339 { BOOST_CONCEPT_USAGE(MutableEdgeListGraph)340 BOOST_CONCEPT_USAGE(MutableEdgeListGraph) { remove_edge_if(p, g); } 341 G g; 342 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 343 dummy_edge_predicate< edge_descriptor > p; 344 }; 345 346 BOOST_concept(VertexMutablePropertyGraph, (G)) : VertexMutableGraph< G > 347 { BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph)348 BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) { v = add_vertex(vp, g); } 349 G g; 350 typename graph_traits< G >::vertex_descriptor v; 351 typename vertex_property_type< G >::type vp; 352 }; 353 354 BOOST_concept(EdgeMutablePropertyGraph, (G)) : EdgeMutableGraph< G > 355 { 356 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 357 BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph)358 BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) { p = add_edge(u, v, ep, g); } 359 G g; 360 std::pair< edge_descriptor, bool > p; 361 typename graph_traits< G >::vertex_descriptor u, v; 362 typename edge_property_type< G >::type ep; 363 }; 364 365 BOOST_concept(AdjacencyMatrix, (G)) : Graph< G > 366 { 367 typedef typename graph_traits< G >::edge_descriptor edge_descriptor; 368 BOOST_CONCEPT_USAGE(AdjacencyMatrix)369 BOOST_CONCEPT_USAGE(AdjacencyMatrix) 370 { 371 p = edge(u, v, g); 372 const_constraints(g); 373 } const_constraints(const G & cg)374 void const_constraints(const G& cg) { p = edge(u, v, cg); } 375 typename graph_traits< G >::vertex_descriptor u, v; 376 std::pair< edge_descriptor, bool > p; 377 G g; 378 }; 379 380 BOOST_concept(ReadablePropertyGraph, (G)(X)(Property)) : Graph< G > 381 { 382 typedef typename property_map< G, Property >::const_type const_Map; 383 BOOST_CONCEPT_USAGE(ReadablePropertyGraph)384 BOOST_CONCEPT_USAGE(ReadablePropertyGraph) 385 { 386 BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept< const_Map, X >)); 387 388 const_constraints(g); 389 } const_constraints(const G & cg)390 void const_constraints(const G& cg) 391 { 392 const_Map pmap = get(Property(), cg); 393 pval = get(Property(), cg, x); 394 ignore_unused_variable_warning(pmap); 395 } 396 G g; 397 X x; 398 typename property_traits< const_Map >::value_type pval; 399 }; 400 401 BOOST_concept(PropertyGraph, (G)(X)(Property)) 402 : ReadablePropertyGraph< G, X, Property > 403 { 404 typedef typename property_map< G, Property >::type Map; BOOST_CONCEPT_USAGE(PropertyGraph)405 BOOST_CONCEPT_USAGE(PropertyGraph) 406 { 407 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept< Map, X >)); 408 409 Map pmap = get(Property(), g); 410 pval = get(Property(), g, x); 411 put(Property(), g, x, pval); 412 ignore_unused_variable_warning(pmap); 413 } 414 G g; 415 X x; 416 typename property_traits< Map >::value_type pval; 417 }; 418 419 BOOST_concept(LvaluePropertyGraph, (G)(X)(Property)) 420 : ReadablePropertyGraph< G, X, Property > 421 { 422 typedef typename property_map< G, Property >::type Map; 423 typedef typename property_map< G, Property >::const_type const_Map; 424 BOOST_CONCEPT_USAGE(LvaluePropertyGraph)425 BOOST_CONCEPT_USAGE(LvaluePropertyGraph) 426 { 427 BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept< const_Map, X >)); 428 429 pval = get(Property(), g, x); 430 put(Property(), g, x, pval); 431 } 432 G g; 433 X x; 434 typename property_traits< Map >::value_type pval; 435 }; 436 437 // The *IndexGraph concepts are "semantic" graph concpepts. These can be 438 // applied to describe any graph that has an index map that can be accessed 439 // using the get(*_index, g) method. For example, adjacency lists with 440 // VertexSet == vecS are implicitly models of this concept. 441 // 442 // NOTE: We could require an associated type vertex_index_type, but that 443 // would mean propagating that type name into graph_traits and all of the 444 // other graph implementations. Much easier to simply call it unsigned. 445 446 BOOST_concept(VertexIndexGraph, (Graph)) 447 { BOOST_CONCEPT_USAGE(VertexIndexGraph)448 BOOST_CONCEPT_USAGE(VertexIndexGraph) 449 { 450 typedef typename graph_traits< Graph >::vertex_descriptor Vertex; 451 typedef typename property_map< Graph, vertex_index_t >::type Map; 452 typedef unsigned Index; // This could be Graph::vertex_index_type 453 Map m = get(vertex_index, g); 454 Index x = get(vertex_index, g, Vertex()); 455 ignore_unused_variable_warning(m); 456 ignore_unused_variable_warning(x); 457 458 // This is relaxed 459 renumber_vertex_indices(g); 460 461 const_constraints(g); 462 } const_constraints(const Graph & g_)463 void const_constraints(const Graph& g_) 464 { 465 typedef typename property_map< Graph, vertex_index_t >::const_type Map; 466 Map m = get(vertex_index, g_); 467 ignore_unused_variable_warning(m); 468 } 469 470 private: 471 Graph g; 472 }; 473 474 BOOST_concept(EdgeIndexGraph, (Graph)) 475 { 476 BOOST_CONCEPT_USAGE(EdgeIndexGraph) 477 { 478 typedef typename graph_traits< Graph >::edge_descriptor Edge; 479 typedef typename property_map< Graph, edge_index_t >::type Map; 480 typedef unsigned Index; // This could be Graph::vertex_index_type 481 Map m = get(edge_index, g); 482 Index x = get(edge_index, g, Edge()); 483 ignore_unused_variable_warning(m); 484 ignore_unused_variable_warning(x); 485 486 // This is relaxed 487 renumber_edge_indices(g); 488 489 const_constraints(g); 490 } 491 void const_constraints(const Graph& g_) 492 { 493 typedef typename property_map< Graph, edge_index_t >::const_type Map; 494 Map m = get(edge_index, g_); 495 ignore_unused_variable_warning(m); 496 } 497 498 private: 499 Graph g; 500 }; 501 502 BOOST_concept(ColorValue, (C)) 503 : EqualityComparable< C >, DefaultConstructible< C > 504 { 505 BOOST_CONCEPT_USAGE(ColorValue) 506 { 507 c = color_traits< C >::white(); 508 c = color_traits< C >::gray(); 509 c = color_traits< C >::black(); 510 } 511 C c; 512 }; 513 514 BOOST_concept(BasicMatrix, (M)(I)(V)) 515 { 516 BOOST_CONCEPT_USAGE(BasicMatrix) 517 { 518 V& elt = A[i][j]; 519 const_constraints(A); 520 ignore_unused_variable_warning(elt); 521 } 522 void const_constraints(const M& cA) 523 { 524 const V& elt = cA[i][j]; 525 ignore_unused_variable_warning(elt); 526 } 527 M A; 528 I i, j; 529 }; 530 531 // The following concepts describe aspects of numberic values and measure 532 // functions. We're extending the notion of numeric values to include 533 // emulation for zero and infinity. 534 535 BOOST_concept(NumericValue, (Numeric)) { BOOST_CONCEPT_USAGE(NumericValue) { 536 BOOST_CONCEPT_ASSERT((DefaultConstructible< Numeric >)); 537 BOOST_CONCEPT_ASSERT((CopyConstructible< Numeric >)); 538 numeric_values< Numeric >::zero(); 539 numeric_values< Numeric >::infinity(); 540 } 541 } 542 ; 543 544 BOOST_concept(DegreeMeasure, (Measure)(Graph)) 545 { 546 BOOST_CONCEPT_USAGE(DegreeMeasure) 547 { 548 typedef typename Measure::degree_type Degree; 549 typedef typename Measure::vertex_type Vertex; 550 551 Degree d = m(Vertex(), g); 552 ignore_unused_variable_warning(d); 553 } 554 555 private: 556 Measure m; 557 Graph g; 558 }; 559 560 BOOST_concept(DistanceMeasure, (Measure)(Graph)) 561 { 562 BOOST_CONCEPT_USAGE(DistanceMeasure) 563 { 564 typedef typename Measure::distance_type Distance; 565 typedef typename Measure::result_type Result; 566 Result r = m(Distance(), g); 567 ignore_unused_variable_warning(r); 568 } 569 570 private: 571 Measure m; 572 Graph g; 573 }; 574 575 } /* namespace concepts */ 576 577 using boost::concepts::MultiPassInputIteratorConcept; 578 579 // Graph concepts 580 using boost::concepts::AdjacencyGraphConcept; 581 using boost::concepts::AdjacencyMatrixConcept; 582 using boost::concepts::BidirectionalGraphConcept; 583 using boost::concepts::EdgeIndexGraphConcept; 584 using boost::concepts::EdgeListGraphConcept; 585 using boost::concepts::EdgeMutableGraphConcept; 586 using boost::concepts::EdgeMutablePropertyGraphConcept; 587 using boost::concepts::GraphConcept; 588 using boost::concepts::IncidenceGraphConcept; 589 using boost::concepts::LvaluePropertyGraphConcept; 590 using boost::concepts::MutableBidirectionalGraphConcept; 591 using boost::concepts::MutableEdgeListGraphConcept; 592 using boost::concepts::MutableGraphConcept; 593 using boost::concepts::MutableIncidenceGraphConcept; 594 using boost::concepts::PropertyGraphConcept; 595 using boost::concepts::ReadablePropertyGraphConcept; 596 using boost::concepts::VertexAndEdgeListGraphConcept; 597 using boost::concepts::VertexIndexGraphConcept; 598 using boost::concepts::VertexListGraphConcept; 599 using boost::concepts::VertexMutableGraphConcept; 600 using boost::concepts::VertexMutablePropertyGraphConcept; 601 602 // Utility concepts 603 using boost::concepts::BasicMatrixConcept; 604 using boost::concepts::ColorValueConcept; 605 using boost::concepts::DegreeMeasureConcept; 606 using boost::concepts::DistanceMeasureConcept; 607 using boost::concepts::NumericValueConcept; 608 609 } /* namespace boost */ 610 #include <boost/concept/detail/concept_undef.hpp> 611 612 #endif /* BOOST_GRAPH_CONCEPTS_H */ 613