2 //=======================================================================
3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
6 // Copyright 2009, Andrew Sutton
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 //=======================================================================
13 #ifndef BOOST_GRAPH_CONCEPTS_HPP
14 #define BOOST_GRAPH_CONCEPTS_HPP
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>
29 #include <boost/concept/detail/concept_def.hpp>
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 :(
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
45 #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
47 typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&);
51 BOOST_concept(MultiPassInputIterator,(T)) {
52 BOOST_CONCEPT_USAGE(MultiPassInputIterator) {
53 BOOST_CONCEPT_ASSERT((InputIterator<T>));
57 BOOST_concept(Graph,(G))
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;
65 BOOST_CONCEPT_USAGE(Graph)
67 BOOST_CONCEPT_ASSERT((DefaultConstructible<vertex_descriptor>));
68 BOOST_CONCEPT_ASSERT((EqualityComparable<vertex_descriptor>));
69 BOOST_CONCEPT_ASSERT((Assignable<vertex_descriptor>));
74 BOOST_concept(IncidenceGraph,(G))
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;
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));
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>));
100 void const_constraints(const G& cg) {
101 p = out_edges(u, cg);
102 n = out_degree(u, cg);
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;
114 BOOST_concept(BidirectionalGraph,(G))
117 typedef typename graph_traits<G>::in_edge_iterator
119 typedef typename graph_traits<G>::traversal_category
122 BOOST_CONCEPT_USAGE(BidirectionalGraph) {
123 BOOST_CONCEPT_ASSERT((MultiPassInputIterator<in_edge_iterator>));
124 BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
125 bidirectional_graph_tag>));
127 BOOST_STATIC_ASSERT((boost::mpl::not_<boost::is_same<in_edge_iterator, void> >::value));
133 const_constraints(g);
135 void const_constraints(const G& cg) {
137 n = in_degree(v, cg);
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;
148 BOOST_concept(AdjacencyGraph,(G))
151 typedef typename graph_traits<G>::adjacency_iterator
153 typedef typename graph_traits<G>::traversal_category
156 BOOST_CONCEPT_USAGE(AdjacencyGraph) {
157 BOOST_CONCEPT_ASSERT((MultiPassInputIterator<adjacency_iterator>));
158 BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
159 adjacency_graph_tag>));
161 BOOST_STATIC_ASSERT((boost::mpl::not_<boost::is_same<adjacency_iterator, void> >::value));
163 p = adjacent_vertices(v, g);
165 const_constraints(g);
167 void const_constraints(const G& cg) {
168 p = adjacent_vertices(v, cg);
170 std::pair<adjacency_iterator,adjacency_iterator> p;
171 typename graph_traits<G>::vertex_descriptor v;
175 BOOST_concept(VertexListGraph,(G))
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
183 BOOST_CONCEPT_USAGE(VertexListGraph) {
184 BOOST_CONCEPT_ASSERT((MultiPassInputIterator<vertex_iterator>));
185 BOOST_CONCEPT_ASSERT((Convertible<traversal_category,
186 vertex_list_graph_tag>));
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));
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;
201 const_constraints(g);
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;
215 V = num_vertices(cg);
217 std::pair<vertex_iterator,vertex_iterator> p;
218 typename graph_traits<G>::vertex_descriptor v;
220 vertices_size_type V;
223 BOOST_concept(EdgeListGraph,(G))
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
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>));
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));
247 const_constraints(g);
249 void const_constraints(const G& cg) {
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;
263 BOOST_concept(VertexAndEdgeListGraph,(G))
269 // Where to put the requirement for this constructor?
271 // Not in mutable graph, then LEDA graph's can't be models of
273 BOOST_concept(EdgeMutableGraph,(G))
275 typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
277 BOOST_CONCEPT_USAGE(EdgeMutableGraph) {
278 p = add_edge(u, v, g);
279 remove_edge(u, v, g);
285 std::pair<edge_descriptor, bool> p;
286 typename graph_traits<G>::vertex_descriptor u, v;
289 BOOST_concept(VertexMutableGraph,(G))
292 BOOST_CONCEPT_USAGE(VertexMutableGraph) {
297 typename graph_traits<G>::vertex_descriptor u, v;
300 BOOST_concept(MutableGraph,(G))
301 : EdgeMutableGraph<G>
302 , VertexMutableGraph<G>
306 template <class edge_descriptor>
307 struct dummy_edge_predicate {
308 bool operator()(const edge_descriptor&) const {
313 BOOST_concept(MutableIncidenceGraph,(G))
316 BOOST_CONCEPT_USAGE(MutableIncidenceGraph) {
317 remove_edge(iter, g);
318 remove_out_edge_if(u, p, 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;
327 BOOST_concept(MutableBidirectionalGraph,(G))
328 : MutableIncidenceGraph<G>
330 BOOST_CONCEPT_USAGE(MutableBidirectionalGraph)
332 remove_in_edge_if(u, p, 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;
340 BOOST_concept(MutableEdgeListGraph,(G))
341 : EdgeMutableGraph<G>
343 BOOST_CONCEPT_USAGE(MutableEdgeListGraph) {
344 remove_edge_if(p, g);
347 typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
348 dummy_edge_predicate<edge_descriptor> p;
351 BOOST_concept(VertexMutablePropertyGraph,(G))
352 : VertexMutableGraph<G>
354 BOOST_CONCEPT_USAGE(VertexMutablePropertyGraph) {
355 v = add_vertex(vp, g);
358 typename graph_traits<G>::vertex_descriptor v;
359 typename vertex_property_type<G>::type vp;
362 BOOST_concept(EdgeMutablePropertyGraph,(G))
363 : EdgeMutableGraph<G>
365 typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
367 BOOST_CONCEPT_USAGE(EdgeMutablePropertyGraph) {
368 p = add_edge(u, v, ep, 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;
376 BOOST_concept(AdjacencyMatrix,(G))
379 typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
381 BOOST_CONCEPT_USAGE(AdjacencyMatrix) {
383 const_constraints(g);
385 void const_constraints(const G& cg) {
388 typename graph_traits<G>::vertex_descriptor u, v;
389 std::pair<edge_descriptor, bool> p;
393 BOOST_concept(ReadablePropertyGraph,(G)(X)(Property))
396 typedef typename property_map<G, Property>::const_type const_Map;
398 BOOST_CONCEPT_USAGE(ReadablePropertyGraph)
400 BOOST_CONCEPT_ASSERT((ReadablePropertyMapConcept<const_Map, X>));
402 const_constraints(g);
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);
411 typename property_traits<const_Map>::value_type pval;
414 BOOST_concept(PropertyGraph,(G)(X)(Property))
415 : ReadablePropertyGraph<G, X, Property>
417 typedef typename property_map<G, Property>::type Map;
418 BOOST_CONCEPT_USAGE(PropertyGraph) {
419 BOOST_CONCEPT_ASSERT((ReadWritePropertyMapConcept<Map, X>));
421 Map pmap = get(Property(), g);
422 pval = get(Property(), g, x);
423 put(Property(), g, x, pval);
424 ignore_unused_variable_warning(pmap);
428 typename property_traits<Map>::value_type pval;
431 BOOST_concept(LvaluePropertyGraph,(G)(X)(Property))
432 : ReadablePropertyGraph<G, X, Property>
434 typedef typename property_map<G, Property>::type Map;
435 typedef typename property_map<G, Property>::const_type const_Map;
437 BOOST_CONCEPT_USAGE(LvaluePropertyGraph) {
438 BOOST_CONCEPT_ASSERT((LvaluePropertyMapConcept<const_Map, X>));
440 pval = get(Property(), g, x);
441 put(Property(), g, x, pval);
445 typename property_traits<Map>::value_type pval;
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.
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.
457 BOOST_concept(VertexIndexGraph,(Graph))
459 BOOST_CONCEPT_USAGE(VertexIndexGraph)
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);
470 renumber_vertex_indices(g);
472 const_constraints(g);
474 void const_constraints(const Graph& g_)
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);
484 BOOST_concept(EdgeIndexGraph,(Graph))
486 BOOST_CONCEPT_USAGE(EdgeIndexGraph)
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);
497 renumber_edge_indices(g);
499 const_constraints(g);
501 void const_constraints(const Graph& g_)
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);
511 BOOST_concept(ColorValue,(C))
512 : EqualityComparable<C>
513 , DefaultConstructible<C>
515 BOOST_CONCEPT_USAGE(ColorValue) {
516 c = color_traits<C>::white();
517 c = color_traits<C>::gray();
518 c = color_traits<C>::black();
523 BOOST_concept(BasicMatrix,(M)(I)(V))
525 BOOST_CONCEPT_USAGE(BasicMatrix) {
527 const_constraints(A);
528 ignore_unused_variable_warning(elt);
530 void const_constraints(const M& cA) {
531 const V& elt = cA[i][j];
532 ignore_unused_variable_warning(elt);
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.
542 BOOST_concept(NumericValue,(Numeric))
544 BOOST_CONCEPT_USAGE(NumericValue)
546 BOOST_CONCEPT_ASSERT(( DefaultConstructible<Numeric> ));
547 BOOST_CONCEPT_ASSERT(( CopyConstructible<Numeric> ));
548 numeric_values<Numeric>::zero();
549 numeric_values<Numeric>::infinity();
553 BOOST_concept(DegreeMeasure,(Measure)(Graph))
555 BOOST_CONCEPT_USAGE(DegreeMeasure)
557 typedef typename Measure::degree_type Degree;
558 typedef typename Measure::vertex_type Vertex;
560 Degree d = m(Vertex(), g);
561 ignore_unused_variable_warning(d);
568 BOOST_concept(DistanceMeasure,(Measure)(Graph))
570 BOOST_CONCEPT_USAGE(DistanceMeasure)
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);
582 } /* namespace concepts */
584 using boost::concepts::MultiPassInputIteratorConcept;
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;
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;
617 } /* namespace boost */
618 #include <boost/concept/detail/concept_undef.hpp>
620 #endif /* BOOST_GRAPH_CONCEPTS_H */