Skip to content

Commit 296cb4c

Browse files
committed
missing methods + most tests
1 parent 062da83 commit 296cb4c

3 files changed

Lines changed: 401 additions & 114 deletions

File tree

include/hgl/hypergraph.hpp

Lines changed: 120 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class hypergraph final {
2121
using traits_type = HypergraphTraits;
2222
using directional_tag = typename traits_type::directional_tag;
2323
using implementation_tag = typename traits_type::implementation_tag;
24+
using implementation_type = typename implementation_tag::implementation_type<directional_tag>;
2425

2526
using vertex_type = typename traits_type::vertex_type;
2627
using vertex_properties_type = typename traits_type::vertex_properties_type;
@@ -40,7 +41,7 @@ class hypergraph final {
4041
hypergraph& operator=(const hypergraph&) = delete;
4142

4243
hypergraph(const types::size_type n_vertices = 0uz, const types::size_type n_hyperedges = 0uz)
43-
: _n_vertices(n_vertices), _n_hyperedges(n_hyperedges) {
44+
: _n_vertices(n_vertices), _n_hyperedges(n_hyperedges), _impl(n_vertices, n_hyperedges) {
4445
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
4546
this->_vertex_properties.reserve(n_vertices);
4647
for (const auto _ : this->vertex_ids())
@@ -67,21 +68,8 @@ class hypergraph final {
6768

6869
// --- vertex methods ---
6970

70-
[[nodiscard]] gl_attr_force_inline auto vertices() const
71-
requires(type_traits::c_empty_properties<vertex_properties_type>)
72-
{
73-
return this->vertex_ids()
74-
| std::views::transform([](const types::id_type id) { return vertex_type{id}; });
75-
}
76-
77-
[[nodiscard]] gl_attr_force_inline auto vertices() const
78-
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
79-
{
80-
return this->_vertex_properties | std::views::enumerate
81-
| std::views::transform([](const auto& property_item) {
82-
const auto& [id, ptr] = property_item;
83-
return vertex_type{static_cast<types::id_type>(id), *ptr};
84-
});
71+
[[nodiscard]] gl_attr_force_inline auto vertices() noexcept {
72+
return this->vertex_ids() | std::views::transform(this->_create_vertex_descriptor());
8573
}
8674

8775
[[nodiscard]] gl_attr_force_inline auto vertex_ids() const noexcept {
@@ -105,7 +93,7 @@ class hypergraph final {
10593
}
10694

10795
vertex_type add_vertex() {
108-
// this->_impl.add_vertex();
96+
this->_impl.add_vertices(1uz);
10997
const auto new_vertex_id = this->_n_vertices++;
11098

11199
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
@@ -120,7 +108,7 @@ class hypergraph final {
120108
vertex_type add_vertex_with(vertex_properties_type properties)
121109
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
122110
{
123-
// this->_impl.add_vertex();
111+
this->_impl.add_vertices(1uz);
124112
return vertex_type{
125113
this->_n_vertices++,
126114
*this->_vertex_properties.emplace_back(
@@ -130,7 +118,7 @@ class hypergraph final {
130118
}
131119

132120
void add_vertices(const types::size_type n) {
133-
// this->_impl.add_vertices(n);
121+
this->_impl.add_vertices(n);
134122
this->_n_vertices += n;
135123

136124
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
@@ -148,7 +136,7 @@ class hypergraph final {
148136
{
149137
const auto n = std::ranges::size(properties_range);
150138

151-
// this->_impl.add_vertices(n);
139+
this->_impl.add_vertices(n);
152140
this->_n_vertices += n;
153141

154142
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
@@ -160,8 +148,7 @@ class hypergraph final {
160148
}
161149
}
162150

163-
void remove_vertex(const types::id_type vertex_id) {
164-
this->_verify_vertex_id(vertex_id);
151+
gl_attr_force_inline void remove_vertex(const types::id_type vertex_id) {
165152
this->_remove_vertex_impl(vertex_id);
166153
}
167154

@@ -210,21 +197,8 @@ class hypergraph final {
210197

211198
// --- hyperedge methods ---
212199

213-
[[nodiscard]] gl_attr_force_inline auto hyperedges() const
214-
requires(type_traits::c_empty_properties<hyperedge_properties_type>)
215-
{
216-
return this->hyperedge_ids()
217-
| std::views::transform([](const types::id_type id) { return hyperedge_type{id}; });
218-
}
219-
220-
[[nodiscard]] gl_attr_force_inline auto hyperedges() const
221-
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
222-
{
223-
return this->_hyperedge_properties | std::views::enumerate
224-
| std::views::transform([](const auto& property_item) {
225-
const auto& [id, ptr] = property_item;
226-
return hyperedge_type{static_cast<types::id_type>(id), *ptr};
227-
});
200+
[[nodiscard]] gl_attr_force_inline auto hyperedges() noexcept {
201+
return this->hyperedge_ids() | std::views::transform(this->_create_hyperedge_descriptor());
228202
}
229203

230204
[[nodiscard]] gl_attr_force_inline auto hyperedge_ids() const noexcept {
@@ -248,7 +222,7 @@ class hypergraph final {
248222
}
249223

250224
hyperedge_type add_hyperedge() {
251-
// this->_impl.add_hyperedge();
225+
this->_impl.add_hyperedges(1uz);
252226
const auto new_hyperedge_id = this->_n_hyperedges++;
253227

254228
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
@@ -265,7 +239,7 @@ class hypergraph final {
265239
hyperedge_type add_hyperedge_with(hyperedge_properties_type properties)
266240
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
267241
{
268-
// this->_impl.add_hyperedge();
242+
this->_impl.add_hyperedges(1uz);
269243
return hyperedge_type{
270244
this->_n_hyperedges++,
271245
*this->_hyperedge_properties.emplace_back(
@@ -275,7 +249,7 @@ class hypergraph final {
275249
}
276250

277251
void add_hyperedges(const types::size_type n) {
278-
// this->_impl.add_hyperedges(n);
252+
this->_impl.add_hyperedges(n);
279253
this->_n_hyperedges += n;
280254

281255
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
@@ -294,7 +268,7 @@ class hypergraph final {
294268
{
295269
const auto n = std::ranges::size(properties_range);
296270

297-
// this->_impl.add_hyperedges(n);
271+
this->_impl.add_hyperedges(n);
298272
this->_n_hyperedges += n;
299273

300274
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
@@ -306,8 +280,7 @@ class hypergraph final {
306280
}
307281
}
308282

309-
void remove_hyperedge(const types::id_type hyperedge_id) {
310-
this->_verify_hyperedge_id(hyperedge_id);
283+
gl_attr_force_inline void remove_hyperedge(const types::id_type hyperedge_id) {
311284
this->_remove_hyperedge_impl(hyperedge_id);
312285
}
313286

@@ -356,6 +329,68 @@ class hypergraph final {
356329
return *this->_hyperedge_properties[id];
357330
}
358331

332+
// --- incidence methods ---
333+
334+
void bind(const types::id_type vertex_id, const types::id_type hyperedge_id) {
335+
this->_verify_vertex_id(vertex_id);
336+
this->_verify_hyperedge_id(hyperedge_id);
337+
this->_impl.bind(vertex_id, hyperedge_id);
338+
}
339+
340+
gl_attr_force_inline void bind(const vertex_type& vertex, const hyperedge_type& hyperedge) {
341+
this->bind(vertex.id(), hyperedge.id());
342+
}
343+
344+
void unbind(const types::id_type vertex_id, const types::id_type hyperedge_id) {
345+
this->_verify_vertex_id(vertex_id);
346+
this->_verify_hyperedge_id(hyperedge_id);
347+
this->_impl.unbind(vertex_id, hyperedge_id);
348+
}
349+
350+
gl_attr_force_inline void unbind(const vertex_type& vertex, const hyperedge_type& hyperedge) {
351+
this->unbind(vertex.id(), hyperedge.id());
352+
}
353+
354+
[[nodiscard]] auto incident_hyperedges(const types::id_type vertex_id) {
355+
this->_verify_vertex_id(vertex_id);
356+
return this->_impl.incident_hyperedges(vertex_id)
357+
| std::views::transform(this->_create_hyperedge_descriptor());
358+
}
359+
360+
[[nodiscard]] gl_attr_force_inline auto incident_hyperedges(const vertex_type& vertex) {
361+
return this->incident_hyperedges(vertex.id());
362+
}
363+
364+
[[nodiscard]] types::size_type degree(const types::id_type vertex_id) const {
365+
this->_verify_vertex_id(vertex_id);
366+
return this->_impl.degree(vertex_id);
367+
}
368+
369+
[[nodiscard]] gl_attr_force_inline types::size_type degree(const vertex_type& vertex) const {
370+
return this->degree(vertex.id());
371+
}
372+
373+
[[nodiscard]] auto incident_vertices(const types::id_type hyperedge_id) {
374+
this->_verify_hyperedge_id(hyperedge_id);
375+
return this->_impl.incident_vertices(hyperedge_id)
376+
| std::views::transform(this->_create_vertex_descriptor());
377+
}
378+
379+
[[nodiscard]] gl_attr_force_inline auto incident_vertices(const hyperedge_type& hyperedge) {
380+
return this->incident_vertices(hyperedge.id());
381+
}
382+
383+
[[nodiscard]] types::size_type hyperedge_size(const types::id_type hyperedge_id) const {
384+
this->_verify_hyperedge_id(hyperedge_id);
385+
return this->_impl.hyperedge_size(hyperedge_id);
386+
}
387+
388+
[[nodiscard]] gl_attr_force_inline types::size_type hyperedge_size(
389+
const hyperedge_type& hyperedge
390+
) const {
391+
return this->hyperedge_size(hyperedge.id());
392+
}
393+
359394
private:
360395
// --- vertex methods ---
361396

@@ -365,10 +400,13 @@ class hypergraph final {
365400
}
366401

367402
void _remove_vertex_impl(const types::id_type vertex_id) {
403+
if (not this->has_vertex(vertex_id))
404+
return;
405+
406+
this->_impl.remove_vertex(vertex_id);
368407
this->_n_vertices--;
369408
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
370409
this->_vertex_properties.erase(this->_vertex_properties.begin() + vertex_id);
371-
// TODO: impl::remove_vertex(vertex_id)
372410
}
373411

374412
// --- hyperedge methods ---
@@ -379,14 +417,52 @@ class hypergraph final {
379417
}
380418

381419
void _remove_hyperedge_impl(const types::id_type hyperedge_id) {
420+
if (not this->has_hyperedge(hyperedge_id))
421+
return;
422+
423+
this->_impl.remove_hyperedge(hyperedge_id);
382424
this->_n_hyperedges--;
383425
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
384426
this->_hyperedge_properties.erase(this->_hyperedge_properties.begin() + hyperedge_id);
385427
}
386428

429+
// --- transformations ---
430+
431+
gl_attr_force_inline auto _create_vertex_descriptor() noexcept
432+
requires(type_traits::c_empty_properties<vertex_properties_type>)
433+
{
434+
return [](const types::id_type id) { return vertex_type{id}; };
435+
}
436+
437+
gl_attr_force_inline auto _create_vertex_descriptor() noexcept
438+
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
439+
{
440+
return [&pmap = this->_vertex_properties](const types::id_type id) {
441+
return vertex_type{id, *pmap[id]};
442+
};
443+
}
444+
445+
gl_attr_force_inline auto _create_hyperedge_descriptor() noexcept
446+
requires(type_traits::c_empty_properties<hyperedge_properties_type>)
447+
{
448+
return [](const types::id_type id) { return hyperedge_type{id}; };
449+
}
450+
451+
gl_attr_force_inline auto _create_hyperedge_descriptor() noexcept
452+
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
453+
{
454+
return [&pmap = this->_hyperedge_properties](const types::id_type id) {
455+
return hyperedge_type{id, *pmap[id]};
456+
};
457+
}
458+
459+
// --- data members ---
460+
387461
types::size_type _n_vertices = 0uz;
388462
types::size_type _n_hyperedges = 0uz;
389463

464+
implementation_type _impl{};
465+
390466
[[no_unique_address]] vertex_properties_map_type _vertex_properties{};
391467
[[no_unique_address]] hyperedge_properties_map_type _hyperedge_properties{};
392468
};

include/hgl/impl/impl_tags.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#pragma once
66

77
#include "hgl/directional_tags.hpp"
8+
#include "hgl/impl/incidence_list.hpp"
9+
#include "hgl/impl/incidence_matrix.hpp"
810
#include "hgl/impl/layout_tags.hpp"
911
#include "hgl/types/type_traits.hpp"
1012
#include "hgl/types/types.hpp"
@@ -16,11 +18,17 @@ namespace impl {
1618
template <type_traits::c_hypergraph_layout_tag LayoutTag>
1719
struct list_t {
1820
using layout_tag = LayoutTag;
21+
22+
template <type_traits::c_hypergraph_directional_tag DirectionalTag>
23+
using implementation_type = incidence_list<DirectionalTag, LayoutTag>;
1924
};
2025

2126
template <type_traits::c_hypergraph_layout_tag LayoutTag>
2227
struct matrix_t {
2328
using layout_tag = LayoutTag;
29+
30+
template <type_traits::c_hypergraph_directional_tag DirectionalTag>
31+
using implementation_type = incidence_matrix<DirectionalTag, LayoutTag>;
2432
};
2533

2634
} // namespace impl

0 commit comments

Comments
 (0)