diff --git a/include/osp/concepts/computational_dag_concept.hpp b/include/osp/concepts/computational_dag_concept.hpp index b5499196..546b6467 100644 --- a/include/osp/concepts/computational_dag_concept.hpp +++ b/include/osp/concepts/computational_dag_concept.hpp @@ -22,9 +22,36 @@ limitations under the License. #include "directed_graph_edge_desc_concept.hpp" +/** + * @file computational_dag_concept.hpp + * @brief Concepts for Computational Directed Acyclic Graphs (cDAGs). + * + * This file defines concepts that validate whether a graph type satisfies the requirements + * of a computational DAG. + * + * A Computational DAG combines: + * - The `directed_graph_concept`. + * - Mandatory vertex weights: work, communication, and memory. + * + * Optional extensions include: + * - Vertex types (for heterogeneous systems). + * - Edge weights (communication). + * + * A computational DAG serves as an input to scheduling algorithms. + */ + namespace osp { -// weighted vertices +/** + * @brief Concept to check if a graph has vertex weights. + * + * Requires validation of: + * - `vertex_work_weight(v)`: Returns arithmetic type. + * - `vertex_comm_weight(v)`: Returns arithmetic type. + * - `vertex_mem_weight(v)`: Returns arithmetic type. + * + * @tparam T The graph type. + */ template struct has_vertex_weights : std::false_type {}; @@ -41,7 +68,18 @@ struct has_vertex_weights inline constexpr bool has_vertex_weights_v = has_vertex_weights::value; -// typed vertices concept +/** + * @brief Concept to check if a graph has typed vertices. + * + * Requires validation of: + * - `vertex_type(v)`: Returns an integral type representing the type of vertex `v`. + * - `num_vertex_types()`: Returns the total number of distinct vertex types. + * + * This is useful for scheduling on heterogeneous resources where tasks (vertices) + * may be compatible only with certain processor types. + * + * @tparam T The graph type. + */ template struct has_typed_vertices : std::false_type {}; @@ -54,7 +92,15 @@ struct has_typed_vertices().vertex_type( template inline constexpr bool has_typed_vertices_v = has_typed_vertices::value; -// weighted edges concept +/** + * @brief Concept to check if edges have communication weights. + * + * Requires: + * - The graph must satisfy `is_directed_graph_edge_desc` (supports edge descriptors). + * - `edge_comm_weight(e)`: Returns an arithmetic type for a given edge descriptor `e`. + * + * @tparam T The graph type. + */ template struct has_edge_weights : std::false_type {}; @@ -69,7 +115,15 @@ struct has_edge_weights inline constexpr bool has_edge_weights_v = has_edge_weights::value; -// computational dag concept without explicit edges +/** + * @brief Concept for a basic computational DAG. + * + * A computational DAG must: + * - Be a directed graph (`is_directed_graph`). + * - Have mandatory vertex weights (`has_vertex_weights`): work, communication, and memory. + * + * @tparam T The graph type. + */ template struct is_computational_dag : std::false_type {}; @@ -79,8 +133,13 @@ struct is_computational_dag> : std::conjunction inline constexpr bool is_computational_dag_v = is_computational_dag::value; - -// computational dag with typed vertices concept +/** + * @brief Concept for a computational DAG with typed vertices. + * + * Extends `is_computational_dag` by also requiring `has_typed_vertices`. + * + * @tparam T The graph type. + */ template struct is_computational_dag_typed_vertices : std::false_type {}; @@ -91,9 +150,14 @@ struct is_computational_dag_typed_vertices> template inline constexpr bool is_computational_dag_typed_vertices_v = is_computational_dag_typed_vertices::value; - - -// computational dag with explicit edges concept +/** + * @brief Concept for a computational DAG that supports explicit edge descriptors. + * + * Extends `is_computational_dag` by requiring `is_directed_graph_edge_desc`, + * allowing iteration over edges using explicit descriptors. + * + * @tparam T The graph type. + */ template struct is_computational_dag_edge_desc : std::false_type {}; @@ -104,7 +168,13 @@ struct is_computational_dag_edge_desc> template inline constexpr bool is_computational_dag_edge_desc_v = is_computational_dag_edge_desc::value; -// computational_dag_typed_vertices_edge_idx concept +/** + * @brief Concept for a computational DAG with both typed vertices and edge descriptors. + * + * Combines `is_directed_graph_edge_desc` and `is_computational_dag_typed_vertices`. + * + * @tparam T The graph type. + */ template struct is_computational_dag_typed_vertices_edge_desc : std::false_type {}; diff --git a/include/osp/concepts/constructable_computational_dag_concept.hpp b/include/osp/concepts/constructable_computational_dag_concept.hpp index 2748630e..26e5a4a9 100644 --- a/include/osp/concepts/constructable_computational_dag_concept.hpp +++ b/include/osp/concepts/constructable_computational_dag_concept.hpp @@ -22,10 +22,32 @@ limitations under the License. #include "computational_dag_concept.hpp" +/** + * @file constructable_computational_dag_concept.hpp + * @brief Concepts for Constructable and Modifiable Computational DAGs. + * + * This file defines concepts that validate whether a graph type supports dynamic construction + * and modification of its structure and properties. This includes adding vertices and edges, + * as well as setting weights and types for existing elements. + * + * These concepts are useful for algorithms that need to build or transform graphs, + * such as graph generators or coarsening algorithms. + */ namespace osp { -// modify vertices +/** + * @brief Concept to check if vertex weights are modifiable. + * + * Requires: + * - `set_vertex_work_weight(v, w)` + * - `set_vertex_comm_weight(v, w)` + * - `set_vertex_mem_weight(v, w)` + * + * Also requires the graph to be default constructible, copy/move constructible, and assignable. + * + * @tparam T The graph type. + */ template struct is_modifiable_cdag_vertex : std::false_type {}; @@ -36,54 +58,83 @@ struct is_modifiable_cdag_vertex< decltype(std::declval().set_vertex_mem_weight(std::declval>(), std::declval>()))>> : std::conjunction, std::is_default_constructible, - std::is_copy_constructible, - std::is_move_constructible, + std::is_copy_constructible, + std::is_move_constructible, std::is_copy_assignable, std::is_move_assignable> {}; template inline constexpr bool is_modifiable_cdag_vertex_v = is_modifiable_cdag_vertex::value; -// add vertices +/** + * @brief Concept to check if vertices can be added to the graph. + * + * Requires: + * - `add_vertex(work_weight, comm_weight, mem_weight)` + * - Constructibility from `vertex_idx_t` (for reserving size). + * + * @tparam T The graph type. + */ template struct is_constructable_cdag_vertex : std::false_type {}; template struct is_constructable_cdag_vertex< T, std::void_t().add_vertex(std::declval>(), std::declval>(), std::declval>()))>> - : std::conjunction, + : std::conjunction, std::is_constructible>> {}; template inline constexpr bool is_constructable_cdag_vertex_v = is_constructable_cdag_vertex::value; -// modify vertices types +/** + * @brief Concept to check if vertex types are modifiable. + * + * Requires: + * - `set_vertex_type(v, type)` + * + * @tparam T The graph type. + */ template struct is_modifiable_cdag_typed_vertex : std::false_type {}; template struct is_modifiable_cdag_typed_vertex< T, std::void_t().set_vertex_type(std::declval>(), std::declval>()))>> - : std::conjunction, + : std::conjunction, is_computational_dag_typed_vertices> {}; // for default node type template inline constexpr bool is_modifiable_cdag_typed_vertex_v = is_modifiable_cdag_typed_vertex::value; -// add vertices with types +/** + * @brief Concept to check if typed vertices can be added. + * + * Requires: + * - `add_vertex(work, comm, mem, type)` + * + * @tparam T The graph type. + */ template struct is_constructable_cdag_typed_vertex : std::false_type {}; template struct is_constructable_cdag_typed_vertex< T, std::void_t().add_vertex(std::declval>(), std::declval>(), std::declval>(), std::declval>()))>> - : std::conjunction, + : std::conjunction, is_modifiable_cdag_typed_vertex> {}; // for default node type template inline constexpr bool is_constructable_cdag_typed_vertex_v = is_constructable_cdag_typed_vertex::value; -// add edges +/** + * @brief Concept to check if edges can be added (unweighted). + * + * Requires: + * - `add_edge(source, target)` + * + * @tparam T The graph type. + */ template struct is_constructable_cdag_edge : std::false_type {}; @@ -95,7 +146,14 @@ struct is_constructable_cdag_edge().add_ template inline constexpr bool is_constructable_cdag_edge_v = is_constructable_cdag_edge::value; -// modify edges with comm costs +/** + * @brief Concept to check if edge communication weights are modifiable. + * + * Requires: + * - `set_edge_comm_weight(edge, weight)` + * + * @tparam T The graph type. + */ template struct is_modifiable_cdag_comm_edge : std::false_type {}; @@ -107,20 +165,34 @@ struct is_modifiable_cdag_comm_edge< template inline constexpr bool is_modifiable_cdag_comm_edge_v = is_modifiable_cdag_comm_edge::value; -// add edges with comm costs +/** + * @brief Concept to check if weighted edges can be added. + * + * Requires: + * - `add_edge(source, target, weight)` + * + * @tparam T The graph type. + */ template struct is_constructable_cdag_comm_edge : std::false_type {}; template struct is_constructable_cdag_comm_edge< T, std::void_t().add_edge(std::declval>(), std::declval>(), std::declval>()))>> - : std::conjunction, + : std::conjunction, is_computational_dag_edge_desc, is_modifiable_cdag_comm_edge> {}; // for default edge weight template inline constexpr bool is_constructable_cdag_comm_edge_v = is_constructable_cdag_comm_edge::value; +/** + * @brief Concept for a fully constructable computational DAG. + * + * Combines `is_constructable_cdag_vertex` and `is_constructable_cdag_edge`. + * + * @tparam T The graph type. + */ template struct is_constructable_cdag : std::false_type {}; @@ -131,6 +203,9 @@ struct is_constructable_cdag> template inline constexpr bool is_constructable_cdag_v = is_constructable_cdag::value; +/** + * @brief Helper trait to check if a graph can be directly constructed from a vertex count and a set of edges. + */ template inline constexpr bool is_direct_constructable_cdag_v = std::is_constructible, std::set, vertex_idx_t>>>::value; diff --git a/include/osp/concepts/directed_graph_concept.hpp b/include/osp/concepts/directed_graph_concept.hpp index 1fbce9d0..c6a470b3 100644 --- a/include/osp/concepts/directed_graph_concept.hpp +++ b/include/osp/concepts/directed_graph_concept.hpp @@ -22,15 +22,42 @@ limitations under the License. #include "iterator_concepts.hpp" namespace osp { -// directed_graph concept without explicit edges +/** + * @brief Concept for a directed graph structure in OneStopParallel (OSP). + * + * OneStopParallel is a header-only library where directed graphs serve as the fundamental + * data structure for all scheduling algorithms and other DAG processing algorithms, such as + * coarsening or partitioning. The `is_directed_graph` concept defines the minimal interface + * that a graph type must satisfy to be used within the OSP ecosystem. + * + * A type `T` satisfies `is_directed_graph` if it provides the following API: + * + * - **vertices()**: Returns a range of all vertices in the graph. + * - **num_vertices()**: Returns the total number of vertices as an integral type. + * - **num_edges()**: Returns the total number of edges as an integral type. + * - **parents(v)**: Returns a range of parent vertices for a given vertex `v`. + * - `v` must be of type `vertex_idx_t`. + * - **children(v)**: Returns a range of child vertices for a given vertex `v`. + * - `v` must be of type `vertex_idx_t`. + * - **in_degree(v)**: Returns the number of incoming edges for vertex `v` as an integral type. + * - **out_degree(v)**: Returns the number of outgoing edges for vertex `v` as an integral type. + * + * This concept ensures that any graph implementation passed to OSP algorithms exposes + * the necessary structural information for processing. + * + * This concept encapsulates a classic adjacency list graph structure, allowing efficient + * iteration over the parents and children of any given node. + * + * @tparam T The graph type to check against the concept. + */ template struct is_directed_graph : std::false_type {}; template struct is_directed_graph< - T, std::void_t::vertex_idx, + T, std::void_t::vertex_idx, decltype(std::declval().vertices()), - decltype(std::declval().num_vertices()), + decltype(std::declval().num_vertices()), decltype(std::declval().num_edges()), decltype(std::declval().parents(std::declval>())), decltype(std::declval().children(std::declval>())), @@ -43,31 +70,33 @@ struct is_directed_graph< is_input_range_of().parents(std::declval>())), vertex_idx_t>, is_input_range_of().children(std::declval>())), vertex_idx_t>, std::is_integral().in_degree(std::declval>()))>, - std::is_integral().out_degree(std::declval>()))> - > {}; + std::is_integral().out_degree(std::declval>()))>> {}; template inline constexpr bool is_directed_graph_v = is_directed_graph::value; +/** + * @brief Concept for an edge list structure. + * + * The `is_edge_list_type` concept exposes the graph structure through access to a list of edges. + * It requires the type `T` to be a range (providing `begin()`, `end()`, and `size()`) where + * the value type contains `source` and `target` members of type `v_type`. + * + * @tparam T The edge list type. + * @tparam v_type The vertex type. + * @tparam e_type The size type (usually integral). + */ template struct is_edge_list_type : std::false_type {}; template struct is_edge_list_type< - T, v_type, e_type, std::void_t().begin()), - decltype(std::declval().end()), - decltype(std::declval().size()), - typename std::iterator_traits()))>::value_type, - decltype(std::declval()))>::value_type>().source), - decltype(std::declval()))>::value_type>().target)>> - // decltype((*(std::declval().begin())).source())>> - // decltype(std::declval<*(std::declval().begin())>().target())>> - : std::conjunction< std::is_same()))>::value_type>().source), v_type>, - std::is_same()))>::value_type>().target), v_type>, - std::is_same().size()), e_type>> {}; + T, v_type, e_type, std::void_t().begin()), decltype(std::declval().end()), decltype(std::declval().size()), typename std::iterator_traits()))>::value_type, decltype(std::declval()))>::value_type>().source), decltype(std::declval()))>::value_type>().target)>> + : std::conjunction()))>::value_type>().source), v_type>, + std::is_same()))>::value_type>().target), v_type>, + std::is_same().size()), e_type>> {}; template inline constexpr bool is_edge_list_type_v = is_edge_list_type::value; - } // namespace osp \ No newline at end of file diff --git a/include/osp/concepts/directed_graph_edge_desc_concept.hpp b/include/osp/concepts/directed_graph_edge_desc_concept.hpp index 054ecc4e..eb6672ef 100644 --- a/include/osp/concepts/directed_graph_edge_desc_concept.hpp +++ b/include/osp/concepts/directed_graph_edge_desc_concept.hpp @@ -19,38 +19,99 @@ limitations under the License. #pragma once #include "directed_graph_concept.hpp" -#include "osp/graph_algorithms/directed_graph_edge_view.hpp" #include "graph_traits.hpp" +#include "osp/graph_algorithms/directed_graph_edge_view.hpp" + +/** + * @file directed_graph_edge_desc_concept.hpp + * @brief Concepts and default implementations for edge descriptors in directed graphs. + * + * This file extends the basic directed graph concepts to support edge descriptors. + * It provides default implementations for accessing source/target vertices from edges + * and defines the `is_directed_graph_edge_desc` concept to check if a graph type + * properly supports edge descriptors and edge iteration. + * + * Note: If a graph implementation satisfies `directed_graph_concept`, OSP automatically + * adds the edge descriptor API on top using `directed_edge` as the default edge descriptor. + * The mechanics for this are implemented in `directed_graph_edge_view.hpp`. + */ namespace osp { -// default implementation to get the source of an edge +/** + * @brief Default implementation to get the source vertex of an edge. + * + * @tparam Graph_t The graph type. + * @param edge The edge descriptor. + * @return The source vertex index. + */ template inline vertex_idx_t source(const directed_edge &edge, const Graph_t &) { return edge.source; } -// default implementation to get the target of an edge +/** + * @brief Default implementation to get the target vertex of an edge. + * + * @tparam Graph_t The graph type. + * @param edge The edge descriptor. + * @return The target vertex index. + */ template inline vertex_idx_t target(const directed_edge &edge, const Graph_t &) { return edge.target; } +/** + * @brief Get a view of all edges in the graph. + * + * @tparam Graph_t The graph type. + * @param graph The graph instance. + * @return An `edge_view` allowing iteration over all edges. + */ template inline edge_view edges(const Graph_t &graph) { return edge_view(graph); } +/** + * @brief Get a view of outgoing edges from a vertex. + * + * @tparam Graph_t The graph type. + * @param u The source vertex index. + * @param graph The graph instance. + * @return An `out_edge_view` allowing iteration over outgoing edges from `u`. + */ template inline out_edge_view out_edges(vertex_idx_t u, const Graph_t &graph) { return out_edge_view(graph, u); } +/** + * @brief Get a view of incoming edges to a vertex. + * + * @tparam Graph_t The graph type. + * @param v The target vertex index. + * @param graph The graph instance. + * @return An `in_edge_view` allowing iteration over incoming edges to `v`. + */ template inline in_edge_view in_edges(vertex_idx_t v, const Graph_t &graph) { return in_edge_view(graph, v); } +/** + * @brief Concept check for a directed graph with edge descriptors. + * + * Checks if a type `T` satisfies the requirements of a directed graph that also + * supports edge descriptors, including: + * - Validity of `directed_graph_edge_desc_traits`. + * - Existence of `edges()`, `out_edges()`, and `in_edges()` functions returning input ranges of edge descriptors. + * - Existence of `source()` and `target()` functions mapping edge descriptors to vertex indices. + * - Default and copy constructibility of the edge descriptor type. + * + * @tparam T The graph type to check. + */ template struct is_directed_graph_edge_desc : std::false_type {}; @@ -74,8 +135,13 @@ struct is_directed_graph_edge_desc inline constexpr bool is_directed_graph_edge_desc_v = is_directed_graph_edge_desc::value; -// Specialization for graphs that define a directed_edge_descriptor that can be used as a key in a hash table. -// Compatible with STL hash tables. +/** + * @brief Specialization for graphs that define a directed_edge_descriptor that can be used as a key in a hash table. + * + * Compatible with STL hash tables (requires `std::hash` specialization and equality operator). + * + * @tparam T The graph type. + */ template struct has_hashable_edge_desc : std::false_type {}; @@ -87,7 +153,6 @@ struct has_hashable_edge_desc, std::is_default_constructible>, std::is_copy_constructible>> {}; - template inline constexpr bool has_hashable_edge_desc_v = has_hashable_edge_desc::value; diff --git a/include/osp/concepts/graph_traits.hpp b/include/osp/concepts/graph_traits.hpp index daab23ec..357ca1c9 100644 --- a/include/osp/concepts/graph_traits.hpp +++ b/include/osp/concepts/graph_traits.hpp @@ -20,12 +20,28 @@ limitations under the License. #include "iterator_concepts.hpp" +/** + * @file graph_traits.hpp + * @brief Type traits and concepts for graph structures in OneStopParallel. + * + * This file defines the core requirements for types used by graph implementations in the library, + * specifically for computational DAGs. It provides mechanisms + * to extract types for vertex indices, edge descriptors, and weights, + * ensuring that graph implementations conform to the expected interfaces. + */ + namespace osp { -#define DEFINE_TYPE_MEMBER_TEST(test_name, member_name) \ - template \ - struct test_name : std::false_type {}; \ - template \ +/** + * @brief Macro to define a trait that checks for the existence of a specific type member. + * + * Creates a struct `test_name` inheriting from `std::true_type` if `T::member_name` exists, + * otherwise inherits from `std::false_type`. + */ +#define DEFINE_TYPE_MEMBER_TEST(test_name, member_name) \ + template \ + struct test_name : std::false_type {}; \ + template \ struct test_name> : std::true_type {}; DEFINE_TYPE_MEMBER_TEST(has_vertex_idx_tmember, vertex_idx) @@ -36,17 +52,33 @@ DEFINE_TYPE_MEMBER_TEST(has_vertex_mem_weight_tmember, vertex_mem_weight_type) DEFINE_TYPE_MEMBER_TEST(has_vertex_type_tmember, vertex_type_type) DEFINE_TYPE_MEMBER_TEST(has_edge_comm_weight_tmember, edge_comm_weight_type) -// Every directed graph must have a vertex_idx type +/** + * @brief Core traits for any directed graph type. + * + * Requires that the graph type `T` defines a `vertex_idx` type member. + * + * @tparam T The graph type. + */ template struct directed_graph_traits { static_assert(has_vertex_idx_tmember::value, "graph must have vertex_idx"); using vertex_idx = typename T::vertex_idx; }; -// Macro to extract the vertex_idx type from the graph +/** + * @brief Alias to easily access the vertex index type of a graph. + */ template using vertex_idx_t = typename directed_graph_traits::vertex_idx; +/** + * @brief A default edge descriptor for directed graphs. + * + * This struct is used when the graph type does not provide its own edge descriptor. + * It simply holds the source and target vertex indices. + * + * @tparam Graph_t The graph type. + */ template struct directed_edge { @@ -65,6 +97,11 @@ struct directed_edge { directed_edge(vertex_idx_t src, vertex_idx_t tgt) : source(src), target(tgt) {} }; +/** + * @brief Helper struct to extract the edge descriptor type of a directed graph. + * + * If the graph defines `directed_edge_descriptor`, it is extracted; otherwise, `directed_edge` is used as a default implementation. + */ template struct directed_graph_edge_desc_traits_helper { using directed_edge_descriptor = directed_edge; @@ -84,6 +121,16 @@ struct directed_graph_edge_desc_traits { template using edge_desc_t = typename directed_graph_edge_desc_traits::directed_edge_descriptor; +/** + * @brief Traits for computational Directed Acyclic Graphs (DAGs). + * + * Computational DAGs extend basic graphs by adding requirements for weight types: + * - `vertex_work_weight_type`: Represents computational cost of a task. + * - `vertex_comm_weight_type`: Represents data size/communication cost. + * - `vertex_mem_weight_type`: Represents memory usage of a task. + * + * @tparam T The computational DAG type. + */ template struct computational_dag_traits { static_assert(has_vertex_work_weight_tmember::value, "cdag must have vertex work weight type"); @@ -104,6 +151,11 @@ using v_commw_t = typename computational_dag_traits::vertex_comm_weight_type; template using v_memw_t = typename computational_dag_traits::vertex_mem_weight_type; +/** + * @brief Traits to extract the vertex type of a computational DAG, if defined. + * + * If the DAG defines `vertex_type_type`, it is extracted; otherwise, `void` is used. + */ template struct computational_dag_typed_vertices_traits { using vertex_type_type = void; @@ -117,6 +169,11 @@ struct computational_dag_typed_vertices_traits using v_type_t = typename computational_dag_typed_vertices_traits::vertex_type_type; +/** + * @brief Traits to extract the edge communication weight type of a computational DAG, if defined. + * + * If the DAG defines `edge_comm_weight_type`, it is extracted; otherwise, `void` is used. + */ template struct computational_dag_edge_desc_traits { using edge_comm_weight_type = void; @@ -130,6 +187,14 @@ struct computational_dag_edge_desc_traits using e_commw_t = typename computational_dag_edge_desc_traits::edge_comm_weight_type; +// ----------------------------------------------------------------------------- +// Property Traits +// ----------------------------------------------------------------------------- + +/** + * @brief Check if a graph guarantees vertices are stored/iterated in topological order. + * It allows a graph implementation to notify algorithms that vertices are stored/iterated in topological order which can be used to optimize the algorithm. + */ template struct has_vertices_in_top_order_trait : std::false_type {}; @@ -140,6 +205,9 @@ struct has_vertices_in_top_order_trait inline constexpr bool has_vertices_in_top_order_v = has_vertices_in_top_order_trait::value; +/** + * @brief Check if a graph guarantees children of a vertex are stored/iterated in vertex index order. + */ template struct has_children_in_vertex_order_trait : std::false_type {}; @@ -150,6 +218,9 @@ struct has_children_in_vertex_order_trait inline constexpr bool has_children_in_vertex_order_v = has_children_in_vertex_order_trait::value; +/** + * @brief Check if a graph guarantees parents of a vertex are stored/iterated in vertex index order. + */ template struct has_parents_in_vertex_order_trait : std::false_type {}; @@ -162,6 +233,11 @@ inline constexpr bool has_parents_in_vertex_order_v = has_parents_in_vertex_orde } // namespace osp +/** + * @brief Specialization of std::hash for osp::directed_edge. + * + * This specialization provides a hash function for osp::directed_edge, which is used in hash-based containers like std::unordered_set and std::unordered_map. + */ template struct std::hash> { std::size_t operator()(const osp::directed_edge &p) const noexcept { diff --git a/include/osp/concepts/iterator_concepts.hpp b/include/osp/concepts/iterator_concepts.hpp index b4efd48c..2bf9c4cb 100644 --- a/include/osp/concepts/iterator_concepts.hpp +++ b/include/osp/concepts/iterator_concepts.hpp @@ -13,18 +13,35 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -@author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner +@author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner */ - #pragma once #include #include namespace osp { - -// Concept for const_iterator with forward iterator category +/** + * @file iterator_concepts.hpp + * @brief C++17 compatible concept checks (type traits) for iterators and ranges. + * + * This file provides type traits that emulate C++20 concepts for iterators and ranges. + * These are used to ensure type safety and correct usage of templates within the library + * while maintaining compatibility with C++17. + */ + +/** + * @brief Checks if a type is a forward iterator. + * + * This type trait checks if `T` satisfies the requirements of a forward iterator. + * It verifies the existence of standard iterator typedefs and checks if the iterator category + * is derived from `std::forward_iterator_tag`. + * + * @note Equivalent to C++20 `std::forward_iterator`. + * + * @tparam T The type to check. + */ template struct is_forward_iterator : std::false_type {}; @@ -41,14 +58,24 @@ struct is_forward_iterator< template inline constexpr bool is_forward_iterator_v = is_forward_iterator::value; -// Concept for ranges with const forward iterators supporting begin or cbegin +/** + * @brief Checks if a type is a range of forward iterators with a specific value type. + * + * This type trait checks if `T` is a range (provides `begin()` and `end()`) whose iterator + * satisfies `is_forward_iterator` and whose value type matches `ValueType`. + * + * @note Equivalent to C++20 `std::ranges::forward_range` combined with a value type check. + * + * @tparam T The range type to check. + * @tparam ValueType The expected value type of the range. + */ template struct is_forward_range_of : std::false_type {}; template struct is_forward_range_of< T, ValueType, - std::void_t())), + std::void_t())), decltype(std::end(std::declval()))>> : std::conjunction< is_forward_iterator()))>, @@ -57,7 +84,17 @@ struct is_forward_range_of< template inline constexpr bool is_forward_range_of_v = is_forward_range_of::value; -// Concept for containers +/** + * @brief Checks if a type is a container (sized forward range). + * + * This type trait checks if `T` satisfies `is_forward_range_of` and additionally provides + * a `size()` member function. + * + * @note Equivalent to C++20 `std::ranges::sized_range` combined with `std::ranges::forward_range`. + * + * @tparam T The container type to check. + * @tparam ValueType The expected value type of the container. + */ template struct is_container_of : std::false_type {}; @@ -71,9 +108,17 @@ struct is_container_of< template inline constexpr bool is_container_of_v = is_container_of::value; - - -// Concept for const_iterator with forward iterator category +/** + * @brief Checks if a type is an input iterator. + * + * This type trait checks if `T` satisfies the requirements of an input iterator. + * It verifies the existence of standard iterator typedefs and checks if the iterator category + * is derived from `std::input_iterator_tag`. + * + * @note Equivalent to C++20 `std::input_iterator`. + * + * @tparam T The type to check. + */ template struct is_input_iterator : std::false_type {}; @@ -90,14 +135,24 @@ struct is_input_iterator< template inline constexpr bool is_input_iterator_v = is_input_iterator::value; -// Concept for ranges with const input iterators supporting begin or cbegin +/** + * @brief Checks if a type is a range of input iterators with a specific value type. + * + * This type trait checks if `T` is a range (provides `begin()` and `end()`) whose iterator + * satisfies `is_input_iterator` and whose value type matches `ValueType`. + * + * @note Equivalent to C++20 `std::ranges::input_range` combined with a value type check. + * + * @tparam T The range type to check. + * @tparam ValueType The expected value type of the range. + */ template struct is_input_range_of : std::false_type {}; template struct is_input_range_of< T, ValueType, - std::void_t())), + std::void_t())), decltype(std::end(std::declval()))>> : std::conjunction< is_input_iterator()))>, @@ -106,5 +161,4 @@ struct is_input_range_of< template inline constexpr bool is_input_range_of_v = is_input_range_of::value; - } // namespace osp \ No newline at end of file diff --git a/include/osp/concepts/specific_graph_impl.hpp b/include/osp/concepts/specific_graph_impl.hpp index 518bb732..29c3f75c 100644 --- a/include/osp/concepts/specific_graph_impl.hpp +++ b/include/osp/concepts/specific_graph_impl.hpp @@ -18,21 +18,37 @@ limitations under the License. #pragma once +/** + * @file specific_graph_impl.hpp + * @brief Type traits for specific graph implementations used in OneStopParallel. + * + * This file contains trait checks for specific graph implementations, such as + * Compact Sparse Graphs (CSR-like structures), which may require specialized + * handling or offer optimizations in certain algorithms. + */ + namespace osp { -// Compact Sparse Graph concept +/** + * @brief Trait to check if a graph type is a `Compact_Sparse_Graph`. + * + * @tparam T The graph type. + */ template struct is_Compact_Sparse_Graph : std::false_type {}; template inline constexpr bool is_Compact_Sparse_Graph_v = is_Compact_Sparse_Graph::value; -// Compact Sparse Graph concept with reorder +/** + * @brief Trait to check if a graph type is a `Compact_Sparse_Graph` that supports reordering. + * + * @tparam T The graph type. + */ template struct is_Compact_Sparse_Graph_reorder : std::false_type {}; template inline constexpr bool is_Compact_Sparse_Graph_reorder_v = is_Compact_Sparse_Graph_reorder::value; - } // namespace osp \ No newline at end of file