Repository navigation
feature: add support for stateful visitors for DFS - #614
Conversation
|
Boost dependency footprint vs Header-inclusion weights (graph files pulling each direct dependency in): No header-inclusion-weight changes. Transitive Boost modules: 47 → 47 (0) |
|
Compiler-warning counts vs
|
4b1d53b to
6a3dfb8
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! 🚀 New features to boost your workflow:
|
9e74c43 to
b4df0b2
Compare
|
@andreacassioli what do you think about this PR ? Don't hesitate to give a review, I'm mostly trying to assess if it's a good way to enable stateful visitors through std::reference_wrappers ? |
mborland
left a comment
There was a problem hiding this comment.
Looks generally good to me. I think it would also be beneficial to add this new support to the DFS docs since it looks like the stateful visitor needs to be of a specific form like in your tests:
struct finish_edge_tally : boost::dfs_visitor<>
{
template < class Edge, class Graph > void finish_edge(Edge, Graph&)
{
++count;
}
std::size_t count = 0;
};| { | ||
| using type = Visitor; | ||
| }; | ||
|
|
There was a problem hiding this comment.
Something I like to do is add at C++14 style helper:
template <class Visitor>
using unwrap_visitor_t = typename unwrap_visitor<Visitor>::typethat way at the call sites below instead of having:
using visitor_type
= typename ::boost::graph::detail::unwrap_visitor< DFSVisitor >::type;you have instead
using visitor_type = detail::unwrap_visitor_t<DFSVisitor>;I find this to be more readable.
You can also do C++17 style helpers if you allow template variables (C++14)
template <typename T>
constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::valueThere was a problem hiding this comment.
yes on all counts !
I avoided touching the documentation for now, as it's basically a design change and I wanted to keep the PR minimal to simplify review ! 🙏🏽 Thanks a lot Matt !
|
@Becheler it is a nice extension, and pretty neat. I like that it is explicit. Few times I have been fooled thinking that the visitor was passed by reference! |
|
@andreacassioli I was not aware of #307, thanks! It shows the problem well: the docs of BGL mixes conventions, so we need to pick one. There are 3 main designs for stateful visitors:
|
b4df0b2 to
a35beb2
Compare
|
An automated preview of the documentation is available at https://614.graph.prtest3.cppalliance.org/libs/graph/doc/html/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-10-08 10:24:30 UTC |
a35beb2 to
f526341
Compare
Before submitting
developbranch.Type of change
Does this PR introduce a breaking change?
What this PR does
Brings a trait to unwrap visitors that are passed by copy to algorithms internals, so they can carry state if the caller passed a reference wrapper.
Motivation
Stateful visitors has been a complaint for a while. Capturing state in the visitor as reference/pointers members works but violates guidelines and tooling complains.
There are 3 main designs for stateful visitors. BGL mixes conventions, so we need to pick one.
make_dfs_visitor(...).bellman_ford_shortest_pathsalready returns abool. In the STL onlystd::for_eachdoes this, because getting the visitor back is essentially its only purpose.std::reference_wrapper. Default behavior is unchanged (non breaking, temporaries still work), sharing state is an explicit opt in at the call site (std::ref(vis)), and internal copies only copy the wrapper, so state can't be lost. It's the same idiom asstd::thread,std::bindandstd::make_tuple, and it avoids reference members in visitors, which tooling flags.Testing
Checklist
b2in thetest/directory).