Skip to content

Commit fc53d23

Browse files
committed
wip: hyperedge directional tags -> hypergraph directional tags; hyperedge methods of hypergraph
1 parent 6fe140b commit fc53d23

8 files changed

Lines changed: 239 additions & 143 deletions

File tree

include/hgl/directional_tags.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2024-2026 Jakub Musiał
2+
// This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl).
3+
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
4+
5+
#pragma once
6+
7+
#include <type_traits>
8+
9+
namespace hgl {
10+
11+
struct undirected_t {
12+
using type = std::type_identity_t<undirected_t>;
13+
};
14+
15+
struct bf_directed_t {
16+
using type = std::type_identity_t<bf_directed_t>;
17+
};
18+
19+
} // namespace hgl

include/hgl/hyperedge_tags.hpp

Lines changed: 0 additions & 47 deletions
This file was deleted.

include/hgl/hypergraph.hpp

Lines changed: 152 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ class hypergraph final {
3838
hypergraph(const hypergraph&) = delete;
3939
hypergraph& operator=(const hypergraph&) = delete;
4040

41-
hypergraph() = default;
42-
43-
hypergraph(const types::size_type n_vertices) : _n_vertices(n_vertices) {
41+
hypergraph(const types::size_type n_vertices = 0uz, const types::size_type n_hyperedges = 0uz)
42+
: _n_vertices(n_vertices), _n_hyperedges(n_hyperedges) {
4443
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
4544
this->_vertex_properties.reserve(n_vertices);
4645
for (const auto _ : this->vertex_ids())
4746
this->_vertex_properties.push_back(std::make_unique<vertex_properties_type>());
4847
}
48+
49+
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
50+
this->_hyperedge_properties.reserve(n_hyperedges);
51+
for (const auto _ : this->hyperedge_ids())
52+
this->_hyperedge_properties.push_back(std::make_unique<hyperedge_properties_type>()
53+
);
54+
}
4955
}
5056

5157
// --- general methods ---
@@ -71,8 +77,8 @@ class hypergraph final {
7177
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
7278
{
7379
return this->_vertex_properties | std::views::enumerate
74-
| std::views::transform([](const auto& x) {
75-
const auto& [id, ptr] = x;
80+
| std::views::transform([](const auto& property_item) {
81+
const auto& [id, ptr] = property_item;
7682
return vertex_type{static_cast<types::id_type>(id), *ptr};
7783
});
7884
}
@@ -199,6 +205,147 @@ class hypergraph final {
199205
return *this->_vertex_properties[id];
200206
}
201207

208+
// --- hyperedge methods ---
209+
210+
[[nodiscard]] gl_attr_force_inline auto hyperedges() const
211+
requires(type_traits::c_empty_properties<hyperedge_properties_type>)
212+
{
213+
return this->hyperedge_ids()
214+
| std::views::transform([](const types::id_type id) { return hyperedge_type{id}; });
215+
}
216+
217+
[[nodiscard]] gl_attr_force_inline auto hyperedges() const
218+
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
219+
{
220+
return this->_hyperedge_properties | std::views::enumerate
221+
| std::views::transform([](const auto& property_item) {
222+
const auto& [id, ptr] = property_item;
223+
return vertex_type{static_cast<types::id_type>(id), *ptr};
224+
});
225+
}
226+
227+
[[nodiscard]] gl_attr_force_inline auto hyperedge_ids() const noexcept {
228+
return std::views::iota(constants::initial_id, this->_n_hyperedges);
229+
}
230+
231+
// [[nodiscard]] vertex_type get_vertex(const types::id_type vertex_id) const {
232+
// this->_verify_vertex_id(vertex_id);
233+
// if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
234+
// return vertex_type{vertex_id, *this->_vertex_properties[vertex_id]};
235+
// else
236+
// return vertex_type{vertex_id};
237+
// }
238+
239+
// [[nodiscard]] gl_attr_force_inline bool has_vertex(const types::id_type vertex_id) const {
240+
// return vertex_id < this->_n_vertices;
241+
// }
242+
243+
// [[nodiscard]] gl_attr_force_inline bool has_vertex(const vertex_type& vertex) const {
244+
// return this->has_vertex(vertex.id());
245+
// }
246+
247+
// vertex_type add_vertex() {
248+
// // this->_impl.add_vertex();
249+
// const auto new_vertex_id = this->_n_vertices++;
250+
251+
// if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
252+
// return vertex_type{
253+
// new_vertex_id,
254+
// *this->_vertex_properties.emplace_back(std::make_unique<vertex_properties_type>())
255+
// };
256+
// else
257+
// return vertex_type{new_vertex_id};
258+
// }
259+
260+
// vertex_type add_vertex_with(vertex_properties_type properties)
261+
// requires(type_traits::c_non_empty_properties<vertex_properties_type>)
262+
// {
263+
// // this->_impl.add_vertex();
264+
// this->_vertex_properties.push_back(
265+
// std::make_unique<vertex_properties_type>(std::move(properties))
266+
// );
267+
// return vertex_type{this->_n_vertices++, *this->_vertex_properties.back()};
268+
// }
269+
270+
// void add_vertices(const types::size_type n) {
271+
// // this->_impl.add_vertices(n);
272+
// this->_n_vertices += n;
273+
274+
// if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
275+
// const auto old_size = this->_vertex_properties.size();
276+
// this->_vertex_properties.reserve(this->_n_vertices);
277+
// for (types::size_type i = old_size; i < this->_n_vertices; ++i)
278+
// this->_vertex_properties.push_back(std::make_unique<vertex_properties_type>());
279+
// }
280+
// }
281+
282+
// void add_vertices_with(
283+
// const type_traits::c_sized_range_of<vertex_properties_type> auto& properties_range
284+
// )
285+
// requires(type_traits::c_non_empty_properties<vertex_properties_type>)
286+
// {
287+
// const auto n = std::ranges::size(properties_range);
288+
289+
// // this->_impl.add_vertices(n);
290+
// this->_n_vertices += n;
291+
292+
// if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
293+
// for (auto& properties : properties_range) {
294+
// this->_vertex_properties.emplace_back(
295+
// std::make_unique<vertex_properties_type>(properties)
296+
// );
297+
// }
298+
// }
299+
// }
300+
301+
// void remove_vertex(const types::size_type vertex_id) {
302+
// this->_verify_vertex_id(vertex_id);
303+
// this->_remove_vertex_impl(vertex_id);
304+
// }
305+
306+
// gl_attr_force_inline void remove_vertex(const vertex_type& vertex) {
307+
// this->remove_vertex(vertex.id());
308+
// }
309+
310+
// void remove_vertices_from(
311+
// const type_traits::c_forward_range_of<types::id_type> auto& vertex_id_range
312+
// ) {
313+
// // sorts the ids in a descending order and removes duplicate ids
314+
// std::set<types::id_type, std::greater<types::id_type>> vertex_id_set(
315+
// std::ranges::begin(vertex_id_range), std::ranges::end(vertex_id_range)
316+
// );
317+
318+
// // TODO: optimize
319+
// for (const auto vertex_id : vertex_id_set)
320+
// this->_remove_vertex_impl(vertex_id);
321+
// }
322+
323+
// void remove_vertices_from(const type_traits::c_sized_range_of<vertex_type> auto& vertex_range) {
324+
// // sort the ids in a descending order and removes duplicate ids
325+
// std::set<vertex_type, std::greater<vertex_type>> vertex_set(
326+
// std::ranges::begin(vertex_range), std::ranges::end(vertex_range)
327+
// );
328+
329+
// // TODO: optimize
330+
// for (const auto& vertex : vertex_set)
331+
// this->_remove_vertex_impl(vertex.id());
332+
// }
333+
334+
// [[nodiscard]] gl_attr_force_inline auto vertex_properties_map() const noexcept
335+
// requires(type_traits::c_non_empty_properties<vertex_properties_type>)
336+
// {
337+
// return util::deref_view(this->_vertex_properties);
338+
// }
339+
340+
// [[nodiscard]] gl_attr_force_inline vertex_properties_type& get_vertex_properties(
341+
// const types::id_type id
342+
// ) const
343+
// requires(type_traits::c_non_empty_properties<vertex_properties_type>)
344+
// {
345+
// this->_verify_vertex_id(id);
346+
// return *this->_vertex_properties[id];
347+
// }
348+
202349
private:
203350
// --- vertex methods ---
204351

include/hgl/hypergraph_elements.hpp

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,10 @@ using vertex_descriptor = gl::vertex_descriptor<Properties>;
1919

2020
// hyperedge descriptor
2121

22-
// TODO: validate whether a hyperedge descriptor requires a directional-tag
23-
// or if it could be replaced with a hypergraph directional-tag
24-
25-
template <
26-
type_traits::c_hyperedge_directional_tag DirectionalTag = undirected_t,
27-
type_traits::c_properties Properties = types::empty_properties>
22+
template <type_traits::c_properties Properties = types::empty_properties>
2823
class hyperedge_descriptor final {
2924
public:
30-
using type = hyperedge_descriptor<DirectionalTag, Properties>;
31-
using directional_tag = DirectionalTag;
25+
using type = hyperedge_descriptor<Properties>;
3226
using properties_type = Properties;
3327
using properties_ref_type = std::conditional_t<
3428
type_traits::c_empty_properties<properties_type>,
@@ -78,14 +72,6 @@ class hyperedge_descriptor final {
7872
return this->is_valid();
7973
}
8074

81-
[[nodiscard]] constexpr bool is_undirected() const noexcept {
82-
return type_traits::c_undirected_hyperedge<type>;
83-
}
84-
85-
[[nodiscard]] constexpr bool is_bf_directed() const noexcept {
86-
return type_traits::c_bf_directed_hyperedge<type>;
87-
}
88-
8975
[[nodiscard]] gl_attr_force_inline bool is_valid() const noexcept {
9076
return this->_id != constants::invalid_id;
9177
}
@@ -110,14 +96,8 @@ class hyperedge_descriptor final {
11096
};
11197

11298
template <
113-
type_traits::c_hyperedge_directional_tag DirectionalTag = undirected_t,
99+
type_traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
114100
type_traits::c_properties Properties = types::empty_properties>
115101
using hyperedge = hyperedge_descriptor<DirectionalTag, Properties>;
116102

117-
template <type_traits::c_properties Properties = types::empty_properties>
118-
using undirected_hyperedge = hyperedge_descriptor<undirected_t, Properties>;
119-
120-
template <type_traits::c_properties Properties = types::empty_properties>
121-
using bf_directed_hyperedge = hyperedge_descriptor<bf_directed_t, Properties>;
122-
123103
} // namespace hgl

include/hgl/hypergraph_traits.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
namespace hgl {
1111

1212
template <
13-
type_traits::c_hyperedge_directional_tag HyperedgeDirectionalTag = undirected_t,
13+
type_traits::c_hypergraph_directional_tag HyperedgeDirectionalTag = undirected_t,
1414
type_traits::c_properties VertexProperties = types::empty_properties,
1515
type_traits::c_properties HyperedgeProperties = types::empty_properties,
16-
type_traits::c_hypergraph_impl_tag ImplTag = impl::edge_list_t>
16+
type_traits::c_hypergraph_impl_tag ImplTag = impl::hyperedge_list_t>
1717
struct hypergraph_traits {
1818
using vertex_type = vertex_descriptor<VertexProperties>;
1919
using vertex_properties_type = typename vertex_type::properties_type;
@@ -26,17 +26,17 @@ struct hypergraph_traits {
2626
};
2727

2828
template <
29-
type_traits::c_hyperedge_directional_tag HyperedgeDirectionalTag = undirected_t,
29+
type_traits::c_hypergraph_directional_tag HyperedgeDirectionalTag = undirected_t,
3030
type_traits::c_properties VertexProperties = types::empty_properties,
3131
type_traits::c_properties HyperedgeProperties = types::empty_properties>
32-
using edge_list_hg_traits = hypergraph_traits<
32+
using hyperedge_list_hg_traits = hypergraph_traits<
3333
HyperedgeDirectionalTag,
3434
VertexProperties,
3535
HyperedgeProperties,
36-
impl::edge_list_t>;
36+
impl::hyperedge_list_t>;
3737

3838
template <
39-
type_traits::c_hyperedge_directional_tag HyperedgeDirectionalTag = undirected_t,
39+
type_traits::c_hypergraph_directional_tag HyperedgeDirectionalTag = undirected_t,
4040
type_traits::c_properties VertexProperties = types::empty_properties,
4141
type_traits::c_properties HyperedgeProperties = types::empty_properties>
4242
using adjacency_list_hg_traits = hypergraph_traits<
@@ -46,7 +46,7 @@ using adjacency_list_hg_traits = hypergraph_traits<
4646
impl::adjacency_list_t>;
4747

4848
template <
49-
type_traits::c_hyperedge_directional_tag HyperedgeDirectionalTag = undirected_t,
49+
type_traits::c_hypergraph_directional_tag HyperedgeDirectionalTag = undirected_t,
5050
type_traits::c_properties VertexProperties = types::empty_properties,
5151
type_traits::c_properties HyperedgeProperties = types::empty_properties>
5252
using incidence_matrix_hg_traits = hypergraph_traits<
@@ -58,23 +58,23 @@ using incidence_matrix_hg_traits = hypergraph_traits<
5858
template <
5959
type_traits::c_properties VertexProperties = types::empty_properties,
6060
type_traits::c_properties HyperedgeProperties = types::empty_properties,
61-
type_traits::c_hypergraph_impl_tag ImplTag = impl::edge_list_t>
61+
type_traits::c_hypergraph_impl_tag ImplTag = impl::hyperedge_list_t>
6262
using undirected_hg_traits =
6363
hypergraph_traits<undirected_t, VertexProperties, HyperedgeProperties, ImplTag>;
6464

6565
template <
6666
type_traits::c_properties VertexProperties = types::empty_properties,
6767
type_traits::c_properties HyperedgeProperties = types::empty_properties,
68-
type_traits::c_hypergraph_impl_tag ImplTag = impl::edge_list_t>
68+
type_traits::c_hypergraph_impl_tag ImplTag = impl::hyperedge_list_t>
6969
using bf_directed_hg_traits =
7070
hypergraph_traits<bf_directed_t, VertexProperties, HyperedgeProperties, ImplTag>;
7171

7272
namespace type_traits {
7373

7474
template <typename TraitsType>
75-
concept c_edge_list_hg_traits =
75+
concept c_hyperedge_list_hg_traits =
7676
c_instantiation_of<TraitsType, hypergraph_traits>
77-
and std::same_as<typename TraitsType::implementation_tag, impl::edge_list_t>;
77+
and std::same_as<typename TraitsType::implementation_tag, impl::hyperedge_list_t>;
7878

7979
template <typename TraitsType>
8080
concept c_adjacency_list_hg_traits =

include/hgl/impl/impl_tags.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace hgl {
1010

1111
namespace impl {
1212

13-
struct edge_list_t {};
13+
struct hyperedge_list_t {};
1414

1515
struct adjacency_list_t {};
1616

@@ -22,7 +22,7 @@ namespace type_traits {
2222

2323
template <typename T>
2424
concept c_hypergraph_impl_tag =
25-
c_one_of<T, impl::edge_list_t, impl::adjacency_list_t, impl::incidence_matrix_t>;
25+
c_one_of<T, impl::hyperedge_list_t, impl::adjacency_list_t, impl::incidence_matrix_t>;
2626

2727
} // namespace type_traits
2828

0 commit comments

Comments
 (0)