From 2e69f61119e38c760195e20f53c7782fd7a4da63 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Sat, 28 Mar 2026 18:26:09 -0400 Subject: [PATCH 1/2] Improve alias descriptions in container interface table --- D3130_Container_Interface/tex/container_interface.tex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index 5282e31..d1caf0a 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -405,7 +405,8 @@ \subsection{Functions} \tcode{out_edges(g,uid)} & \tcode{out_edge_range_t} & constant & \tcode{out\_edges(g,*find\_vertex(g,uid))} \\ \tcode{out_degree(g,u)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,u))} if \tcode{sized_range>} \\ \tcode{out_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,uid))} if \tcode{sized_range>} \\ - (\tcode{edges}, \tcode{degree} are backward-compatible aliases for \tcode{out\_edges}, \tcode{out\_degree}) & & & \\ + (\tcode{edges(g,u), edges(g,uid)} & & & aliases for \tcode{out\_edges}) \\ + (\tcode{degree(g,u), degree(g,uid)} & & & aliases for \tcode{out\_degree}) \\ \hdashline \tcode{in_edges(g,u)} & \tcode{in_edge_range_t} & constant & n/a (requires bidirectional graph) \\ \tcode{in_edges(g,uid)} & \tcode{in_edge_range_t} & constant & \tcode{in\_edges(g,*find\_vertex(g,uid))} \\ @@ -443,13 +444,14 @@ \subsection{Functions} & & & \tcode{[](uv) \{ return target\_id(g,uv)==vid; \})} \\ \tcode{find_out_edge(g,uid,vid)} & \tcode{out_edge_t} & linear & \tcode{find\_out\_edge(} \\ & & & \hspace{8mm}\tcode{g, *find\_vertex(g,uid), vid)} \\ - (\tcode{find\_vertex\_edge} is a backward-compatible alias for \tcode{find\_out\_edge}) & & & \\ \tcode{contains_out_edge(g,uid,vid)} & \tcode{bool} & constant & \tcode{uid < size(vertices(g))} \\ & & & \tcode{\&\& vid < size(vertices(g))} \\ & & & \hspace{3mm}if \tcode{is_adjacency_matrix_v}.\\ & & linear & \tcode{find\_out\_edge(g,uid,vid)} \\ & & & \tcode{!= end(out\_edges(g,uid))} otherwise. \\ - (\tcode{contains\_edge} is a backward-compatible alias for \tcode{contains\_out\_edge}) & & & \\ + (\tcode{find\_vertex\_edge(g,u,vid)} & & & alias for \tcode{find\_out\_edge}) \\ + (\tcode{find\_vertex\_edge(g,uid,vid)} & & & alias for \tcode{find\_out\_edge}) \\ + (\tcode{contains\_edge(g,uid,vid)} & & & alias for \tcode{contains\_out\_edge}) \\ \hdashline \tcode{source_id(g,uv)} & \tcode{vertex_id_t} & constant & mandatory for descriptor-based edges \\ \tcode{source(g,uv)} & \tcode{vertex_t} & constant & \tcode{*(begin(vertices(g)) + source\_id(g,uv))} \\ From d9f6569cb3e76e9662ea1caea1e546acbf245b28 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 9 Apr 2026 13:18:19 -0400 Subject: [PATCH 2/2] D3128: add vertex_property_map section and revision entry --- D3128_Algorithms/src/vertex_property_map.hpp | 38 ++++++++++++ D3128_Algorithms/tex/algorithms.tex | 62 ++++++++++++++++++++ D3128_Algorithms/tex/revision.tex | 2 + 3 files changed, 102 insertions(+) create mode 100644 D3128_Algorithms/src/vertex_property_map.hpp diff --git a/D3128_Algorithms/src/vertex_property_map.hpp b/D3128_Algorithms/src/vertex_property_map.hpp new file mode 100644 index 0000000..4cf62f3 --- /dev/null +++ b/D3128_Algorithms/src/vertex_property_map.hpp @@ -0,0 +1,38 @@ +// vertex\_property\_map: per-vertex associative container +// vector for index graphs, unordered\_map for mapped graphs. +template +using vertex_property_map = conditional_t< + index_vertex_range, + vector, + unordered_map, T>>; + +// Eager initialization: every vertex pre-populated with init\_value. $\mathcal{O}(V)$. +template +constexpr auto make_vertex_property_map(const G& g, const T& init_value); + +// Lazy initialization: sized for index graphs, empty and reserved for mapped graphs. +template +constexpr auto make_vertex_property_map(const G& g); + +// Test whether a vertex ID has an entry in the map. +template +constexpr bool vertex_property_map_contains(const Map& m, const Key& uid); + +// Read with default fallback; no insertion for unordered\_map. +template +constexpr auto vertex_property_map_get(const Map& m, const Key& uid, + const T& default_val); + +// Extract the per-vertex value type from a vertex\_property\_map container. +// For vector: value\_type. For unordered\_map: mapped\_type. +template +using vertex_property_map_value_t = + typename detail::vertex_property_map_value_impl::type; + +// Concept: container usable as a per-vertex property map for graph G. +// Requires subscript access with the graph's vertex ID type, returning a value +// convertible to the map's value type. +template +concept vertex_property_map_for = requires(M& m, const vertex_id_t& uid) { + { m[uid] } -> convertible_to>; +}; diff --git a/D3128_Algorithms/tex/algorithms.tex b/D3128_Algorithms/tex/algorithms.tex index 39f5c06..6915754 100644 --- a/D3128_Algorithms/tex/algorithms.tex +++ b/D3128_Algorithms/tex/algorithms.tex @@ -234,6 +234,68 @@ \subsubsection{Legacy: \tcode{vertex_property_map_for} Concept} subscriptable containers directly. It is satisfied by \tcode{std::vector} for index graphs and \tcode{std::unordered\_map,T>} for mapped graphs. +\subsection{Vertex Property Map} +Algorithms frequently need per-vertex storage for quantities such as distances, predecessor +IDs, component labels, and visited flags. Because the graph library supports both +\emph{index-based} vertex containers (\tcode{std::vector}, \tcode{std::deque}) and +\emph{key-based} vertex containers (\tcode{std::map}, \tcode{std::unordered\_map}), the +appropriate external container differs: +\begin{itemize} + \item For index graphs, a \tcode{std::vector} addressed by \tcode{vertex\_id\_t} provides $\mathcal{O}(1)$ access. + \item For mapped graphs, a \tcode{std::unordered\_map, T>} is required + because vertex IDs are non-contiguous keys. +\end{itemize} + +The \tcode{vertex\_property\_map} facility provides a uniform abstraction that selects the +correct container automatically and offers factory functions and access helpers so that +algorithms and users need not distinguish between the two cases. + +\subsubsection{Synopsis} +{\small + \lstinputlisting{D3128_Algorithms/src/vertex_property_map.hpp} +} + +\subsubsection{\tcode{vertex\_property\_map} Type Alias} +A conditional type alias that resolves to \tcode{std::vector} when the graph \tcode{G} +satisfies \tcode{index\_vertex\_range}, and to +\tcode{std::unordered\_map, T>} otherwise. + +\subsubsection{\tcode{make\_vertex\_property\_map} Factory Functions} +Two overloads create a \tcode{vertex\_property\_map}: +\begin{itemize} + \item \textbf{Eager initialization} --- + \tcode{make\_vertex\_property\_map(g, init\_value)} pre-populates every vertex with + \tcode{init\_value}. Useful when an algorithm reads all entries before writing + (e.g.\ component labels). $\mathcal{O}(|V|)$. + \item \textbf{Lazy initialization} --- + \tcode{make\_vertex\_property\_map(g)} creates a default-constructed + (index graphs) or empty-but-reserved (mapped graphs) container. + Useful with \tcode{vertex\_property\_map\_get} when absence has a semantic meaning + (e.g.\ infinity for distances, \tcode{false} for visited flags). +\end{itemize} + +\subsubsection{Access Helpers} +\begin{itemize} + \item \tcode{vertex\_property\_map\_contains(m, uid)} --- + Tests whether vertex~\tcode{uid} has an entry. + For \tcode{vector}: \tcode{uid < size(m)}. + For \tcode{unordered\_map}: \tcode{m.contains(uid)}. + \item \tcode{vertex\_property\_map\_get(m, uid, default\_val)} --- + Returns the stored value if present, otherwise returns \tcode{default\_val} + \emph{without insertion}. This avoids accidentally growing an + \tcode{unordered\_map} through \tcode{operator[]}. +\end{itemize} + +\subsubsection{\tcode{vertex\_property\_map\_value\_t}} +A trait that extracts the per-vertex value type from a \tcode{vertex\_property\_map} container: +\tcode{T} for \tcode{vector}, \tcode{V} for \tcode{unordered\_map}. + +\subsubsection{\tcode{vertex\_property\_map\_for} Concept} +Requires that \tcode{m[uid]} is valid for \tcode{uid} of type \tcode{vertex\_id\_t} and +the result is convertible to \tcode{vertex\_property\_map\_value\_t}. +This concept constrains algorithm parameters that accept subscriptable containers directly, +such as \tcode{afforest} and the \tcode{init\_shortest\_paths} helpers. + \subsection{Visitor Concepts and Classes} Visitors are optional member functions on a user-defined class that are called during the execution of an algorithm. Each algorithm has its own set of visitor events that it supports, and each event function must match the visitor concepts diff --git a/D3128_Algorithms/tex/revision.tex b/D3128_Algorithms/tex/revision.tex index cb89d4a..5fdfee8 100644 --- a/D3128_Algorithms/tex/revision.tex +++ b/D3128_Algorithms/tex/revision.tex @@ -78,4 +78,6 @@ \subsection*{\paperno r4} (\tcode{PredecessorFn}, \tcode{DistanceFn}) constrained by new \tcode{predecessor_fn_for} and \tcode{distance_fn_for} concepts, enabling flexible storage strategies for per-vertex properties. Add \tcode{container_value_fn} adaptor and \tcode{_null_predecessor} sentinel for convenience. + \item Add \tcode{vertex_property_map} facility: a type alias, factory functions, access helpers, + a value-type trait, and a concept for uniform per-vertex storage across index and mapped graphs. \end{itemize}