diff --git a/doc/hawick_circuits.html b/doc/hawick_circuits.html index 92eb59958..f44d01ada 100644 --- a/doc/hawick_circuits.html +++ b/doc/hawick_circuits.html @@ -49,6 +49,10 @@

Parameters

For example, if a circuit u -> v -> w -> u exists in the graph, the visitor will be called with a sequence consisting of (u, v, w).

+ + Note that if visitor is a std::reference_wrapper, + it will be unwrapped before the .cycle method being called on it. + This allows passing a visitor that shouldn't be copied.

IN: VertexIndexMap const& vim = get(vertex_index, graph)

diff --git a/include/boost/graph/hawick_circuits.hpp b/include/boost/graph/hawick_circuits.hpp index ba4065492..243801d6d 100644 --- a/include/boost/graph/hawick_circuits.hpp +++ b/include/boost/graph/hawick_circuits.hpp @@ -21,6 +21,7 @@ #include // for boost::tie #include #include +#include // for std::reference_wrapper #include #include // for std::pair #include @@ -89,6 +90,18 @@ namespace hawick_circuits_detail return std::find(boost::begin(c), boost::end(c), v) != boost::end(c); } + template < typename T > + struct unwrap_reference_wrapper { + typedef T type; + }; + +#if __cplusplus >= 201103L + template < typename T > + struct unwrap_reference_wrapper > { + typedef T& type; + }; +#endif + /*! * @internal * Algorithm finding all the cycles starting from a given vertex. @@ -301,8 +314,9 @@ namespace hawick_circuits_detail typedef std::vector< Vertex > Stack; typedef std::vector< std::vector< Vertex > > ClosedMatrix; + typedef typename unwrap_reference_wrapper::type VisitorNoRef; - typedef hawick_circuits_from< Graph, Visitor, VertexIndexMap, Stack, + typedef hawick_circuits_from< Graph, VisitorNoRef, VertexIndexMap, Stack, ClosedMatrix, GetAdjacentVertices > SubAlgorithm; diff --git a/test/hawick_circuits.cpp b/test/hawick_circuits.cpp index d4807939f..8184931d4 100644 --- a/test/hawick_circuits.cpp +++ b/test/hawick_circuits.cpp @@ -6,6 +6,8 @@ #include "cycle_test.hpp" #include +#include +#include #include struct call_hawick_circuits @@ -26,6 +28,20 @@ struct call_hawick_unique_circuits } }; +struct not_copyable +{ + not_copyable() { } + + template < typename Path, typename Graph > + void cycle(Path const&, Graph const&) + { + + } + +private: + not_copyable(not_copyable const&); +}; + int main() { std::cout << "---------hawick_circuits---------\n"; @@ -33,4 +49,24 @@ int main() std::cout << "\n\n---------hawick_unique_circuits---------\n"; cycle_test(call_hawick_unique_circuits()); + + // Make sure we can pass a reference_wrapper to the algorithm. +#if __cplusplus >= 201103L + { + typedef boost::adjacency_list Graph; + typedef std::pair Pair; + Pair edges[3] = { + Pair(0, 1), // a->b + Pair(1, 2), // b->c + Pair(2, 0), // c->a + }; + + Graph G(3); + for (int i = 0; i < 3; ++i) + add_edge(edges[i].first, edges[i].second, G); + + not_copyable visitor; + boost::hawick_circuits(G, std::ref(visitor)); + } +#endif // >= C++11 }