@@ -22,15 +22,42 @@ limitations under the License.
2222#include " iterator_concepts.hpp"
2323namespace osp {
2424
25- // directed_graph concept without explicit edges
25+ /* *
26+ * @brief Concept for a directed graph structure in OneStopParallel (OSP).
27+ *
28+ * OneStopParallel is a header-only library where directed graphs serve as the fundamental
29+ * data structure for all scheduling algorithms and other DAG processing algorithms, such as
30+ * coarsening or partitioning. The `is_directed_graph` concept defines the minimal interface
31+ * that a graph type must satisfy to be used within the OSP ecosystem.
32+ *
33+ * A type `T` satisfies `is_directed_graph` if it provides the following API:
34+ *
35+ * - **vertices()**: Returns a range of all vertices in the graph.
36+ * - **num_vertices()**: Returns the total number of vertices as an integral type.
37+ * - **num_edges()**: Returns the total number of edges as an integral type.
38+ * - **parents(v)**: Returns a range of parent vertices for a given vertex `v`.
39+ * - `v` must be of type `vertex_idx_t<T>`.
40+ * - **children(v)**: Returns a range of child vertices for a given vertex `v`.
41+ * - `v` must be of type `vertex_idx_t<T>`.
42+ * - **in_degree(v)**: Returns the number of incoming edges for vertex `v` as an integral type.
43+ * - **out_degree(v)**: Returns the number of outgoing edges for vertex `v` as an integral type.
44+ *
45+ * This concept ensures that any graph implementation passed to OSP algorithms exposes
46+ * the necessary structural information for processing.
47+ *
48+ * This concept encapsulates a classic adjacency list graph structure, allowing efficient
49+ * iteration over the parents and children of any given node.
50+ *
51+ * @tparam T The graph type to check against the concept.
52+ */
2653template <typename T, typename = void >
2754struct is_directed_graph : std::false_type {};
2855
2956template <typename T>
3057struct is_directed_graph <
31- T, std::void_t <typename directed_graph_traits<T>::vertex_idx,
58+ T, std::void_t <typename directed_graph_traits<T>::vertex_idx,
3259 decltype (std::declval<T>().vertices()),
33- decltype(std::declval<T>().num_vertices()),
60+ decltype(std::declval<T>().num_vertices()),
3461 decltype(std::declval<T>().num_edges()),
3562 decltype(std::declval<T>().parents(std::declval<vertex_idx_t <T>>())),
3663 decltype(std::declval<T>().children(std::declval<vertex_idx_t <T>>())),
@@ -43,31 +70,33 @@ struct is_directed_graph<
4370 is_input_range_of<decltype(std::declval<T>().parents(std::declval<vertex_idx_t <T>>())), vertex_idx_t<T>>,
4471 is_input_range_of<decltype(std::declval<T>().children(std::declval<vertex_idx_t <T>>())), vertex_idx_t<T>>,
4572 std::is_integral<decltype(std::declval<T>().in_degree(std::declval<vertex_idx_t <T>>()))>,
46- std::is_integral<decltype(std::declval<T>().out_degree(std::declval<vertex_idx_t <T>>()))>
47- > {};
73+ std::is_integral<decltype(std::declval<T>().out_degree(std::declval<vertex_idx_t <T>>()))>> {};
4874
4975template <typename T>
5076inline constexpr bool is_directed_graph_v = is_directed_graph<T>::value;
5177
78+ /* *
79+ * @brief Concept for an edge list structure.
80+ *
81+ * The `is_edge_list_type` concept exposes the graph structure through access to a list of edges.
82+ * It requires the type `T` to be a range (providing `begin()`, `end()`, and `size()`) where
83+ * the value type contains `source` and `target` members of type `v_type`.
84+ *
85+ * @tparam T The edge list type.
86+ * @tparam v_type The vertex type.
87+ * @tparam e_type The size type (usually integral).
88+ */
5289template <typename T, typename v_type, typename e_type, typename = void >
5390struct is_edge_list_type : std::false_type {};
5491
5592template <typename T, typename v_type, typename e_type>
5693struct is_edge_list_type <
57- T, v_type, e_type, std::void_t <decltype (std::declval<T>().begin()),
58- decltype (std::declval<T>().end()),
59- decltype(std::declval<T>().size()),
60- typename std::iterator_traits<decltype(std::begin(std::declval<T>()))>::value_type,
61- decltype(std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().source),
62- decltype(std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().target)>>
63- // decltype((*(std::declval<T>().begin())).source())>>
64- // decltype(std::declval<*(std::declval<T>().begin())>().target())>>
65- : std::conjunction< std::is_same<decltype(std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().source), v_type>,
66- std::is_same<decltype(std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().target), v_type>,
67- std::is_same<decltype(std::declval<T>().size()), e_type>> {};
94+ T, v_type, e_type, std::void_t <decltype (std::declval<T>().begin()), decltype (std::declval<T>().end()), decltype (std::declval<T>().size()), typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type, decltype (std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().source), decltype (std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().target)>>
95+ : std::conjunction<std::is_same<decltype (std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().source), v_type>,
96+ std::is_same<decltype (std::declval<typename std::iterator_traits<decltype (std::begin(std::declval<T>()))>::value_type>().target), v_type>,
97+ std::is_same<decltype (std::declval<T>().size()), e_type>> {};
6898
6999template <typename T, typename v_type, typename e_type>
70100inline constexpr bool is_edge_list_type_v = is_edge_list_type<T, v_type, e_type>::value;
71101
72-
73102} // namespace osp
0 commit comments