sl@0: // sl@0: //======================================================================= sl@0: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. sl@0: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: //======================================================================= sl@0: // sl@0: #ifndef BOOST_GRAPH_CONCEPTS_HPP sl@0: #define BOOST_GRAPH_CONCEPTS_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: sl@0: template sl@0: struct MultiPassInputIteratorConcept { sl@0: void constraints() { sl@0: function_requires< InputIteratorConcept >(); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct GraphConcept sl@0: { sl@0: typedef typename graph_traits::vertex_descriptor vertex_descriptor; sl@0: typedef typename graph_traits::directed_category directed_category; sl@0: typedef typename graph_traits::edge_parallel_category sl@0: edge_parallel_category; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< DefaultConstructibleConcept >(); sl@0: function_requires< EqualityComparableConcept >(); sl@0: function_requires< AssignableConcept >(); sl@0: } sl@0: G g; sl@0: }; sl@0: sl@0: template sl@0: struct IncidenceGraphConcept sl@0: { sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: typedef typename graph_traits::out_edge_iterator sl@0: out_edge_iterator; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: function_requires< MultiPassInputIteratorConcept >(); sl@0: function_requires< DefaultConstructibleConcept >(); sl@0: function_requires< EqualityComparableConcept >(); sl@0: function_requires< AssignableConcept >(); sl@0: function_requires< ConvertibleConcept >(); sl@0: sl@0: p = out_edges(u, g); sl@0: n = out_degree(u, g); sl@0: e = *p.first; sl@0: u = source(e, g); sl@0: v = target(e, g); sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: p = out_edges(u, cg); sl@0: n = out_degree(u, cg); sl@0: e = *p.first; sl@0: u = source(e, cg); sl@0: v = target(e, cg); sl@0: } sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: typename graph_traits::edge_descriptor e; sl@0: typename graph_traits::degree_size_type n; sl@0: G g; sl@0: }; sl@0: sl@0: template sl@0: struct BidirectionalGraphConcept sl@0: { sl@0: typedef typename graph_traits::in_edge_iterator sl@0: in_edge_iterator; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< IncidenceGraphConcept >(); sl@0: function_requires< MultiPassInputIteratorConcept >(); sl@0: function_requires< ConvertibleConcept >(); sl@0: sl@0: p = in_edges(v, g); sl@0: n = in_degree(v, g); sl@0: e = *p.first; sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: p = in_edges(v, cg); sl@0: n = in_degree(v, cg); sl@0: e = *p.first; sl@0: } sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor v; sl@0: typename graph_traits::edge_descriptor e; sl@0: typename graph_traits::degree_size_type n; sl@0: G g; sl@0: }; sl@0: sl@0: template sl@0: struct AdjacencyGraphConcept sl@0: { sl@0: typedef typename graph_traits::adjacency_iterator sl@0: adjacency_iterator; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: function_requires< MultiPassInputIteratorConcept >(); sl@0: function_requires< ConvertibleConcept >(); sl@0: sl@0: p = adjacent_vertices(v, g); sl@0: v = *p.first; sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: p = adjacent_vertices(v, cg); sl@0: } sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor v; sl@0: G g; sl@0: }; sl@0: sl@0: // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if sl@0: // you want to use vector_as_graph, it is! I'm sure the graph sl@0: // library leaves these out all over the place. Probably a sl@0: // redesign involving specializing a template with a static sl@0: // member function is in order :( sl@0: // sl@0: // It is needed in order to allow us to write using boost::vertices as sl@0: // needed for ADL when using vector_as_graph below. sl@0: #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \ sl@0: && !BOOST_WORKAROUND(__GNUC__, <= 2) \ sl@0: && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) sl@0: # define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK sl@0: #endif sl@0: sl@0: #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK sl@0: template sl@0: typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); sl@0: #endif sl@0: sl@0: template sl@0: struct VertexListGraphConcept sl@0: { sl@0: typedef typename graph_traits::vertex_iterator vertex_iterator; sl@0: typedef typename graph_traits::vertices_size_type vertices_size_type; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: function_requires< MultiPassInputIteratorConcept >(); sl@0: function_requires< ConvertibleConcept >(); sl@0: sl@0: #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK sl@0: // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if sl@0: // you want to use vector_as_graph, it is! I'm sure the graph sl@0: // library leaves these out all over the place. Probably a sl@0: // redesign involving specializing a template with a static sl@0: // member function is in order :( sl@0: using boost::vertices; sl@0: #endif sl@0: p = vertices(g); sl@0: v = *p.first; sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: #ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK sl@0: // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if sl@0: // you want to use vector_as_graph, it is! I'm sure the graph sl@0: // library leaves these out all over the place. Probably a sl@0: // redesign involving specializing a template with a static sl@0: // member function is in order :( sl@0: using boost::vertices; sl@0: #endif sl@0: sl@0: p = vertices(cg); sl@0: v = *p.first; sl@0: V = num_vertices(cg); sl@0: } sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor v; sl@0: G g; sl@0: vertices_size_type V; sl@0: }; sl@0: sl@0: template sl@0: struct EdgeListGraphConcept sl@0: { sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: typedef typename graph_traits::edge_iterator edge_iterator; sl@0: typedef typename graph_traits::edges_size_type edges_size_type; sl@0: typedef typename graph_traits::traversal_category sl@0: traversal_category; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: function_requires< MultiPassInputIteratorConcept >(); sl@0: function_requires< DefaultConstructibleConcept >(); sl@0: function_requires< EqualityComparableConcept >(); sl@0: function_requires< AssignableConcept >(); sl@0: function_requires< ConvertibleConcept >(); sl@0: sl@0: p = edges(g); sl@0: e = *p.first; sl@0: u = source(e, g); sl@0: v = target(e, g); sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: p = edges(cg); sl@0: E = num_edges(cg); sl@0: e = *p.first; sl@0: u = source(e, cg); sl@0: v = target(e, cg); sl@0: } sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: typename graph_traits::edge_descriptor e; sl@0: edges_size_type E; sl@0: G g; sl@0: }; sl@0: sl@0: template sl@0: struct VertexAndEdgeListGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< VertexListGraphConcept >(); sl@0: function_requires< EdgeListGraphConcept >(); sl@0: } sl@0: }; sl@0: sl@0: // Where to put the requirement for this constructor? sl@0: // G g(n_vertices); sl@0: // Not in mutable graph, then LEDA graph's can't be models of sl@0: // MutableGraph. sl@0: sl@0: template sl@0: struct EdgeMutableGraphConcept sl@0: { sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: void constraints() { sl@0: p = add_edge(u, v, g); sl@0: remove_edge(u, v, g); sl@0: remove_edge(e, g); sl@0: clear_vertex(v, g); sl@0: } sl@0: G g; sl@0: edge_descriptor e; sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: }; sl@0: sl@0: template sl@0: struct VertexMutableGraphConcept sl@0: { sl@0: void constraints() { sl@0: v = add_vertex(g); sl@0: remove_vertex(v, g); sl@0: } sl@0: G g; sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: }; sl@0: sl@0: template sl@0: struct MutableGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< EdgeMutableGraphConcept >(); sl@0: function_requires< VertexMutableGraphConcept >(); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct dummy_edge_predicate { sl@0: bool operator()(const edge_descriptor&) const { sl@0: return false; sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct MutableIncidenceGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< MutableGraphConcept >(); sl@0: remove_edge(iter, g); sl@0: remove_out_edge_if(u, p, g); sl@0: } sl@0: G g; sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: dummy_edge_predicate p; sl@0: typename boost::graph_traits::vertex_descriptor u; sl@0: typename boost::graph_traits::out_edge_iterator iter; sl@0: }; sl@0: sl@0: template sl@0: struct MutableBidirectionalGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< MutableIncidenceGraphConcept >(); sl@0: remove_in_edge_if(u, p, g); sl@0: } sl@0: G g; sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: dummy_edge_predicate p; sl@0: typename boost::graph_traits::vertex_descriptor u; sl@0: }; sl@0: sl@0: template sl@0: struct MutableEdgeListGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< EdgeMutableGraphConcept >(); sl@0: remove_edge_if(p, g); sl@0: } sl@0: G g; sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: dummy_edge_predicate p; sl@0: }; sl@0: sl@0: template sl@0: struct VertexMutablePropertyGraphConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< VertexMutableGraphConcept >(); sl@0: v = add_vertex(vp, g); sl@0: } sl@0: G g; sl@0: typename graph_traits::vertex_descriptor v; sl@0: typename vertex_property::type vp; sl@0: }; sl@0: sl@0: template sl@0: struct EdgeMutablePropertyGraphConcept sl@0: { sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: void constraints() { sl@0: function_requires< EdgeMutableGraphConcept >(); sl@0: p = add_edge(u, v, ep, g); sl@0: } sl@0: G g; sl@0: std::pair p; sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: typename edge_property::type ep; sl@0: }; sl@0: sl@0: template sl@0: struct AdjacencyMatrixConcept sl@0: { sl@0: typedef typename graph_traits::edge_descriptor edge_descriptor; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: sl@0: p = edge(u, v, g); sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: p = edge(u, v, cg); sl@0: } sl@0: typename graph_traits::vertex_descriptor u, v; sl@0: std::pair p; sl@0: G g; sl@0: }; sl@0: sl@0: template sl@0: struct ReadablePropertyGraphConcept sl@0: { sl@0: typedef typename property_map::const_type const_Map; sl@0: void constraints() { sl@0: function_requires< GraphConcept >(); sl@0: function_requires< ReadablePropertyMapConcept >(); sl@0: sl@0: const_constraints(g); sl@0: } sl@0: void const_constraints(const G& cg) { sl@0: const_Map pmap = get(Property(), cg); sl@0: pval = get(Property(), cg, x); sl@0: ignore_unused_variable_warning(pmap); sl@0: } sl@0: G g; sl@0: X x; sl@0: typename property_traits::value_type pval; sl@0: }; sl@0: sl@0: template sl@0: struct PropertyGraphConcept sl@0: { sl@0: typedef typename property_map::type Map; sl@0: void constraints() { sl@0: function_requires< ReadablePropertyGraphConcept >(); sl@0: function_requires< ReadWritePropertyMapConcept >(); sl@0: sl@0: Map pmap = get(Property(), g); sl@0: pval = get(Property(), g, x); sl@0: put(Property(), g, x, pval); sl@0: ignore_unused_variable_warning(pmap); sl@0: } sl@0: G g; sl@0: X x; sl@0: typename property_traits::value_type pval; sl@0: }; sl@0: sl@0: template sl@0: struct LvaluePropertyGraphConcept sl@0: { sl@0: typedef typename property_map::type Map; sl@0: typedef typename property_map::const_type const_Map; sl@0: void constraints() { sl@0: function_requires< ReadablePropertyGraphConcept >(); sl@0: function_requires< LvaluePropertyMapConcept >(); sl@0: sl@0: pval = get(Property(), g, x); sl@0: put(Property(), g, x, pval); sl@0: } sl@0: G g; sl@0: X x; sl@0: typename property_traits::value_type pval; sl@0: }; sl@0: sl@0: // This needs to move out of the graph library sl@0: template sl@0: struct BufferConcept sl@0: { sl@0: void constraints() { sl@0: b.push(t); sl@0: b.pop(); sl@0: typename B::value_type& v = b.top(); sl@0: const_constraints(b); sl@0: ignore_unused_variable_warning(v); sl@0: } sl@0: void const_constraints(const B& cb) { sl@0: const typename B::value_type& v = cb.top(); sl@0: n = cb.size(); sl@0: bool e = cb.empty(); sl@0: ignore_unused_variable_warning(v); sl@0: ignore_unused_variable_warning(e); sl@0: } sl@0: typename B::size_type n; sl@0: typename B::value_type t; sl@0: B b; sl@0: }; sl@0: sl@0: template sl@0: struct ColorValueConcept sl@0: { sl@0: void constraints() { sl@0: function_requires< EqualityComparableConcept >(); sl@0: function_requires< DefaultConstructibleConcept >(); sl@0: sl@0: c = color_traits::white(); sl@0: c = color_traits::gray(); sl@0: c = color_traits::black(); sl@0: } sl@0: C c; sl@0: }; sl@0: sl@0: template sl@0: struct BasicMatrixConcept sl@0: { sl@0: void constraints() { sl@0: V& elt = A[i][j]; sl@0: const_constraints(A); sl@0: ignore_unused_variable_warning(elt); sl@0: } sl@0: void const_constraints(const M& cA) { sl@0: const V& elt = cA[i][j]; sl@0: ignore_unused_variable_warning(elt); sl@0: } sl@0: M A; sl@0: I i, j; sl@0: }; sl@0: sl@0: } // namespace boost sl@0: sl@0: #endif /* BOOST_GRAPH_CONCEPTS_H */