Skip to content

Commit 66b10a3

Browse files
committed
some initial vertex methods for hypergraph
1 parent 549f983 commit 66b10a3

2 files changed

Lines changed: 166 additions & 18 deletions

File tree

include/gl/graph.hpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,18 @@ class graph final {
8686
});
8787
}
8888

89-
[[nodiscard]] gl_attr_force_inline std::ranges::iota_view<types::id_type, types::id_type>
90-
vertex_ids() const {
89+
[[nodiscard]] gl_attr_force_inline auto vertex_ids() const noexcept {
9190
return std::views::iota(constants::initial_id, this->_n_vertices);
9291
}
9392

94-
// clang-format off
95-
// gl_attr_force_inline misplacement
96-
97-
[[nodiscard]] gl_attr_force_inline vertex_type get_vertex(const types::id_type vertex_id) const {
93+
[[nodiscard]] vertex_type get_vertex(const types::id_type vertex_id) const {
9894
this->_verify_vertex_id(vertex_id);
9995
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
10096
return vertex_descriptor{vertex_id, *this->_vertex_properties[vertex_id]};
10197
else
10298
return vertex_descriptor{vertex_id};
10399
}
104100

105-
// clang-format on
106-
107101
[[nodiscard]] gl_attr_force_inline bool has_vertex(const types::id_type vertex_id) const {
108102
return vertex_id < this->_n_vertices;
109103
}
@@ -116,23 +110,26 @@ class graph final {
116110
this->_impl.add_vertex();
117111
const auto new_vertex_id = this->_n_vertices++;
118112

119-
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
120-
this->_vertex_properties.push_back(std::make_unique<vertex_properties_type>());
121-
return vertex_descriptor{new_vertex_id, *this->_vertex_properties.back()};
122-
}
123-
else {
113+
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
114+
return vertex_descriptor{
115+
new_vertex_id,
116+
*this->_vertex_properties.emplace_back(std::make_unique<vertex_properties_type>())
117+
};
118+
else
124119
return vertex_descriptor{new_vertex_id};
125-
}
126120
}
127121

122+
// TODO: rename to add_vertex_with
128123
const vertex_type add_vertex(vertex_properties_type properties)
129124
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
130125
{
131126
this->_impl.add_vertex();
132-
this->_vertex_properties.push_back(
133-
std::make_unique<vertex_properties_type>(std::move(properties))
134-
);
135-
return vertex_descriptor{this->_n_vertices++, *this->_vertex_properties.back()};
127+
return vertex_descriptor{
128+
this->_n_vertices++,
129+
*this->_vertex_properties.emplace_back(
130+
std::make_unique<vertex_properties_type>(std::move(properties))
131+
)
132+
};
136133
}
137134

138135
void add_vertices(const types::size_type n) {

include/hgl/hypergraph.hpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
#include "hypergraph_traits.hpp"
88

9+
#include <memory>
10+
#include <set>
11+
#include <type_traits>
12+
#include <vector>
13+
914
namespace hgl {
1015

1116
template <type_traits::c_instantiation_of<hypergraph_traits> HypergraphTraits = hypergraph_traits<>>
@@ -16,18 +21,164 @@ class hypergraph final {
1621

1722
using vertex_type = typename traits_type::vertex_type;
1823
using vertex_properties_type = typename traits_type::vertex_properties_type;
24+
using vertex_properties_map_type = std::conditional_t<
25+
type_traits::c_empty_properties<vertex_properties_type>,
26+
types::empty_properties_map,
27+
std::vector<std::unique_ptr<vertex_properties_type>>>;
1928

2029
using hyperedge_type = typename traits_type::hyperedge_type;
2130
using hyperedge_properties_type = typename traits_type::hyperedge_properties_type;
31+
using hyperedge_properties_map_type = std::conditional_t<
32+
type_traits::c_empty_properties<hyperedge_properties_type>,
33+
types::empty_properties_map,
34+
std::vector<std::unique_ptr<hyperedge_properties_type>>>;
2235

2336
hypergraph(const hypergraph&) = delete;
2437
hypergraph& operator=(const hypergraph&) = delete;
2538

2639
hypergraph() = default;
2740

41+
// --- general methods ---
42+
43+
[[nodiscard]] gl_attr_force_inline types::size_type n_vertices() const noexcept {
44+
return this->_n_vertices;
45+
}
46+
47+
[[nodiscard]] gl_attr_force_inline types::size_type n_hyperedges() const noexcept {
48+
return this->_n_hyperedges;
49+
}
50+
51+
// --- vertex methods ---
52+
53+
[[nodiscard]] gl_attr_force_inline auto vertices() const
54+
requires(type_traits::c_empty_properties<vertex_properties_type>)
55+
{
56+
return this->vertex_ids()
57+
| std::views::transform([](const types::id_type id) { return vertex_type{id}; });
58+
}
59+
60+
[[nodiscard]] gl_attr_force_inline auto vertices() const
61+
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
62+
{
63+
return this->_vertex_properties | std::views::enumerate
64+
| std::views::transform([](const auto& x) {
65+
const auto& [id, ptr] = x;
66+
return vertex_type{static_cast<types::id_type>(id), *ptr};
67+
});
68+
}
69+
70+
[[nodiscard]] gl_attr_force_inline auto vertex_ids() const noexcept {
71+
return std::views::iota(constants::initial_id, this->_n_vertices);
72+
}
73+
74+
[[nodiscard]] vertex_type get_vertex(const types::id_type vertex_id) const {
75+
// this->_verify_vertex_id(vertex_id);
76+
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
77+
return vertex_descriptor{vertex_id, *this->_vertex_properties[vertex_id]};
78+
else
79+
return vertex_descriptor{vertex_id};
80+
}
81+
82+
[[nodiscard]] gl_attr_force_inline bool has_vertex(const types::id_type vertex_id) const {
83+
return vertex_id < this->_n_vertices;
84+
}
85+
86+
[[nodiscard]] gl_attr_force_inline bool has_vertex(const vertex_type& vertex) const {
87+
return this->has_vertex(vertex.id());
88+
}
89+
90+
const vertex_type add_vertex() {
91+
// this->_impl.add_vertex();
92+
const auto new_vertex_id = this->_n_vertices++;
93+
94+
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
95+
return vertex_descriptor{
96+
new_vertex_id,
97+
*this->_vertex_properties.emplace_back(std::make_unique<vertex_properties_type>())
98+
};
99+
else
100+
return vertex_descriptor{new_vertex_id};
101+
}
102+
103+
const vertex_type add_vertex_with(vertex_properties_type properties)
104+
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
105+
{
106+
// this->_impl.add_vertex();
107+
this->_vertex_properties.push_back(
108+
std::make_unique<vertex_properties_type>(std::move(properties))
109+
);
110+
return vertex_descriptor{this->_n_vertices++, *this->_vertex_properties.back()};
111+
}
112+
113+
void add_vertices(const types::size_type n) {
114+
// this->_impl.add_vertices(n);
115+
this->_n_vertices += n;
116+
117+
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
118+
const auto old_size = this->_vertex_properties.size();
119+
this->_vertex_properties.reserve(this->_n_vertices);
120+
for (types::size_type i = old_size; i < this->_n_vertices; ++i)
121+
this->_vertex_properties.push_back(std::make_unique<vertex_properties_type>());
122+
}
123+
}
124+
125+
void add_vertices_with(
126+
const type_traits::c_sized_range_of<vertex_properties_type> auto& properties_range
127+
)
128+
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
129+
{
130+
const auto n = std::ranges::size(properties_range);
131+
132+
// this->_impl.add_vertices(n);
133+
this->_n_vertices += n;
134+
135+
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
136+
for (auto& properties : properties_range) {
137+
this->_vertex_properties.emplace_back(
138+
std::make_unique<vertex_properties_type>(properties)
139+
);
140+
}
141+
}
142+
}
143+
144+
void remove_vertex(const types::size_type vertex_id) {
145+
// this->_verify_vertex_id(vertex_id);
146+
// this->_remove_vertex_impl(vertex_id);
147+
}
148+
149+
gl_attr_force_inline void remove_vertex(const vertex_type& vertex) {
150+
this->remove_vertex(vertex.id());
151+
}
152+
153+
void remove_vertices_from(
154+
const type_traits::c_forward_range_of<types::id_type> auto& vertex_id_range
155+
) {
156+
// sorts the ids in a descending order and removes duplicate ids
157+
std::set<types::id_type, std::greater<types::id_type>> vertex_id_set(
158+
std::ranges::begin(vertex_id_range), std::ranges::end(vertex_id_range)
159+
);
160+
161+
// TODO: optimize
162+
// for (const auto vertex_id : vertex_id_set)
163+
// this->_remove_vertex_impl(vertex_id);
164+
}
165+
166+
void remove_vertices_from(const type_traits::c_sized_range_of<vertex_type> auto& vertex_range) {
167+
// TODO: optimize
168+
// sort the ids in a descending order and removes duplicate ids
169+
std::set<vertex_type, std::greater<vertex_type>> vertex_set(
170+
std::ranges::begin(vertex_range), std::ranges::end(vertex_range)
171+
);
172+
// for (const auto& vertex : vertex_set)
173+
// this->_remove_vertex_impl(vertex.id());
174+
}
175+
28176
private:
29177
types::size_type _n_vertices = 0uz;
30178
types::size_type _n_hyperedges = 0uz;
179+
180+
[[no_unique_address]] vertex_properties_map_type _vertex_properties{};
181+
[[no_unique_address]] hyperedge_properties_map_type _hyperedge_properties{};
31182
};
32183

33184
} // namespace hgl

0 commit comments

Comments
 (0)