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
a651c3b
agents: archive completed planning documents
pratzl Mar 1, 2026
63b2538
refactor: simplify index_vertex_range, add underlying_iterator alias …
pratzl Mar 1, 2026
24c7d68
Merge branch 'main' into mapped
pratzl Mar 1, 2026
0ed22f4
docs: add map-based container strategy and implementation plan
pratzl Mar 1, 2026
afd3132
chore: snapshot index-only algorithm implementations for reference
pratzl Mar 1, 2026
82f5a5f
feat: add mapped_adjacency_list concepts and vertex_map infrastructure
pratzl Mar 1, 2026
db03d8f
refactor: rename vertex_map to vertex_property_map, add vertex_proper…
pratzl Mar 1, 2026
0367f4d
feat: generalize BFS, DFS, topological_sort for mapped graphs
pratzl Mar 1, 2026
77c1a07
feat: generalize init_shortest_paths for mapped graphs
pratzl Mar 1, 2026
9798f6d
feat: generalize bellman_ford for mapped graphs
pratzl Mar 1, 2026
b63e2b5
perf: use vertex descriptors in component and Dijkstra algorithms
pratzl Mar 3, 2026
d088ba7
docs: update map_container_plan.md — Phase 5 + descriptor optimizatio…
pratzl Mar 3, 2026
a963262
feat: generalize jaccard, mis, triangle_count, label_propagation for …
pratzl Mar 3, 2026
023df90
docs: mark Phase 6 complete in map_container_plan.md
pratzl Mar 3, 2026
6e115c7
feat: generalize articulation_points, biconnected_components for mapp…
pratzl Mar 4, 2026
7a0c315
feat: generalize prim MST for mapped graphs
pratzl Mar 4, 2026
79bfd48
chore: update docs for mapped graph algorithm support
pratzl Mar 5, 2026
6f2034a
docs: update algorithm docs for adjacency_list + vertex_property_map
pratzl Mar 5, 2026
a42112f
refactor: remove legacy init_shortest_paths overloads, require graph …
pratzl Mar 5, 2026
a5f86c9
Add uniform property access goal and strategy docs
pratzl Mar 8, 2026
ae4910c
Relax edge<G,E> concept — drop is_edge_descriptor_v gate (Q3)
pratzl Mar 12, 2026
2a21479
Merge remote-tracking branch 'origin/main' into mapped
pratzl Mar 12, 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
37 changes: 18 additions & 19 deletions include/graph/adj_list/adjacency_list_concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,33 @@ namespace graph::adj_list {
// =============================================================================

/**
* @brief Concept for edge descriptors
*
* An edge is an edge descriptor that provides access to both source and target vertices.
* All edge descriptors in the graph library provide these operations.
*
* @brief Concept for edge types
*
* An edge is any type for which source_id(g, e) and target_id(g, e) are valid expressions.
* This includes adj_list edge_descriptors, edge_list descriptors, edge_data aggregates,
* tuple/pair representations, and any user-defined type with appropriate CPO support.
*
* Requirements:
* - e must be an edge_descriptor
* - source_id(g, e) must be valid (returns source vertex ID)
* - source(g, e) must be valid (returns source vertex descriptor)
* - target_id(g, e) must be valid (returns target vertex ID)
* - target(g, e) must be valid (returns target vertex descriptor)
*
*
* Note: Return types are not constrained to allow better compiler error messages.
*
* Algorithms that additionally need vertex descriptors (source(g,e) / target(g,e))
* should add those requirements explicitly beyond this concept.
*
* Examples:
* - Edge in adjacency list: edge_descriptor<vector<vector<int>>::iterator, int>
* - Edge in edge list: edge_descriptor<vector<tuple<int, int, double>>::iterator>
* - Weighted edge: edge_descriptor with value access
*
* @tparam G Graph type
* @tparam E Edge type (must be edge_descriptor)
* - adj_list edge_descriptor<EdgeIter, VertexIter, EdgeDirection>
* - edge_list edge_descriptor<VId, EV>
* - edge_data<VId, true, void, EV>
* - std::tuple<int, int, double> (source=get<0>, target=get<1>)
*
* @tparam G Graph (or edge-list container) type
* @tparam E Edge type
*/
template <class G, class E>
concept edge = is_edge_descriptor_v<std::remove_cvref_t<E>> && requires(G& g, const E& e) {
concept edge = requires(G& g, const E& e) {
source_id(g, e);
source(g, e);
target_id(g, e);
target(g, e);
};

// =============================================================================
Expand Down
28 changes: 28 additions & 0 deletions tests/edge_list/test_edge_list_concepts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <graph/edge_list/edge_list.hpp>
#include <graph/edge_list/edge_list_descriptor.hpp>
#include <graph/graph_data.hpp>
#include <graph/adj_list/adjacency_list_concepts.hpp>
#include <vector>
#include <tuple>

Expand Down Expand Up @@ -158,3 +159,30 @@ TEST_CASE("has_edge_value runtime behavior", "[edge_list][runtime]") {
auto val = graph::edge_value(edges, e);
REQUIRE(val == 3.14);
}

// =============================================================================
// Interop with adj_list::edge<G,E> concept (I.2)
// =============================================================================

TEST_CASE("edge_list types satisfy adj_list::edge concept", "[edge_list][concepts][interop]") {
// After dropping the is_edge_descriptor_v gate, any type whose elements
// support source_id(g,e) and target_id(g,e) satisfies edge<G,E>.

// tuple<source, target, value>
using tuple_el = std::vector<std::tuple<int, int, double>>;
STATIC_REQUIRE(adj_list::edge<tuple_el, std::tuple<int, int, double>>);

// pair<source, target>
using pair_el = std::vector<std::pair<int, int>>;
STATIC_REQUIRE(adj_list::edge<pair_el, std::pair<int, int>>);

// edge_data with value
using ed_type = graph::edge_data<int, true, void, double>;
using ed_el = std::vector<ed_type>;
STATIC_REQUIRE(adj_list::edge<ed_el, ed_type>);

// edge_list::edge_descriptor
using desc_type = edge_list::edge_descriptor<int, double>;
using desc_el = std::vector<desc_type>;
STATIC_REQUIRE(adj_list::edge<desc_el, desc_type>);
}
Loading