Skip to content

Commit 46be8f9

Browse files
committed
hypergraph elements and dir tags docs
1 parent 592880e commit 46be8f9

6 files changed

Lines changed: 193 additions & 27 deletions

File tree

include/gl/edge_descriptor.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ namespace gl {
2222
/// @ingroup GL GL-Core
2323
/// @brief A lightweight wrapper representing a graph edge with its endpoints and optional properties.
2424
///
25-
/// **Module:** Part of the @ref GL-Core "Core Graph Components" group.
26-
///
2725
/// The `edge_descriptor` class provides a type-safe and efficient way to represent
2826
/// edges in both directed and undirected graph structures. It encapsulates the unique
2927
/// identifier of the edge, its source and target vertices, and optional property data.

include/gl/vertex_descriptor.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@ namespace gl {
2323
/// @ingroup GL GL-Core
2424
/// @brief A lightweight wrapper around a vertex identifier with optional properties.
2525
///
26-
/// **Module:** Part of the @ref GL-Core "Core Graph Components" group.
27-
///
2826
/// The `vertex_descriptor` class provides a type-safe and efficient way to represent
2927
/// vertices in graph structures. It acts as a lightweight wrapper that combines
3028
/// a unique identifier with optional property data, ensuring safe access and
3129
/// comparison operations.
3230
///
3331
/// > [!WARNING] This class is not intended to be instantiated directly.
3432
/// >
35-
/// > Instead, `vertex_descriptor` objects should be retrieved from the @ref gl::graph class instance that owns the given vertex.
33+
/// > Instead, `vertex_descriptor` objects should be retrieved from the @ref gl::graph "graph" class instance that owns the given vertex.
3634
///
3735
/// ### Example Usage
3836
/// ```cpp
@@ -49,7 +47,7 @@ namespace gl {
4947
///
5048
/// 1\. Apply the stream manipulator to ensure custom property data is included in the output.
5149
///
52-
/// 2\. Use the arrow operator `->` to read custom properties attached to the vertex.
50+
/// 2\. Use the arrow operator `->` to read custom properties attached to the vertex (assuming the vertex properties type contains `parent` and `level` members).
5351
///
5452
/// 3\. Access another vertex via the `graph` using its ID, and modify the current vertex's properties.
5553
///

include/hgl/directional_tags.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,45 @@
22
// This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl).
33
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
44

5+
/// @file hgl/directional_tags.hpp
6+
/// @brief Defines tag types used to specify the directionality of a hypergraph.
7+
58
#pragma once
69

710
#include "hgl/traits.hpp"
811

912
namespace hgl {
1013

14+
/// @ingroup HGL-Core
15+
/// @brief Tag type specifying that a hypergraph is undirected.
16+
///
17+
/// In an undirected hypergraph, a hyperedge is strictly defined as a set of incident vertices,
18+
/// with no distinction between origin and destination.
1119
struct undirected_t {
20+
/// @brief Self type identity for internal metaprogramming use.
1221
using type = std::type_identity_t<undirected_t>;
1322
};
1423

24+
/// @ingroup HGL-Core
25+
/// @brief Tag type specifying that a hypergraph is backward-forward (BF) directed.
26+
///
27+
/// In a BF-directed hypergraph, each hyperedge maps a distinct set of *tail* vertices (origins)
28+
/// to a distinct set of *head* vertices (destinations).
1529
struct bf_directed_t {
30+
/// @brief Self type identity for internal metaprogramming use.
1631
using type = std::type_identity_t<bf_directed_t>;
1732
};
1833

1934
namespace traits {
2035

36+
/// @ingroup HGL-Traits
37+
/// @brief Validates if a type is a valid hypergraph directional tag.
38+
///
39+
/// The valid hypergraph directional tags are @ref hgl::undirected_t "undirected_t" and
40+
/// @ref hgl::bf_directed_t "bf_directed_t". This concept is used to constrain template
41+
/// parameters intended to specify the directionality of a hypergraph.
42+
///
43+
/// @tparam T The type to evaluate against the concept.
2144
template <typename T>
2245
concept c_hypergraph_directional_tag = c_one_of<T, undirected_t, bf_directed_t>;
2346

include/hgl/hypergraph_elements.hpp

Lines changed: 145 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl).
33
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
44

5+
/// @file hgl/hypergraph_elements.hpp
6+
/// @brief Defines the hyperedge_descriptor class, element tags, and aliases for hypergraph elements.
7+
58
#pragma once
69

710
#include "gl/traits.hpp"
@@ -16,93 +19,219 @@ namespace hgl {
1619

1720
// --- hypergraph elements ---
1821

19-
using gl::vertex_descriptor;
20-
22+
/// @ingroup HGL-Core
23+
/// @brief Type alias adapting the standard graph vertex descriptor for hypergraphs.
24+
///
25+
/// Because hypergraphs and standard graphs share the same fundamental vertex representation,
26+
/// this alias imports the @ref gl::vertex_descriptor type into the HGL module. It provides a
27+
/// type-safe wrapper combining a unique identifier with optional property data.
28+
///
29+
/// > [!WARNING] This class is not intended to be instantiated directly.
30+
/// >
31+
/// > Instead, `vertex_descriptor` objects should be retrieved from the @ref hgl::hypergraph class instance that owns the given vertex.
32+
///
33+
/// ### Example Usage
34+
/// ```cpp
35+
/// std::cout << gl::io::verbose << gl::io::with_vertex_properties; // (1)!
36+
///
37+
/// for (const auto& vertex : hypergraph.vertices()) {
38+
/// const auto deg = hypergraph.degree(vertex); // (2)!
39+
///
40+
/// if (deg == 0uz)
41+
/// vertex->description = "Isolated node"; // (3)!
42+
/// else
43+
/// vertex->description = std::format("Connected to {} hyperedges", deg);
44+
///
45+
/// std::cout << "Vertex details: " << vertex << '\n';
46+
/// }
47+
/// ```
48+
///
49+
/// 1. Stream manipulators inject persistent formatting state globally before iterating.
50+
/// 2. Use the owning hypergraph to query topological information about the vertex.
51+
/// 3. Safely access and modify the underlying properties via the `->` operator (assuming the vertex properties type contains a `description` member).
52+
///
53+
/// ### Template Parameters
54+
/// | Parameter | Description | Default | Constraint |
55+
/// | :-------- | :--- | :--- | :--- |
56+
/// | Properties | The type of property data attached to the vertex. | @ref hgl::empty_properties "empty_properties" | [**c_properties**](gl_concepts.md#gl-traits-c-properties) |
57+
/// | IdType | The underlying integer type used for the IDs. | @ref hgl::default_id_type "default_id_type" | [**c_id_type**](gl_concepts.md#gl-traits-c-id-type) |
58+
///
59+
/// ### See Also
60+
/// - @ref gl::vertex_descriptor for the full definition of the type.
61+
/// - @ref hgl::hyperedge_descriptor "hyperedge_descriptor" for the corresponding hyperedge wrapper class.
62+
/// - @ref hgl::hypergraph "hypergraph" for the owning hypergraph class that manages vertex descriptors.
63+
template <
64+
traits::c_properties Properties = empty_properties,
65+
traits::c_id_type IdType = default_id_type>
66+
using vertex_descriptor = gl::vertex_descriptor<Properties, IdType>;
67+
68+
/// @ingroup HGL-Core
69+
/// @brief A lightweight wrapper representing a hypergraph edge with optional properties.
70+
///
71+
/// The `hyperedge_descriptor` class provides a type-safe and efficient way to represent
72+
/// hyperedges in hypergraph structures. It acts as a lightweight wrapper that encapsulates
73+
/// the unique identifier of the hyperedge and its optional property data, ensuring safe
74+
/// access and comparison operations.
75+
///
76+
/// > [!WARNING] This class is not intended to be instantiated directly.
77+
/// >
78+
/// > Instead, `hyperedge_descriptor` objects should be retrieved from the @ref hgl::hypergraph class instance that owns the given hyperedge.
79+
///
80+
/// ### Example Usage
81+
/// ```cpp
82+
/// std::cout << gl::io::verbose << gl::io::with_hyperedge_properties; // (1)!
83+
///
84+
/// for (const auto& hyperedge : hypergraph.hyperedges()) {
85+
/// const auto size = hypergraph.hyperedge_size(hyperedge); // (2)!
86+
/// hyperedge->weight = static_cast<double>(size) * 1.5; // (3)!
87+
/// std::cout << "Hyperedge details: " << hyperedge << '\n';
88+
/// }
89+
/// ```
90+
///
91+
/// 1. Stream manipulators like `with_hyperedge_properties` apply persistently to `std::cout`.
92+
/// 2. Use the owning hypergraph to query topological information about the hyperedge.
93+
/// 3. Update the payload properties through the overloaded `->` operator (assuming the hyperedge properties type contains a `weight` member).
94+
///
95+
/// ### Template Parameters
96+
/// | Parameter | Description | Default | Constraint |
97+
/// | :-------- | :--- | :--- | :--- |
98+
/// | Properties | The type of property data attached to the hyperedge. | @ref hgl::empty_properties "empty_properties" | [**c_properties**](gl_concepts.md#gl-traits-c-properties) |
99+
/// | IdType | The underlying integer type used for the IDs. | @ref hgl::default_id_type "default_id_type" | [**c_id_type**](gl_concepts.md#gl-traits-c-id-type) |
100+
///
101+
/// ### See Also
102+
/// - @ref hgl::vertex_descriptor "vertex_descriptor" for the corresponding vertex wrapper class.
103+
/// - @ref hgl::hypergraph "hypergraph" for the owning hypergraph class that manages hyperedge descriptors.
21104
template <
22105
traits::c_properties Properties = empty_properties,
23106
traits::c_id_type IdType = default_id_type>
24107
class hyperedge_descriptor final {
25108
public:
109+
/// @brief Self type alias.
26110
using type = hyperedge_descriptor<Properties>;
111+
/// @brief The underlying integer type used for the hyperedge identifier.
27112
using id_type = IdType;
113+
/// @brief The type of property data attached to the hyperedge.
28114
using properties_type = Properties;
29115

116+
/// @brief Default constructor creating an invalid hyperedge descriptor.
30117
hyperedge_descriptor() {
31118
*this = hyperedge_descriptor::invalid();
32119
}
33120

121+
/// @brief Constructs a property-less hyperedge descriptor from a raw ID.
122+
/// @param id The raw identifier of the hyperedge.
34123
explicit hyperedge_descriptor(const id_type id)
35124
requires(traits::c_empty_properties<properties_type>)
36125
: _id(id) {}
37126

127+
/// @brief Constructs a hyperedge descriptor binding an ID to its properties.
128+
/// @param id The raw identifier of the hyperedge.
129+
/// @param properties A reference to the underlying properties payload.
38130
explicit hyperedge_descriptor(const id_type id, properties_type& properties)
39131
requires(traits::c_non_empty_properties<properties_type>)
40132
: _id(id), _properties(properties) {}
41133

134+
/// @brief Returns a special descriptor representing an invalid or uninitialized property-less hyperedge.
135+
/// @return An invalid `hyperedge_descriptor`.
42136
[[nodiscard]] gl_attr_force_inline static hyperedge_descriptor invalid() noexcept
43137
requires(traits::c_empty_properties<properties_type>)
44138
{
45139
return hyperedge_descriptor(invalid_id);
46140
}
47141

142+
/// @brief Returns a special descriptor representing an invalid or uninitialized hyperedge with properties.
143+
/// @return An invalid `hyperedge_descriptor`.
48144
[[nodiscard]] gl_attr_force_inline static hyperedge_descriptor invalid() noexcept
49145
requires(traits::c_non_empty_properties<properties_type>)
50146
{
51147
static properties_type invalid_properties{};
52148
return hyperedge_descriptor(invalid_id, invalid_properties);
53149
}
54150

151+
/// @brief Default copy constructor.
55152
hyperedge_descriptor(const hyperedge_descriptor&) = default;
153+
/// @brief Default copy assignment operator.
56154
hyperedge_descriptor& operator=(const hyperedge_descriptor&) = default;
57155

156+
/// @brief Default move constructor.
58157
hyperedge_descriptor(hyperedge_descriptor&&) noexcept = default;
158+
/// @brief Default move assignment operator.
59159
hyperedge_descriptor& operator=(hyperedge_descriptor&&) noexcept = default;
60160

161+
/// @brief Default destructor.
61162
~hyperedge_descriptor() = default;
62163

164+
/// @brief Compares two hyperedge descriptors for equality.
165+
/// @param other The descriptor to compare against.
166+
/// @return `true` if both descriptors hold the same ID, `false` otherwise.
63167
[[nodiscard]] bool operator==(const hyperedge_descriptor& other) const noexcept {
64168
return this->_id == other._id;
65169
}
66170

171+
/// @brief Contextually converts the descriptor to a boolean.
172+
/// @return `true` if the descriptor is valid, `false` otherwise.
67173
[[nodiscard]] gl_attr_force_inline operator bool() const noexcept {
68174
return this->is_valid();
69175
}
70176

177+
/// @brief Compares two hyperedge descriptors to establish a strict ordering based on their IDs.
178+
/// @param other The descriptor to compare against.
179+
/// @return The result of the three-way comparison between the underlying IDs.
71180
[[nodiscard]] gl_attr_force_inline std::strong_ordering operator<=>(
72181
const hyperedge_descriptor& other
73182
) const noexcept {
74183
return this->_id <=> other._id;
75184
}
76185

186+
/// @brief Checks if the descriptor represents a valid hyperedge.
187+
/// @return `true` if the underlying ID is not the invalid ID constant, `false` otherwise.
77188
[[nodiscard]] gl_attr_force_inline bool is_valid() const noexcept {
78189
return this->_id != invalid_id;
79190
}
80191

192+
/// @brief Retrieves the raw underlying ID of the hyperedge.
193+
/// @return The hyperedge's integer ID.
81194
[[nodiscard]] gl_attr_force_inline id_type id() const noexcept {
82195
return this->_id;
83196
}
84197

198+
/// @brief Retrieves a reference to the property payload attached to the hyperedge.
199+
/// @return A mutable reference to the underlying properties.
200+
/// @throws std::logic_error If the descriptor is invalid.
85201
[[nodiscard]] gl_attr_force_inline properties_type& properties() const
86202
requires(traits::c_non_empty_properties<properties_type>)
87203
{
88204
this->_validate();
89205
return this->_properties.get();
90206
}
91207

208+
/// @brief Arrow operator providing direct access to the hyperedge's properties.
209+
/// @return A pointer to the underlying properties.
210+
/// @throws std::logic_error If the descriptor is invalid.
92211
[[nodiscard]] gl_attr_force_inline properties_type* operator->() const
93212
requires(traits::c_non_empty_properties<properties_type>)
94213
{
95214
this->_validate();
96215
return &this->_properties.get();
97216
}
98217

218+
/// @brief Dereference operator providing direct access to the hyperedge's properties.
219+
/// @return A reference to the underlying properties.
220+
/// @throws std::logic_error If the descriptor is invalid.
99221
[[nodiscard]] gl_attr_force_inline properties_type& operator*() const
100222
requires(traits::c_non_empty_properties<properties_type>)
101223
{
102224
this->_validate();
103225
return this->_properties.get();
104226
}
105227

228+
/// @brief Serializes the hyperedge descriptor to an output stream.
229+
///
230+
/// Depending on active stream flags, this outputs the descriptor in verbose or concise formats.
231+
///
232+
/// @param os The target output stream.
233+
/// @param hyperedge The hyperedge descriptor to format.
234+
/// @return The stream reference for chaining.
106235
friend std::ostream& operator<<(std::ostream& os, const hyperedge_descriptor& hyperedge) {
107236
using enum io::detail::option_bit;
108237

@@ -154,15 +283,29 @@ class hyperedge_descriptor final {
154283

155284
// --- hypergraph element tags ---
156285

286+
/// @ingroup HGL-Core
287+
/// @brief Tag type representing a vertex element in a hypergraph.
157288
struct vertex_t {};
158289

290+
/// @ingroup HGL-Core
291+
/// @brief Tag type representing a hyperedge element in a hypergraph.
159292
struct hyperedge_t {};
160293

294+
/// @ingroup HGL-Core
295+
/// @brief A constant instance of `vertex_t` used for tagging and generic dispatching.
161296
inline constexpr vertex_t vertex{};
297+
/// @ingroup HGL-Core
298+
/// @brief A constant instance of `hyperedge_t` used for tagging and generic dispatching.
162299
inline constexpr hyperedge_t hyperedge{};
163300

164301
namespace traits {
165302

303+
/// @ingroup HGL-Traits
304+
/// @brief Validates if a type is a valid hypergraph element tag.
305+
///
306+
/// The valid hypergraph element tags are @ref hgl::vertex_t "vertex_t" and @ref hgl::hyperedge_t "hyperedge_t".
307+
///
308+
/// @tparam T The type to evaluate against the concept.
166309
template <typename T>
167310
concept c_hypergraph_element_tag = c_one_of<T, vertex_t, hyperedge_t>;
168311

include/hgl/traits.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#pragma once
99

1010
#include "gl/traits.hpp"
11-
#include "hgl/types.hpp"
1211

1312
namespace hgl {
1413

0 commit comments

Comments
 (0)