You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* docs: document index-only vertex descriptor aliases and constraints
- vertex-patterns.md: add index_only_vertex/container_backed_vertex to
Foundation Concepts table; add note to Storage Concepts about
direct_vertex_type covering both container and index-only iterators;
add requires notes to inner_value/underlying_value in Member Functions;
add new Index-Only Aliases section with usage example
- concepts.md: add index_only_vertex and container_backed_vertex to
Descriptor Concepts table
- archive/descriptor.md: add index-only iterator category to vertex
descriptor spec
* refactor: remove index storage path from edge_descriptor; simplify vertices(g)
edge_descriptor always stores EdgeIter directly — edges always have
physical containers, so the conditional_t<random_access_iterator<EdgeIter>,
size_t, EdgeIter> dual-storage path was unnecessary overhead. This
eliminates 38 if constexpr branches across 6 files (~380 lines removed).
compressed_graph: vertices(g) now returns iota_view<size_t,size_t>(0, n),
which the vertices CPO wraps automatically via _wrap_if_needed. The
empty-graph special case is no longer needed.
vertex_descriptor_view: CTAD deduction guides updated to use
std::ranges::iterator_t<> so they work with views (e.g. iota_view)
that lack Container::iterator/const_iterator nested types.
edge_descriptor_view: Fixed forward_list compatibility — removed spurious
sized_range constraint from container constructor, changed if to
if constexpr so std::ranges::size() is not compiled for non-sized ranges.
Tests: Rewrote test_edge_descriptor.cpp and test_descriptor_traits.cpp
for iterator-based storage. Updated test_compressed_graph_cpo.cpp (21
call sites replaced). Fixed pre-existing ODR violation in
test_source_id_cpo.cpp (namespace rename to avoid CustomEdge collision).
Fixed test_edge_value_cpo.cpp custom graph structs to dereference
iterators. Fixed unused vertex_data parameters.
* docs: update documentation for edge_descriptor iterator-only storage
- CHANGELOG: add entries for edge_descriptor simplification, vertices(g)
iota_view, CTAD guide update, and edge_descriptor_view forward_list fix
- vertex-patterns.md: CTAD guides now show std::ranges::iterator_t<>
- adjacency-list-interface.md: edge_descriptor wraps iterator (not index)
- edge-value-concepts.md: target_id() always dereferences stored iterator
- adjacency-lists.md: fix edge_descriptor template parameter names
- archive/descriptor.md: spec updated for iterator-only edge storage
- bgl2_comparison_result.md: updated code sample and size comparison
- archive/edge_map_analysis.md: updated code sample
* Update BGL2 comparison query and results with expanded selectors, design features, and algorithm inventory
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,6 +15,10 @@
15
15
- 456 new algorithm tests for sparse graph types (4343 → 4799)
16
16
17
17
### Changed
18
+
-**`edge_descriptor` simplified to iterator-only storage** — removed the `conditional_t<random_access_iterator, size_t, EdgeIter>` dual-storage path; edges always store the iterator directly since edges always have physical containers. Eliminates 38 `if constexpr` branches across 6 files (~500 lines removed).
19
+
-**`compressed_graph::vertices(g)` returns `iota_view`** — simplified to `std::ranges::iota_view<size_t, size_t>(0, num_vertices())`, which the `vertices` CPO wraps automatically via `_wrap_if_needed`.
20
+
-**`vertex_descriptor_view` CTAD deduction guides** — updated from `Container::iterator`/`const_iterator` to `std::ranges::iterator_t<>` for compatibility with views like `iota_view`.
21
+
-**`edge_descriptor_view` forward_list compatibility** — fixed constructor to use `if constexpr` for `sized_range` check so `std::ranges::size()` is not compiled for non-sized ranges like `forward_list`.
18
22
- All algorithms relaxed from `index_adjacency_list<G>` to `adjacency_list<G>`
19
23
- Algorithm internal arrays use `make_vertex_property_map` (vector or unordered_map depending on graph type)
> **Note on "map" selectors:** Despite having "map" in their names, `mapS`/`multimapS`/`hash_mapS`/`hash_multimapS` all map to **set** containers (not `std::map`). The "map" name reflects the vertex→edge *mapping semantic*, not the container type. The uniqueness/ordering behavior of the underlying set provides the desired parallel-edge control.
22
24
23
25
The `adjacency_list.hpp` provides implementations for:
24
26
-**Vertex list selectors:**`vecS` (index-based), `listS` (iterator-based), `setS` (iterator-based)
25
27
-**Out-edge list selectors:** All 10 selectors work for edge containers
-`algorithm_params.hpp` / `algorithm_result.hpp` — named parameter structs (C++20 designated initializers) and rich result types (e.g., `dijkstra_result` with `path_to()`, `is_reachable()`)
44
+
-`visitor_callbacks.hpp` — 9-event BFS/DFS callback structs with `null_callback` defaults and single-event wrappers
45
+
-`composable_algorithms.hpp` — range adaptors: `find_components()`, `find_distances_from()`, `find_k_core()`, `find_neighbors()`, `find_common_neighbors()`, `degree_distribution()`
**Graph-v3 Key Design Features (for comparison context):**
51
+
- Concept-based CPO design — any type satisfying graph concepts works with algorithms (no adaptor class needed). A `vector<vector<int>>` or user-defined container works directly.
- 3 graph containers: `dynamic_graph` (mutable adjacency list), `compressed_graph` (CSR), `undirected_adjacency_list` (dual-list with O(1) edge removal from both endpoints)
54
+
-`edge_list` module — standalone edge list support for `pair<T,T>`, `tuple<T,T,EV,...>`, and `edge_data` structs
55
+
- Edge descriptors always store the edge iterator directly (no conditional `size_t`/iterator storage)
56
+
- Vertex descriptors use `size_t` for index-based graphs, iterator otherwise
57
+
- 13 view headers — lazy range adaptors including traversal views (`vertices_dfs()`, `edges_bfs()`, `vertices_topological_sort()`) and pipe syntax (`g | vertexlist() | ...`)
58
+
-`dynamic_graph` mutations are batch-oriented (`load_edges()`, `load_vertices()`) — no individual `add_vertex()` / `remove_vertex()` / `add_edge()` / `remove_edge()`
59
+
-`vertex_property_map<G, T>` — `vector<T>` for index graphs, `unordered_map<VId, T>` for mapped graphs, with `container_value_fn()` wrapping for algorithm compatibility
60
+
- Visitor-based algorithms: BFS/DFS support `on_discover_vertex`, `on_examine_edge`, `on_tree_edge`, `on_back_edge`, etc.
0 commit comments