Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions D3128_Algorithms/src/vertex_property_map.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// vertex\_property\_map: per-vertex associative container
// vector for index graphs, unordered\_map for mapped graphs.
template <class G, class T>
using vertex_property_map = conditional_t<
index_vertex_range<G>,
vector<T>,
unordered_map<vertex_id_t<G>, T>>;

// Eager initialization: every vertex pre-populated with init\_value. $\mathcal{O}(V)$.
template <class G, class T>
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 <class G, class T>
constexpr auto make_vertex_property_map(const G& g);

// Test whether a vertex ID has an entry in the map.
template <class Map, class Key>
constexpr bool vertex_property_map_contains(const Map& m, const Key& uid);

// Read with default fallback; no insertion for unordered\_map.
template <class Map, class Key, class T>
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 <class Container>
using vertex_property_map_value_t =
typename detail::vertex_property_map_value_impl<Container>::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 <class M, class G>
concept vertex_property_map_for = requires(M& m, const vertex_id_t<G>& uid) {
{ m[uid] } -> convertible_to<vertex_property_map_value_t<M>>;
};
62 changes: 62 additions & 0 deletions D3128_Algorithms/tex/algorithms.tex
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,68 @@ \subsubsection{Legacy: \tcode{vertex_property_map_for} Concept}
subscriptable containers directly. It is satisfied by \tcode{std::vector<T>} for index graphs
and \tcode{std::unordered\_map<vertex\_id\_t<G>,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<T>} addressed by \tcode{vertex\_id\_t<G>} provides $\mathcal{O}(1)$ access.
\item For mapped graphs, a \tcode{std::unordered\_map<vertex\_id\_t<G>, 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<G, T>} Type Alias}
A conditional type alias that resolves to \tcode{std::vector<T>} when the graph \tcode{G}
satisfies \tcode{index\_vertex\_range<G>}, and to
\tcode{std::unordered\_map<vertex\_id\_t<G>, 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, T>(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<Container>}}
A trait that extracts the per-vertex value type from a \tcode{vertex\_property\_map} container:
\tcode{T} for \tcode{vector<T>}, \tcode{V} for \tcode{unordered\_map<K,V>}.

\subsubsection{\tcode{vertex\_property\_map\_for<M, G>} Concept}
Requires that \tcode{m[uid]} is valid for \tcode{uid} of type \tcode{vertex\_id\_t<G>} and
the result is convertible to \tcode{vertex\_property\_map\_value\_t<M>}.
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
Expand Down
2 changes: 2 additions & 0 deletions D3128_Algorithms/tex/revision.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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}
8 changes: 5 additions & 3 deletions D3130_Container_Interface/tex/container_interface.tex
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ \subsection{Functions}
\tcode{out_edges(g,uid)} & \tcode{out_edge_range_t<G>} & 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<out_edge_range_t<G>>} \\
\tcode{out_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,uid))} if \tcode{sized_range<out_edge_range_t<G>>} \\
(\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<G>} & constant & n/a (requires bidirectional graph) \\
\tcode{in_edges(g,uid)} & \tcode{in_edge_range_t<G>} & constant & \tcode{in\_edges(g,*find\_vertex(g,uid))} \\
Expand Down Expand Up @@ -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<G>} & 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<G>}.\\
& & 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<G>} & constant & mandatory for descriptor-based edges \\
\tcode{source(g,uv)} & \tcode{vertex_t<G>} & constant & \tcode{*(begin(vertices(g)) + source\_id(g,uv))} \\
Expand Down
Loading