Skip to content

Commit 7355b1e

Browse files
committed
graph docs alignment
1 parent e9d438c commit 7355b1e

4 files changed

Lines changed: 33 additions & 60 deletions

File tree

include/gl/graph.hpp

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ struct to_impl;
145145
/// auto e12 = g.add_edge(v1, v2);
146146
/// auto e20 = g.add_edge(v2, v0);
147147
///
148-
/// // (4)!
149-
/// std::cout << "Vertices: " << g.n_vertices() << '\n';
148+
/// std::cout << "Vertices: " << g.n_vertices() << '\n'; // (4)!
150149
/// std::cout << "Edges: " << g.n_edges() << '\n';
151150
///
152151
/// for (auto neighbor : g.neighbors(v0)) // (5)!
@@ -174,8 +173,8 @@ struct to_impl;
174173
/// - **Performance**: Descriptor-returning methods incur a slight overhead if the graph utilizes rich properties, as the descriptor must fetch the property payload. If you only need topology, prefer the `_ids` variants.
175174
///
176175
/// ### Descriptor Invalidation Behavior
177-
///
178176
/// The graph maintains the following invalidation semantics:
177+
///
179178
/// - **Vertex addition**: Does not invalidate vertex IDs. However, property references stored in vertex descriptors may be invalidated.
180179
/// - **Vertex removal**: Invalidates vertex descriptors, IDs, and property references. Subsequent vertex IDs may shift depending on the implementation.
181180
/// - **Edge addition**: Does not invalidate vertex or edge IDs. However, property references stored in edge descriptors may be invalidated.
@@ -193,10 +192,17 @@ struct to_impl;
193192
/// - @ref gl::clone "clone" : Create a deep copy of a graph.
194193
/// - @ref gl::to "to" : Convert a graph to a different implementation.
195194
///
196-
/// > [!IMPORTANT] Const Correctness
195+
/// > [!IMPORTANT] Copy Semantics
197196
/// >
198197
/// > `graph` supports move semantics but disables copy assignment to prevent accidental expensive copies.
199198
/// > Use @ref gl::clone "clone" to explicitly copy a graph.
199+
///
200+
/// > [!WARNING] Const Correctness & Properties (API Note)
201+
/// >
202+
/// > Currently, a `const` graph guarantees **structural immutability** (vertices and edges cannot be added or removed).
203+
/// > However, vertex and edge property maps are internally treated as `mutable`. This means that property payloads
204+
/// > can still be modified through a `const graph&`. Strict const-correct overloads for property access are planned
205+
/// > for a future release. Proceed with caution in multi-threaded contexts.
200206
template <traits::c_instantiation_of<graph_traits> GraphTraits>
201207
class graph final {
202208
public:
@@ -292,10 +298,7 @@ class graph final {
292298
/// @brief Adds a new vertex with specific properties.
293299
/// @param properties The property payload for the new vertex.
294300
/// @return A descriptor for the newly created vertex.
295-
///
296-
/// > [!IMPORTANT] ID Stability
297-
/// >
298-
/// > Adding vertices does **not** invalidate existing vertex IDs. **However**, property references stored in vertex descriptors may be invalidated.
301+
/// @copydetails add_vertex()
299302
vertex_type add_vertex_with(vertex_properties_type properties)
300303
requires(traits::c_non_empty_properties<vertex_properties_type>)
301304
{
@@ -308,10 +311,7 @@ class graph final {
308311

309312
/// @brief Adds a specified number of default-initialized vertices to the graph en masse.
310313
/// @param n The number of vertices to add.
311-
///
312-
/// > [!IMPORTANT] ID Stability
313-
/// >
314-
/// > Adding vertices does **not** invalidate existing vertex IDs. **However**, property references stored in vertex descriptors may be invalidated.
314+
/// @copydetails add_vertex()
315315
void add_vertices(const size_type n) {
316316
this->_impl.add_vertices(n);
317317
this->_n_vertices += n;
@@ -322,10 +322,7 @@ class graph final {
322322

323323
/// @brief Adds multiple vertices based on a range of property payloads.
324324
/// @param properties_rng A range of properties to initialize the new vertices with.
325-
///
326-
/// > [!IMPORTANT] ID Stability
327-
/// >
328-
/// > Adding vertices does **not** invalidate existing vertex IDs. **However**, property references stored in vertex descriptors may be invalidated.
325+
/// @copydetails add_vertex()
329326
void add_vertices_with(
330327
const traits::c_sized_range_of<vertex_properties_type> auto& properties_rng
331328
)
@@ -365,57 +362,35 @@ class graph final {
365362
/// @brief Removes a vertex using its descriptor.
366363
/// @param vertex The descriptor of the vertex to remove.
367364
/// @throws std::out_of_range If the vertex descriptor is invalid.
368-
///
369-
/// > [!WARNING] Descriptor and ID Invalidation
370-
/// >
371-
/// > Removing a vertex invalidates:
372-
/// > - All vertex descriptors and IDs for vertices with higher IDs (they shift down).
373-
/// > - All edge descriptors and IDs for edges incident to this vertex.
374-
/// > - All references to vertex and edge properties obtained from the property maps.
375-
/// > - References to vertex properties obtained via `vertex_properties()`.
365+
/// @copydetails remove_vertex(const id_type)
376366
gl_attr_force_inline void remove_vertex(vertex_type vertex) {
377367
this->remove_vertex(vertex.id());
378368
}
379369

380370
/// @brief Removes a range of vertices using their IDs.
381371
/// @param vertex_id_rng A forward range containing the IDs of vertices to remove.
382372
/// @throws std::out_of_range If any vertex ID in the range is invalid.
383-
///
384-
/// > [!WARNING] Descriptor and ID Invalidation
385-
/// >
386-
/// > Removing vertices invalidates:
387-
/// > - All vertex descriptors and IDs for vertices with higher IDs (they shift down).
388-
/// > - All edge descriptors and IDs for edges incident to removed vertices.
389-
/// > - All references to vertex and edge properties obtained from the property maps.
390-
void remove_vertices_from(const traits::c_forward_range_of<id_type> auto& vertex_id_rng) {
373+
/// @copydetails remove_vertex(const id_type)
374+
void remove_vertices(const traits::c_forward_range_of<id_type> auto& vertex_id_rng) {
375+
// TODO: optimize
391376
// sorts the ids in a descending order and removes duplicate ids
392377
std::set<id_type, std::greater<>> vertex_id_set(
393378
std::ranges::begin(vertex_id_rng), std::ranges::end(vertex_id_rng)
394379
);
380+
if (not vertex_id_set.empty())
381+
this->_verify_vertex_id(*vertex_id_set.begin());
395382

396-
// TODO: optimize
397383
for (auto vertex_id : vertex_id_set)
398384
this->_remove_vertex_impl(vertex_id);
399385
}
400386

401387
/// @brief Removes a range of vertices using their descriptors.
402388
/// @param vertex_rng A sized range containing the descriptors of vertices to remove.
403389
/// @throws std::out_of_range If any vertex descriptor is invalid.
404-
///
405-
/// > [!WARNING] Descriptor and ID Invalidation
406-
/// >
407-
/// > Removing vertices invalidates:
408-
/// > - All vertex descriptors and IDs for vertices with higher IDs (they shift down).
409-
/// > - All edge descriptors and IDs for edges incident to removed vertices.
410-
/// > - All references to vertex and edge properties obtained from the property maps.
411-
void remove_vertices_from(const traits::c_sized_range_of<vertex_type> auto& vertex_rng) {
412-
// TODO: optimize
413-
// sort the ids in a descending order and removes duplicate ids
414-
std::set<vertex_type, std::greater<vertex_type>> vertex_set(
415-
std::ranges::begin(vertex_rng), std::ranges::end(vertex_rng)
416-
);
417-
for (auto vertex : vertex_set)
418-
this->_remove_vertex_impl(vertex.id());
390+
/// @copydetails remove_vertex(const id_type)
391+
void remove_vertices(const traits::c_sized_range_of<vertex_type> auto& vertex_rng) {
392+
auto id_view = vertex_rng | std::views::transform([](const auto& v) { return v.id(); });
393+
this->remove_vertices(id_view);
419394
}
420395

421396
// --- vertex getters ---
@@ -658,8 +633,8 @@ class graph final {
658633
/// \f$
659634
/// deg(v) =
660635
/// \begin{cases}
661-
/// deg_{in}(v) + deg_{out}(v) & \text{if } G \text{ is directed} \\
662-
/// 2 \cdot |L(v)| + |E(v) \setminus L(v)| & \text{if } G \text{ is undirected}
636+
/// deg_{in}(v) + deg_{out}(v) & \text{if } G \text{ is directed}
637+
/// \\ 2 \cdot |L(v)| + |E(v) \setminus L(v)| & \text{if } G \text{ is undirected}
663638
/// \end{cases}
664639
/// \f$
665640
///

include/hgl/hypergraph.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class hypergraph final {
186186
this->remove_vertex(vertex.id());
187187
}
188188

189-
void remove_vertices_from(const traits::c_forward_range_of<id_type> auto& vertex_id_rng) {
189+
void remove_vertices(const traits::c_forward_range_of<id_type> auto& vertex_id_rng) {
190190
// sorts ids in a descending n_vertices and removes duplicate ids
191191
std::set<id_type, std::greater<id_type>> vertex_id_set(
192192
std::ranges::begin(vertex_id_rng), std::ranges::end(vertex_id_rng)
@@ -197,7 +197,7 @@ class hypergraph final {
197197
this->_remove_vertex_impl(vertex_id);
198198
}
199199

200-
void remove_vertices_from(const traits::c_sized_range_of<vertex_type> auto& vertex_rng) {
200+
void remove_vertices(const traits::c_sized_range_of<vertex_type> auto& vertex_rng) {
201201
// sort vertices in a descending n_vertices (by id) and removes duplicate ids
202202
std::set<vertex_type, std::greater<vertex_type>> vertex_set(
203203
std::ranges::begin(vertex_rng), std::ranges::end(vertex_rng)

tests/source/gl/test_graph.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,7 @@ TEST_CASE_TEMPLATE_DEFINE("common graph structure tests", TraitsType, common_gra
277277
sut_type sut{n_vertices};
278278
fixture.init_complete_graph(sut);
279279

280-
sut.remove_vertices_from(
281-
vertex_id_list{constants::v1_id, constants::v3_id, constants::v1_id}
282-
);
280+
sut.remove_vertices(vertex_id_list{constants::v1_id, constants::v3_id, constants::v1_id});
283281

284282
constexpr auto expected_n_vertices = n_vertices - 2uz;
285283
REQUIRE_EQ(sut.n_vertices(), expected_n_vertices);
@@ -300,7 +298,7 @@ TEST_CASE_TEMPLATE_DEFINE("common graph structure tests", TraitsType, common_gra
300298
const auto v1 = sut[constants::v1_id];
301299
const auto v3 = sut[constants::v3_id];
302300

303-
sut.remove_vertices_from(std::vector<vertex_type>{v1, v3, v1});
301+
sut.remove_vertices(std::vector<vertex_type>{v1, v3, v1});
304302

305303
constexpr auto expected_n_vertices = n_vertices - 2uz;
306304
REQUIRE_EQ(sut.n_vertices(), expected_n_vertices);

tests/source/hgl/test_hypergraph.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,27 +186,27 @@ TEST_CASE_TEMPLATE_DEFINE(
186186
CHECK_THROWS_AS(discard(sut.vertex(constants::n_vertices - 1uz)), std::out_of_range);
187187
}
188188

189-
SUBCASE("remove_vertices_from(ids) should properly remove elements at given indices (ignoring "
189+
SUBCASE("remove_vertices(ids) should properly remove elements at given indices (ignoring "
190190
"duplicate indices)") {
191191
constexpr auto n_vertices = constants::n_vertices + 1uz;
192192

193193
sut_type sut{n_vertices};
194-
sut.remove_vertices_from(
194+
sut.remove_vertices(
195195
std::vector<hgl::default_id_type>{constants::id1, constants::id3, constants::id1}
196196
);
197197

198198
constexpr auto expected_n_vertices = n_vertices - 2uz;
199199
REQUIRE_EQ(sut.n_vertices(), expected_n_vertices);
200200
}
201201

202-
SUBCASE("remove_vertices_from(vertices) should properly remove elements at given indices "
202+
SUBCASE("remove_vertices(vertices) should properly remove elements at given indices "
203203
"(ignoring duplicate vertices)") {
204204
constexpr auto n_vertices = constants::n_vertices + 1uz;
205205

206206
sut_type sut{n_vertices};
207207
const auto v1 = sut.vertex(constants::id1);
208208
const auto v3 = sut.vertex(constants::id3);
209-
sut.remove_vertices_from(std::vector<vertex_type>{v1, v3, v1});
209+
sut.remove_vertices(std::vector<vertex_type>{v1, v3, v1});
210210

211211
constexpr auto expected_n_vertices = n_vertices - 2uz;
212212
REQUIRE_EQ(sut.n_vertices(), expected_n_vertices);

0 commit comments

Comments
 (0)