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