From c660bfc05067a683ff3c8677695abf7247f0395d Mon Sep 17 00:00:00 2001 From: Arnaud Becheler <8360330+Becheler@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:34:28 +0200 Subject: [PATCH 1/2] drop dependency on boost.bimap --- CMakeLists.txt | 1 - build.jam | 1 - .../two_graphs_common_spanning_trees.hpp | 47 +++++++++++++++---- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94b15f0bf..c2ebd1066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,6 @@ target_link_libraries(boost_graph Boost::any Boost::array Boost::assert - Boost::bimap Boost::concept_check Boost::config Boost::container_hash diff --git a/build.jam b/build.jam index fa2b2e5f1..3a9172027 100644 --- a/build.jam +++ b/build.jam @@ -10,7 +10,6 @@ constant boost_dependencies : /boost/any//boost_any /boost/array//boost_array /boost/assert//boost_assert - /boost/bimap//boost_bimap /boost/concept_check//boost_concept_check /boost/config//boost_config /boost/container_hash//boost_container_hash diff --git a/include/boost/graph/two_graphs_common_spanning_trees.hpp b/include/boost/graph/two_graphs_common_spanning_trees.hpp index a41dc84b2..0d3f67d30 100644 --- a/include/boost/graph/two_graphs_common_spanning_trees.hpp +++ b/include/boost/graph/two_graphs_common_spanning_trees.hpp @@ -13,7 +13,6 @@ #include -#include #include #include #include @@ -23,6 +22,8 @@ #include #include #include +#include +#include namespace boost { @@ -123,14 +124,44 @@ namespace detail InLMap mMap; }; + // Position/edge lookup used by the algorithm below. left maps a position + // index to its edge, right maps an edge back to its position. + template < typename Edge > struct index_bimap + { + using value_type = std::pair< std::size_t, Edge >; + + struct left_type + { + std::vector< Edge > store; + // i is a dense position in [0, n), so unchecked access is safe. + const Edge& at(std::size_t i) const { return store[i]; } + } left; + + struct right_type + { + using map_type = std::map< Edge, std::size_t >; + using const_iterator = typename map_type::const_iterator; + map_type store; + std::size_t at(const Edge& e) const { return store.at(e); } + const_iterator find(const Edge& e) const { return store.find(e); } + const_iterator end() const { return store.end(); } + } right; + + void insert(const value_type& v) + { + if (left.store.size() <= v.first) + left.store.resize(v.first + 1); + left.store[v.first] = v.second; + right.store[v.second] = v.first; + } + }; + template < typename Graph, typename Func, typename Seq, typename Map > void rec_two_graphs_common_spanning_trees(const Graph& iG, - bimap< bimaps::set_of< int >, - bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + index_bimap< typename graph_traits< Graph >::edge_descriptor > iG_bimap, Map aiG_inL, Map diG, const Graph& vG, - bimap< bimaps::set_of< int >, - bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + index_bimap< typename graph_traits< Graph >::edge_descriptor > vG_bimap, Map avG_inL, Map dvG, Func func, Seq inL) { @@ -612,10 +643,8 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, if (iG_map.size() != num_edges(iG) || vG_map.size() != num_edges(vG)) return; - typedef bimaps::bimap< bimaps::set_of< int >, - bimaps::set_of< order_value_type > > - bimap_type; - typedef typename bimap_type::value_type bimap_value; + using bimap_type = detail::index_bimap< order_value_type >; + using bimap_value = typename bimap_type::value_type; bimap_type iG_bimap, vG_bimap; for (order_size_type i = 0; i < iG_map.size(); ++i) From baea575607e554f3adebec4e603d2207bc133c2c Mon Sep 17 00:00:00 2001 From: Arnaud Becheler <8360330+Becheler@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:41:26 +0200 Subject: [PATCH 2/2] fix: include jeremy's comments --- .../two_graphs_common_spanning_trees.hpp | 96 +++++++++---------- 1 file changed, 43 insertions(+), 53 deletions(-) diff --git a/include/boost/graph/two_graphs_common_spanning_trees.hpp b/include/boost/graph/two_graphs_common_spanning_trees.hpp index 0d3f67d30..1b5a3d7cc 100644 --- a/include/boost/graph/two_graphs_common_spanning_trees.hpp +++ b/include/boost/graph/two_graphs_common_spanning_trees.hpp @@ -134,7 +134,7 @@ namespace detail { std::vector< Edge > store; // i is a dense position in [0, n), so unchecked access is safe. - const Edge& at(std::size_t i) const { return store[i]; } + const Edge& operator[](std::size_t i) const { return store[i]; } } left; struct right_type @@ -210,11 +210,11 @@ namespace detail seq_size_type m; for (seq_size_type j = 0; j < inL.size() && !found; ++j) { - if (!inL[j] && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) + if (!inL[j] && !get(diG, iG_bimap.left[j]) + && !get(dvG, vG_bimap.left[j])) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -253,8 +253,8 @@ namespace detail iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } } } @@ -265,12 +265,12 @@ namespace detail std::stack< edge_descriptor > iG_buf_copy, vG_buf_copy; for (seq_size_type j = 0; j < inL.size(); ++j) { - if (!inL[j] && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) + if (!inL[j] && !get(diG, iG_bimap.left[j]) + && !get(dvG, vG_bimap.left[j])) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -305,14 +305,14 @@ namespace detail iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); - iG_buf_copy.push(iG_bimap.left.at(j)); - vG_buf_copy.push(vG_bimap.left.at(j)); + put(diG, iG_bimap.left[j], true); + put(dvG, vG_bimap.left[j], true); + iG_buf_copy.push(iG_bimap.left[j]); + vG_buf_copy.push(vG_bimap.left[j]); } - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } } @@ -325,7 +325,7 @@ namespace detail { put(diG, iG_buf_copy.top(), false); put(dvG, - vG_bimap.left.at(iG_bimap.right.at(iG_buf_copy.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf_copy.top())], false); iG_buf_copy.pop(); } @@ -333,17 +333,17 @@ namespace detail { put(dvG, vG_buf_copy.top(), false); put(diG, - iG_bimap.left.at(vG_bimap.right.at(vG_buf_copy.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf_copy.top())], false); vG_buf_copy.pop(); } inL[m] = false; - put(aiG_inL, iG_bimap.left.at(m), false); - put(avG_inL, vG_bimap.left.at(m), false); + put(aiG_inL, iG_bimap.left[m], false); + put(avG_inL, vG_bimap.left[m], false); - put(diG, iG_bimap.left.at(m), true); - put(dvG, vG_bimap.left.at(m), true); + put(diG, iG_bimap.left[m], true); + put(dvG, vG_bimap.left[m], true); std::map< vertex_descriptor, edge_descriptor > tree_map; std::map< vertex_descriptor, vertex_descriptor > pred_map; @@ -413,7 +413,7 @@ namespace detail { put(aiG_inL, iG_buf.top(), true); put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf.top())], true); undirected_dfs( @@ -458,7 +458,7 @@ namespace detail put(aiG_inL, iG_buf.top(), false); put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf.top())], false); } iG_buf.pop(); @@ -469,7 +469,7 @@ namespace detail { put(avG_inL, vG_buf.top(), true); put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf.top())], true); undirected_dfs( @@ -514,7 +514,7 @@ namespace detail put(avG_inL, vG_buf.top(), false); put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf.top())], false); } vG_buf.pop(); @@ -527,10 +527,7 @@ namespace detail { inL[iG_bimap.right.at(iG_buf_copy.top())] = true; put(aiG_inL, iG_buf_copy.top(), true); - put(avG_inL, - vG_bimap.left.at( - iG_bimap.right.at(iG_buf_copy.top())), - true); + put(avG_inL, vG_bimap.left[ iG_bimap.right.at(iG_buf_copy.top())], true); iG_buf.push(iG_buf_copy.top()); iG_buf_copy.pop(); } @@ -538,10 +535,7 @@ namespace detail { inL[vG_bimap.right.at(vG_buf_copy.top())] = true; put(avG_inL, vG_buf_copy.top(), true); - put(aiG_inL, - iG_bimap.left.at( - vG_bimap.right.at(vG_buf_copy.top())), - true); + put(aiG_inL, iG_bimap.left[ vG_bimap.right.at(vG_buf_copy.top())], true); vG_buf.push(vG_buf_copy.top()); vG_buf_copy.pop(); } @@ -555,24 +549,20 @@ namespace detail { inL[iG_bimap.right.at(iG_buf.top())] = false; put(aiG_inL, iG_buf.top(), false); - put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), - false); + put(avG_inL, vG_bimap.left[iG_bimap.right.at(iG_buf.top())], false); iG_buf.pop(); } while (!vG_buf.empty()) { inL[vG_bimap.right.at(vG_buf.top())] = false; put(avG_inL, vG_buf.top(), false); - put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), - false); + put(aiG_inL, iG_bimap.left[vG_bimap.right.at(vG_buf.top())], false); vG_buf.pop(); } } - put(diG, iG_bimap.left.at(m), false); - put(dvG, vG_bimap.left.at(m), false); + put(diG, iG_bimap.left[m], false); + put(dvG, vG_bimap.left[m], false); } } } @@ -727,13 +717,13 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, { if (inL[i]) { - put(aiG_inL, iG_bimap.left.at(i), true); - put(avG_inL, vG_bimap.left.at(i), true); + put(aiG_inL, iG_bimap.left[i], true); + put(avG_inL, vG_bimap.left[i], true); } else { - put(aiG_inL, iG_bimap.left.at(i), false); - put(avG_inL, vG_bimap.left.at(i), false); + put(aiG_inL, iG_bimap.left[i], false); + put(avG_inL, vG_bimap.left[i], false); } } @@ -780,8 +770,8 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, { if (!inL[j]) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -816,12 +806,12 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); + put(diG, iG_bimap.left[j], true); + put(dvG, vG_bimap.left[j], true); } - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } }