44
55#pragma once
66
7- #include " constants.hpp"
8- #include " hypergraph_traits.hpp"
9- #include " util.hpp"
7+ #include " hgl/ constants.hpp"
8+ #include " hgl/ hypergraph_traits.hpp"
9+ #include " hgl/ util.hpp"
1010
1111#include < memory>
1212#include < set>
@@ -21,6 +21,8 @@ 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 =
25+ typename implementation_tag::template implementation_type<directional_tag>;
2426
2527 using vertex_type = typename traits_type::vertex_type;
2628 using vertex_properties_type = typename traits_type::vertex_properties_type;
@@ -40,7 +42,7 @@ class hypergraph final {
4042 hypergraph& operator =(const hypergraph&) = delete ;
4143
4244 hypergraph (const types::size_type n_vertices = 0uz, const types::size_type n_hyperedges = 0uz)
43- : _n_vertices(n_vertices), _n_hyperedges(n_hyperedges) {
45+ : _n_vertices(n_vertices), _n_hyperedges(n_hyperedges), _impl(n_vertices, n_hyperedges) {
4446 if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
4547 this ->_vertex_properties .reserve (n_vertices);
4648 for (const auto _ : this ->vertex_ids ())
@@ -67,21 +69,8 @@ class hypergraph final {
6769
6870 // --- vertex methods ---
6971
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- });
72+ [[nodiscard]] gl_attr_force_inline auto vertices () noexcept {
73+ return this ->vertex_ids () | std::views::transform (this ->_create_vertex_descriptor ());
8574 }
8675
8776 [[nodiscard]] gl_attr_force_inline auto vertex_ids () const noexcept {
@@ -105,7 +94,7 @@ class hypergraph final {
10594 }
10695
10796 vertex_type add_vertex () {
108- // this->_impl.add_vertex( );
97+ this ->_impl .add_vertices (1uz );
10998 const auto new_vertex_id = this ->_n_vertices ++;
11099
111100 if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
@@ -120,7 +109,7 @@ class hypergraph final {
120109 vertex_type add_vertex_with (vertex_properties_type properties)
121110 requires(type_traits::c_non_empty_properties<vertex_properties_type>)
122111 {
123- // this->_impl.add_vertex( );
112+ this ->_impl .add_vertices (1uz );
124113 return vertex_type{
125114 this ->_n_vertices ++,
126115 *this ->_vertex_properties .emplace_back (
@@ -130,7 +119,7 @@ class hypergraph final {
130119 }
131120
132121 void add_vertices (const types::size_type n) {
133- // this->_impl.add_vertices(n);
122+ this ->_impl .add_vertices (n);
134123 this ->_n_vertices += n;
135124
136125 if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
@@ -148,7 +137,7 @@ class hypergraph final {
148137 {
149138 const auto n = std::ranges::size (properties_range);
150139
151- // this->_impl.add_vertices(n);
140+ this ->_impl .add_vertices (n);
152141 this ->_n_vertices += n;
153142
154143 if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
@@ -160,8 +149,7 @@ class hypergraph final {
160149 }
161150 }
162151
163- void remove_vertex (const types::id_type vertex_id) {
164- this ->_verify_vertex_id (vertex_id);
152+ gl_attr_force_inline void remove_vertex (const types::id_type vertex_id) {
165153 this ->_remove_vertex_impl (vertex_id);
166154 }
167155
@@ -210,21 +198,8 @@ class hypergraph final {
210198
211199 // --- hyperedge methods ---
212200
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- });
201+ [[nodiscard]] gl_attr_force_inline auto hyperedges () noexcept {
202+ return this ->hyperedge_ids () | std::views::transform (this ->_create_hyperedge_descriptor ());
228203 }
229204
230205 [[nodiscard]] gl_attr_force_inline auto hyperedge_ids () const noexcept {
@@ -248,7 +223,7 @@ class hypergraph final {
248223 }
249224
250225 hyperedge_type add_hyperedge () {
251- // this->_impl.add_hyperedge( );
226+ this ->_impl .add_hyperedges (1uz );
252227 const auto new_hyperedge_id = this ->_n_hyperedges ++;
253228
254229 if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
@@ -265,7 +240,7 @@ class hypergraph final {
265240 hyperedge_type add_hyperedge_with (hyperedge_properties_type properties)
266241 requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
267242 {
268- // this->_impl.add_hyperedge( );
243+ this ->_impl .add_hyperedges (1uz );
269244 return hyperedge_type{
270245 this ->_n_hyperedges ++,
271246 *this ->_hyperedge_properties .emplace_back (
@@ -275,7 +250,7 @@ class hypergraph final {
275250 }
276251
277252 void add_hyperedges (const types::size_type n) {
278- // this->_impl.add_hyperedges(n);
253+ this ->_impl .add_hyperedges (n);
279254 this ->_n_hyperedges += n;
280255
281256 if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
@@ -294,7 +269,7 @@ class hypergraph final {
294269 {
295270 const auto n = std::ranges::size (properties_range);
296271
297- // this->_impl.add_hyperedges(n);
272+ this ->_impl .add_hyperedges (n);
298273 this ->_n_hyperedges += n;
299274
300275 if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
@@ -306,8 +281,7 @@ class hypergraph final {
306281 }
307282 }
308283
309- void remove_hyperedge (const types::id_type hyperedge_id) {
310- this ->_verify_hyperedge_id (hyperedge_id);
284+ gl_attr_force_inline void remove_hyperedge (const types::id_type hyperedge_id) {
311285 this ->_remove_hyperedge_impl (hyperedge_id);
312286 }
313287
@@ -356,6 +330,82 @@ class hypergraph final {
356330 return *this ->_hyperedge_properties [id];
357331 }
358332
333+ // --- incidence methods ---
334+
335+ void bind (const types::id_type vertex_id, const types::id_type hyperedge_id) {
336+ this ->_verify_vertex_id (vertex_id);
337+ this ->_verify_hyperedge_id (hyperedge_id);
338+ this ->_impl .bind (vertex_id, hyperedge_id);
339+ }
340+
341+ gl_attr_force_inline void bind (const vertex_type& vertex, const hyperedge_type& hyperedge) {
342+ this ->bind (vertex.id (), hyperedge.id ());
343+ }
344+
345+ void unbind (const types::id_type vertex_id, const types::id_type hyperedge_id) {
346+ this ->_verify_vertex_id (vertex_id);
347+ this ->_verify_hyperedge_id (hyperedge_id);
348+ this ->_impl .unbind (vertex_id, hyperedge_id);
349+ }
350+
351+ gl_attr_force_inline void unbind (const vertex_type& vertex, const hyperedge_type& hyperedge) {
352+ this ->unbind (vertex.id (), hyperedge.id ());
353+ }
354+
355+ [[nodiscard]] bool are_incident (
356+ const types::id_type vertex_id, const types::id_type hyperedge_id
357+ ) const {
358+ this ->_verify_vertex_id (vertex_id);
359+ this ->_verify_hyperedge_id (hyperedge_id);
360+ return this ->_impl .are_bound (vertex_id, hyperedge_id);
361+ }
362+
363+ [[nodiscard]] gl_attr_force_inline bool are_incident (
364+ const vertex_type& vertex, const hyperedge_type& hyperedge
365+ ) const {
366+ return this ->are_incident (vertex.id (), hyperedge.id ());
367+ }
368+
369+ [[nodiscard]] auto incident_hyperedges (const types::id_type vertex_id) {
370+ this ->_verify_vertex_id (vertex_id);
371+ return this ->_impl .incident_hyperedges (vertex_id)
372+ | std::views::transform (this ->_create_hyperedge_descriptor ());
373+ }
374+
375+ [[nodiscard]] gl_attr_force_inline auto incident_hyperedges (const vertex_type& vertex) {
376+ return this ->incident_hyperedges (vertex.id ());
377+ }
378+
379+ [[nodiscard]] types::size_type degree (const types::id_type vertex_id) const {
380+ this ->_verify_vertex_id (vertex_id);
381+ return this ->_impl .degree (vertex_id);
382+ }
383+
384+ [[nodiscard]] gl_attr_force_inline types::size_type degree (const vertex_type& vertex) const {
385+ return this ->degree (vertex.id ());
386+ }
387+
388+ [[nodiscard]] auto incident_vertices (const types::id_type hyperedge_id) {
389+ this ->_verify_hyperedge_id (hyperedge_id);
390+ return this ->_impl .incident_vertices (hyperedge_id)
391+ | std::views::transform (this ->_create_vertex_descriptor ());
392+ }
393+
394+ [[nodiscard]] gl_attr_force_inline auto incident_vertices (const hyperedge_type& hyperedge) {
395+ return this ->incident_vertices (hyperedge.id ());
396+ }
397+
398+ [[nodiscard]] types::size_type hyperedge_size (const types::id_type hyperedge_id) const {
399+ this ->_verify_hyperedge_id (hyperedge_id);
400+ return this ->_impl .hyperedge_size (hyperedge_id);
401+ }
402+
403+ [[nodiscard]] gl_attr_force_inline types::size_type hyperedge_size (
404+ const hyperedge_type& hyperedge
405+ ) const {
406+ return this ->hyperedge_size (hyperedge.id ());
407+ }
408+
359409private:
360410 // --- vertex methods ---
361411
@@ -365,10 +415,13 @@ class hypergraph final {
365415 }
366416
367417 void _remove_vertex_impl (const types::id_type vertex_id) {
418+ if (not this ->has_vertex (vertex_id))
419+ return ;
420+
421+ this ->_impl .remove_vertex (vertex_id);
368422 this ->_n_vertices --;
369423 if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
370424 this ->_vertex_properties .erase (this ->_vertex_properties .begin () + vertex_id);
371- // TODO: impl::remove_vertex(vertex_id)
372425 }
373426
374427 // --- hyperedge methods ---
@@ -379,14 +432,52 @@ class hypergraph final {
379432 }
380433
381434 void _remove_hyperedge_impl (const types::id_type hyperedge_id) {
435+ if (not this ->has_hyperedge (hyperedge_id))
436+ return ;
437+
438+ this ->_impl .remove_hyperedge (hyperedge_id);
382439 this ->_n_hyperedges --;
383440 if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
384441 this ->_hyperedge_properties .erase (this ->_hyperedge_properties .begin () + hyperedge_id);
385442 }
386443
444+ // --- transformations ---
445+
446+ gl_attr_force_inline auto _create_vertex_descriptor () noexcept
447+ requires(type_traits::c_empty_properties<vertex_properties_type>)
448+ {
449+ return [](const types::id_type id) { return vertex_type{id}; };
450+ }
451+
452+ gl_attr_force_inline auto _create_vertex_descriptor () noexcept
453+ requires(type_traits::c_non_empty_properties<vertex_properties_type>)
454+ {
455+ return [&pmap = this ->_vertex_properties ](const types::id_type id) {
456+ return vertex_type{id, *pmap[id]};
457+ };
458+ }
459+
460+ gl_attr_force_inline auto _create_hyperedge_descriptor () noexcept
461+ requires(type_traits::c_empty_properties<hyperedge_properties_type>)
462+ {
463+ return [](const types::id_type id) { return hyperedge_type{id}; };
464+ }
465+
466+ gl_attr_force_inline auto _create_hyperedge_descriptor () noexcept
467+ requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
468+ {
469+ return [&pmap = this ->_hyperedge_properties ](const types::id_type id) {
470+ return hyperedge_type{id, *pmap[id]};
471+ };
472+ }
473+
474+ // --- data members ---
475+
387476 types::size_type _n_vertices = 0uz;
388477 types::size_type _n_hyperedges = 0uz;
389478
479+ implementation_type _impl{};
480+
390481 [[no_unique_address]] vertex_properties_map_type _vertex_properties{};
391482 [[no_unique_address]] hyperedge_properties_map_type _hyperedge_properties{};
392483};
0 commit comments