2
0
mirror of https://github.com/boostorg/graph.git synced 2026-01-19 04:12:11 +00:00

[hawick] Support passing std::reference_wrapper to boost::hawick_circuits

Reported as ldionne/hawick_circuits#1.
This commit is contained in:
Louis Dionne
2021-04-14 16:19:14 -04:00
parent 0c9dbd7808
commit e63940fea1
3 changed files with 55 additions and 1 deletions

View File

@@ -49,6 +49,10 @@ edges are not desired.</p>
<p>For example, if a circuit <code>u -&gt; v -&gt; w -&gt; u</code> exists in the graph, the
visitor will be called with a sequence consisting of <code>(u, v, w)</code>.</p>
Note that if <code>visitor</code> is a <code>std::reference_wrapper</code>,
it will be unwrapped before the <code>.cycle</code> method being called on it.
This allows passing a visitor that shouldn't be copied.
</blockquote>
<p><strong>IN:</strong> <code>VertexIndexMap const&amp; vim = get(vertex_index, graph)</code></p>

View File

@@ -21,6 +21,7 @@
#include <boost/tuple/tuple.hpp> // for boost::tie
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/result_of.hpp>
#include <functional> // for std::reference_wrapper
#include <set>
#include <utility> // for std::pair
#include <vector>
@@ -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<std::reference_wrapper<T> > {
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<Visitor>::type VisitorNoRef;
typedef hawick_circuits_from< Graph, Visitor, VertexIndexMap, Stack,
typedef hawick_circuits_from< Graph, VisitorNoRef, VertexIndexMap, Stack,
ClosedMatrix, GetAdjacentVertices >
SubAlgorithm;

View File

@@ -6,6 +6,8 @@
#include "cycle_test.hpp"
#include <boost/graph/hawick_circuits.hpp>
#include <cstddef>
#include <functional>
#include <iostream>
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<boost::vecS, boost::vecS, boost::directedS> Graph;
typedef std::pair<std::size_t, std::size_t> 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
}