Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e0dcc47
Add D3129 views update strategy document
pratzl Mar 12, 2026
22d6b26
views_update_strategy: resolve all Section 5 open questions (Q1–Q7)
pratzl Mar 12, 2026
2071d35
Add views update plan; update strategy Q4 with C++23/C++20 backward c…
pratzl Mar 12, 2026
ac5abdd
Phase A: Rewrite D3129 source files — info structs → data structs
pratzl Mar 12, 2026
1152806
Phase B: Rewrite data structs section — tables, examples, prose
pratzl Mar 12, 2026
6f50537
Phase C: Update graph view sections — data structs, bindings, 2-arg V…
pratzl Mar 13, 2026
2073e75
Apply naming convention: u/uid=source, v/vid=target, uv=edge
pratzl Mar 13, 2026
ce8f76a
Phase D: Update search common types — member functions, search_view c…
pratzl Mar 13, 2026
4ee7cc1
Phase E: Update DFS/BFS views — remove sourced, descriptor-based return
pratzl Mar 13, 2026
8552f76
Phase F: Update topological sort — all-vertex, _safe factories, remov…
pratzl Mar 13, 2026
fb01712
Phase G: Add basic views, in_ variants, transpose, pipe syntax, VVF/E…
pratzl Mar 13, 2026
51b85b0
Phase H: Prose audit — cleanup phil notes, rename all obsolete types
pratzl Mar 13, 2026
81cb596
Phase I: Update revision history and config for D3129r3
pratzl Mar 13, 2026
a3430a4
Phase J: Cross-paper fixups — conventions.tex VVF/EVF, D3126 C++23 note
pratzl Mar 13, 2026
84d4004
Update plan: mark Phase J complete
pratzl Mar 13, 2026
12b5763
Add mapped_algo_strategy.md for D3128 mapped container update
pratzl Mar 13, 2026
69bdb70
Add mapped_algo_plan.md for D3128 mapped container update
pratzl Mar 13, 2026
79c61f2
mapped_algo_plan: fold confirmed decisions, collapse to 4 phases
pratzl Mar 13, 2026
71d31ee
D3128 Phase 1: add vertex_property_map concept section, remove stale …
pratzl Mar 13, 2026
d47c587
D3128 Phase 2: index_adjacency_list -> adjacency_list (BFS, DFS, topo…
pratzl Mar 13, 2026
77c011f
D3128 Phase 3: vertex_property_map_for requires clauses (Dijkstra, Be…
pratzl Mar 13, 2026
d52c66e
D3128 Phase 4: prop-map preconditions, Kosaraju bidir upgrade, mapped…
pratzl Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions D3126_Overview/tex/overview.tex
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ \section{Freestanding}
Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc}
exception.

\section{Language Requirements}
The library targets C++20 as its baseline. The topological sort safe view factories (\tcode{vertices_topological_sort_safe}, \tcode{edges_topological_sort_safe}) use \tcode{std::expected} from C++23. The reference implementation provides backward compatibility to C++20 via an external \tcode{expected} library (e.g., \tcode{tl::expected}), switching to \tcode{std::expected} when C++23 or later is available.

\section{Namespaces}
Graph containers and their views and algorithms are not interchangeable with existing containers and algorithms.
Additionally, there are some domain-specific terms that may clash with existing or future names, such as
Expand Down
23 changes: 12 additions & 11 deletions D3128_Algorithms/src/bellman_shortest_dists.hpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
template <index_adjacency_list G,
random_access_range Distances,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
class Distances,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires is_arithmetic_v<range_value_t<Distances>> && sized_range<Distances> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
G&& g,
const vertex_id_t<G>& source,
Distances& distances,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
27 changes: 14 additions & 13 deletions D3128_Algorithms/src/bellman_shortest_dists_multi.hpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
template <index_adjacency_list G,
input_range Sources,
random_access_range Distances,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
input_range Sources,
class Distances,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<range_value_t<Distances>> && sized_range<Distances> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
G&& g,
const Sources& sources,
Distances& distances,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
29 changes: 15 additions & 14 deletions D3128_Algorithms/src/bellman_shortest_paths.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
template <index_adjacency_list G,
random_access_range Distances,
random_access_range Predecessors,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
class Distances,
class Predecessors,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires is_arithmetic_v<range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, range_value_t<Predecessors>> &&
sized_range<Distances> && sized_range<Predecessors> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
vertex_property_map_for<Predecessors, G> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
G&& g,
const vertex_id_t<G>& source,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
33 changes: 17 additions & 16 deletions D3128_Algorithms/src/bellman_shortest_paths_multi.hpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
template <index_adjacency_list G,
input_range Sources,
random_access_range Distances,
random_access_range Predecessors,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
input_range Sources,
class Distances,
class Predecessors,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, range_value_t<Predecessors>> &&
sized_range<Distances> && sized_range<Predecessors> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
vertex_property_map_for<Predecessors, G> &&
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
G&& g,
const Sources& sources,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
2 changes: 1 addition & 1 deletion D3128_Algorithms/src/breadth_first_search.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
template <index_adjacency_list G, class Visitor = empty_visitor>
template <adjacency_list G, class Visitor = empty_visitor>
void breadth_first_search(
G&& g, // graph
vertex_id_t<G> source, // starting vertex\_id
Expand Down
2 changes: 1 addition & 1 deletion D3128_Algorithms/src/breadth_first_search_multi.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
template <index_adjacency_list G, input_range Sources, class Visitor = empty_visitor>
template <adjacency_list G, input_range Sources, class Visitor = empty_visitor>
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>>
void breadth_first_search(G&& g, // graph
const Sources& sources,
Expand Down
19 changes: 12 additions & 7 deletions D3128_Algorithms/src/connected_components.hpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
/*
* Hopcroft-Tarjan Articulation Points
*/
template <index_adjacency_list G, class Iter>
template <adjacency_list G, class Iter>
requires output_iterator<Iter, vertex_id_t<G>>
void articulation_points(G&& g, Iter cut_vertices);

/*
* Hopcroft-Tarjan Biconnected Components
*/
template <index_adjacency_list G, class OuterContainer>
template <adjacency_list G, class OuterContainer>
void biconnected_components(G&& g, OuterContainer& components);

/*
* Connected Components
*/
template <index_adjacency_list G, random_access_range Component>
template <adjacency_list G, class Component>
requires vertex_property_map_for<Component, G>
size_t connected_components(G&& g, Component& component);

/*
* Afforest Connected Components
*/
template <index_adjacency_list G, random_access_range Component>
template <adjacency_list G, class Component>
requires vertex_property_map_for<Component, G>
void afforest(G&& g, Component& component, const size_t neighbor_rounds = 2);

template <index_adjacency_list G, adjacency_list GT, random_access_range Component>
template <adjacency_list G, adjacency_list GT, class Component>
requires vertex_property_map_for<Component, G>
void afforest(G&& g, GT&& g_t, Component& component, const size_t neighbor_rounds = 2);

/*
* Kosaraju Strongly Connected Components
*/
template <index_adjacency_list G, index_adjacency_list GT, random_access_range Component>
template <adjacency_list G, adjacency_list GT, class Component>
requires vertex_property_map_for<Component, G>
void kosaraju(G&& g, GT&& g_t, Component& component);

template <index_bidirectional_adjacency_list G, random_access_range Component>
template <bidirectional_adjacency_list G, class Component>
requires vertex_property_map_for<Component, G>
void kosaraju(G&& g, Component& component);
2 changes: 1 addition & 1 deletion D3128_Algorithms/src/depth_first_search.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
template <index_adjacency_list G, class Visitor = empty_visitor>
template <adjacency_list G, class Visitor = empty_visitor>
void depth_first_search(
G&& g, // graph
vertex_id_t<G> source, // starting vertex\_id
Expand Down
29 changes: 29 additions & 0 deletions D3128_Algorithms/src/dijkstra_example_mapped.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Example: Dijkstra on a mapped graph (string vertex IDs, double edge weights)

#include <graph/container/dynamic_graph.hpp>
#include <graph/container/traits/uov_graph_traits.hpp>
#include <graph/adj_list/vertex_property_map.hpp>
#include <graph/algorithm/dijkstra_shortest_paths.hpp>
using namespace graph;
using namespace graph::adj_list;

using Traits = container::uov_graph_traits<double, void, void, std::string>;
using G = container::dynamic_graph<double, void, void, std::string, false, Traits>;

G g({{"a", "b", 4.0}, {"a", "c", 2.0},
{"b", "d", 5.0},
{"c", "b", 1.0}, {"c", "d", 8.0}});

constexpr double inf = std::numeric_limits<double>::max();

auto dist = make_vertex_property_map<G, double>(g, inf);
auto pred = make_vertex_property_map<G, vertex_id_t<G>>(g, vertex_id_t<G>{});
for (auto&& [uid, u] : views::vertexlist(g))
pred[uid] = uid;

dijkstra_shortest_paths(g, std::string{"a"}, dist, pred,
[](const auto& g, const edge_t<G>& e) { return edge_value(g, e); });

// Shortest a to d: a to c (2) to b (1) to d (5) = 8
// dist["d"] == 8

23 changes: 12 additions & 11 deletions D3128_Algorithms/src/dijkstra_shortest_dists.hpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
template <index_adjacency_list G,
random_access_range Distances,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
class Distances,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires is_arithmetic_v<range_value_t<Distances>> && sized_range<Distances> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
constexpr void dijkstra_shortest_distances(
G&& g,
const vertex_id_t<G>& source,
Distances& distances,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
27 changes: 14 additions & 13 deletions D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
template <index_adjacency_list G,
input_range Sources,
random_access_range Distances,
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
template <adjacency_list G,
input_range Sources,
class Distances,
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
const edge_t<G>&)>,
class Visitor = empty_visitor,
class Compare = less<range_value_t<Distances>>,
class Combine = plus<range_value_t<Distances>>>
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> && sized_range<Distances> &&
is_arithmetic_v<range_value_t<Distances>> &&
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
class Compare = less<vertex_property_map_value_t<Distances>>,
class Combine = plus<vertex_property_map_value_t<Distances>>>
requires vertex_property_map_for<Distances, G> &&
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
constexpr void dijkstra_shortest_distances(
G&& g,
const Sources& sources,
Distances& distances,
WF&& weight = [](const auto&,
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
Visitor&& visitor = empty_visitor(),
Compare&& compare = less<range_value_t<Distances>>(),
Combine&& combine = plus<range_value_t<Distances>>());
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
Loading
Loading