Conversation
added 17 commits
April 29, 2026 12:37
… bgl_graph_adapt_goal.md: defines requirements, scope, acceptance criteria\n for adapting BGL graphs to work with graph-v3 views and algorithms\n- bgl_graph_adapt_strategy.md: technical strategy covering CPO adaptation\n surface, iterator wrapping, property bridge, performance, and risks\n- bgl_graph_adapt_plan.md: phased implementation plan (phases 0-9) with\n file-level instructions, code sketches, and verification commands"
- Add placeholder headers: graph_adaptor.hpp, bgl_edge_iterator.hpp, property_bridge.hpp under include/graph/adaptors/bgl/ - Add tests/adaptors/CMakeLists.txt with conditional TEST_BGL_ADAPTOR option and Boost header auto-detection - Add 8 stub test files (SUCCEED() placeholders) for each adaptor phase - Wire tests/adaptors into tests/CMakeLists.txt via add_subdirectory All stub tests pass: graph3_bgl_adaptor_tests 1/1.
Implement bgl_edge_iterator — a thin wrapper that adds iterator_concept to BGL's boost::iterator_facade-based iterators, satisfying std::forward_iterator for C++20 ranges. - Conditional operator-> via requires clause (only when reference is an lvalue reference; adjacency_list returns proxy, CSR returns lvalue) - base() accessor for underlying BGL iterator Tests verify: - static_assert forward_iterator for adjacency_list and CSR wrappers - Reference type preservation from underlying BGL iterators - Runtime iteration matches boost::target() results - subrange of wrapped iterators models forward_range - CSR operator-> returns same address as &*it
Phase 2 — graph_adaptor and core ADL free functions: - graph_adaptor<BGL_Graph>: non-owning wrapper with CTAD - ADL vertices(), num_vertices(), edges() (out_edges CPO), target_id(), source_id() in namespace graph::bgl - graph_bgl_adl namespace with call_* helpers outside namespace graph to avoid CPO objects blocking ADL (C++ [basic.lookup.argdep]/3) Phase 3 — concept satisfaction: - static_assert adjacency_list<adapted_t> and index_adjacency_list<adapted_t> - Runtime vertexlist() smoke test confirms descriptor wiring is correct All 25 assertions in 15 test cases pass.
Implement property_bridge.hpp with three bridge types: - bgl_readable_property_map_fn: wraps any BGL readable property map into a graph-v3 edge_value_function/vertex_value_function callable - bgl_lvalue_property_map_fn: same but static_asserts that get() returns an lvalue reference, enabling write-through for writable property maps - edge_key_extractor: extracts BGL edge_descriptor from graph-v3 edge descriptor via *uv.value() - make_bgl_edge_weight_fn: convenience factory for edge weight maps - vertex_vector_property_fn / make_vertex_id_property_fn: wraps std::vector<T>& into a (const G&, vertex_id_t) -> T& function for Dijkstra distance and predecessor storage Tests verify: - Readable map reads correct weights from BGL bundled properties - Integration with incidence(g, u, evf) view - Lvalue write-through propagates to underlying BGL graph - Vector distance and predecessor storage round-trips correctly - static_assert edge_value_function and basic_edge_weight_function All 34 assertions in 20 test cases pass.
Tests vertexlist, incidence, neighbors, edgelist, and incidence-with-weight views on a directed adjacency_list<vecS,vecS,directedS> wrapped in graph_adaptor.
Two test cases on directed adjacency_list wrapped in graph_adaptor: - CLRS 5-vertex graph (correct shortest paths 0→3:5 via 0→4→3) - 4-vertex sanity-check graph Fixes incorrect expected values for dist[3] and pred[3] that had assumed the 0→2→1→3=9 path rather than the shorter 0→4→3=5 path.
graph_adaptor.hpp: - Add call_in_edges() helpers in graph_bgl_adl namespace - Add in_edges(graph_adaptor<G>, u) ADL functions (mutable + const) constrained on traversal_category convertible to bidirectional_graph_tag (covers both bidirectionalS and undirectedS) test_bgl_bidirectional.cpp: - static_assert bidirectional_adjacency_list<adapted_bidir_t> - static_assert index_bidirectional_adjacency_list<adapted_bidir_t> - static_assert bidirectional_adjacency_list<adapted_undir_t> - in_edges correctness test for bidirectionalS (source/target IDs) - dijkstra on bidirectionalS - in_edges == out_edges degree test for undirectedS - edgelist view on undirectedS (10 directed entries, 5 unique edges) - dijkstra on undirectedS cross-checked against BGL's own dijkstra
Bug fix (affects all graph types): - graph_adaptor.hpp: target_id/source_id now copy *uv.value() into a local variable instead of binding const& to it. CSR's csr_out_edge_iterator dereferences to a reference to its own m_edge member, so uv.value() (a temporary iterator copy) was producing a dangling reference. - property_bridge.hpp: edge_key_extractor::operator() changed from decltype(auto) to auto to likewise avoid returning a dangling reference to a temporary iterator member. test_bgl_csr.cpp: - static_assert index_adjacency_list<adapted_csr_t> - vertexlist view (5 vertices) - incidence view (out-edge target sets for vertices 0 and 2) - edgelist view (all 9 edges, sorted and compared) - dijkstra_shortest_paths with hand-verified CLRS distances - dijkstra cross-check against BGL's own dijkstra_shortest_paths
Implements graph::adaptors::filtered_graph<G, VertexPredicate, EdgePredicate>, a non-owning adaptor that filters vertices and edges during traversal. Design: - filtered_graph delegates begin()/end()/size()/operator[] to the underlying graph so it satisfies forward_range (CPO _has_inner_value_pattern for vertices) - edges(fg, u) ADL function returns subrange<filtering_iterator<...>> with self-contained predicate — avoids std::views::filter iterator dangling issue (filter_view iterators hold a back-pointer to their parent view) - filtering_iterator stores predicate in std::optional with custom copy/move assignment (lambdas are not assignable) to satisfy semiregular constraint - keep_all sentinel predicate accepts everything (zero overhead via [[no_unique_address]]) - filtered_vertices(fg) convenience function for lazy filtered vertex iteration Tests: 5 test cases covering keep_all passthrough, vertex predicate, edge predicate, filtered_vertices, and a Dijkstra placeholder. All 4849 tests pass.
I/O subsystem (include/graph/io/): - dot.hpp: write_dot()/read_dot() with std::format-based auto-labeling - graphml.hpp: write_graphml()/read_graphml() lightweight XML handling - json.hpp: write_json()/read_json() self-contained JGF-inspired format - detail/common.hpp: shared concepts (formattable, has_vertex_value, has_edge_value) - io.hpp: umbrella header Generators (include/graph/generators/): - erdos_renyi, barabasi_albert, grid, path generators - Extracted from benchmark fixtures to public headers Tests: 19 I/O tests + 6 generator tests (4874 total, all passing) Updated bgl_migration_strategy.md to reflect implemented status.
New user guides: - docs/user-guide/generators.md — path, grid, Erdős–Rényi, Barabási–Albert - docs/user-guide/io.md — DOT, GraphML, JSON read/write with examples Updated: - README.md — highlights, feature table, test count (4874) - docs/index.md — added I/O and generators links - docs/getting-started.md — next steps links - docs/status/metrics.md — added generator/IO counts, updated test count - docs/status/implementation_matrix.md — added Generators, I/O sections, updated umbrella headers and namespace tables
New files: - examples/bgl_adaptor_example.cpp — end-to-end Dijkstra on BGL graph - docs/user-guide/bgl-adaptor.md — user guide (quick start, property bridging, supported types, API reference, limitations) Updated: - examples/CMakeLists.txt — conditionally build BGL example - docs/index.md — added BGL adaptor guide link - agents/bgl_migration_strategy.md — Section 12 references library adaptor - agents/bgl_graph_adapt_plan.md — all phases marked complete
- Add bgl_keyed_vertex_iterator adaptor that wraps BGL void* iterators and yields pair<VD, monostate>, satisfying graph-v3's keyed_vertex_type concept so vertex_descriptor_view can be constructed - Alias bgl_vertex_range to a sized std::ranges::subrange over the adaptor - Add has_integral_vertex_id_v trait; vertices() uses if constexpr to return an iota range for vecS or a bgl_vertex_range for non-vecS - Generalize make_vertex_map_property_fn / vertex_map_property_fn to accept any associative container (map, unordered_map, etc.) - Add 11 test cases covering listS and setS: vertex iteration, edges, target_id, source_id, vertex_map_property_fn, and edge weights - Update bgl-adaptor.md: listS/setS now supported; add Non-vecS section with map storage guidance; update Known Limitations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BGL interop improvements