1717
1818#include < algorithm>
1919#include < initializer_list>
20- #include < memory>
2120#include < set>
2221#include < type_traits>
2322#include < vector>
@@ -91,31 +90,24 @@ class hypergraph final {
9190 using vertex_properties_map_type = std::conditional_t <
9291 traits::c_empty_properties<vertex_properties_type>,
9392 empty_properties_map,
94- std::vector<std::unique_ptr< vertex_properties_type> >>;
93+ std::vector<vertex_properties_type>>;
9594
9695 using hyperedge_type = typename traits_type::hyperedge_type;
9796 using hyperedge_properties_type = typename traits_type::hyperedge_properties_type;
9897 using hyperedge_properties_map_type = std::conditional_t <
9998 traits::c_empty_properties<hyperedge_properties_type>,
10099 empty_properties_map,
101- std::vector<std::unique_ptr< hyperedge_properties_type> >>;
100+ std::vector<hyperedge_properties_type>>;
102101
103102 hypergraph& operator =(const hypergraph&) = delete ;
104103
105104 explicit hypergraph (const size_type n_vertices = 0uz, const size_type n_hyperedges = 0uz)
106105 : _n_vertices(n_vertices), _n_hyperedges(n_hyperedges), _impl(n_vertices, n_hyperedges) {
107- if constexpr (traits::c_non_empty_properties<vertex_properties_type>) {
108- this ->_vertex_properties .reserve (n_vertices);
109- for (const auto _ : this ->vertex_ids ())
110- this ->_vertex_properties .push_back (std::make_unique<vertex_properties_type>());
111- }
106+ if constexpr (traits::c_non_empty_properties<vertex_properties_type>)
107+ this ->_vertex_properties .resize (n_vertices);
112108
113- if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>) {
114- this ->_hyperedge_properties .reserve (n_hyperedges);
115- for (const auto _ : this ->hyperedge_ids ())
116- this ->_hyperedge_properties .push_back (std::make_unique<hyperedge_properties_type>()
117- );
118- }
109+ if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
110+ this ->_hyperedge_properties .resize (n_hyperedges);
119111 }
120112
121113 hypergraph (hypergraph&&) noexcept = default ;
@@ -140,10 +132,7 @@ class hypergraph final {
140132 const auto new_vertex_id = static_cast <id_type>(this ->_n_vertices ++);
141133
142134 if constexpr (traits::c_non_empty_properties<vertex_properties_type>)
143- return vertex_type{
144- new_vertex_id,
145- *this ->_vertex_properties .emplace_back (std::make_unique<vertex_properties_type>())
146- };
135+ return vertex_type{new_vertex_id, this ->_vertex_properties .emplace_back ()};
147136 else
148137 return vertex_type{new_vertex_id};
149138 }
@@ -154,22 +143,16 @@ class hypergraph final {
154143 this ->_impl .add_vertices (1uz);
155144 return vertex_type{
156145 static_cast <id_type>(this ->_n_vertices ++),
157- *this ->_vertex_properties .emplace_back (
158- std::make_unique<vertex_properties_type>(std::move (properties))
159- )
146+ this ->_vertex_properties .emplace_back (std::move (properties))
160147 };
161148 }
162149
163150 void add_vertices (const size_type n) {
164151 this ->_impl .add_vertices (n);
165152 this ->_n_vertices += n;
166153
167- if constexpr (traits::c_non_empty_properties<vertex_properties_type>) {
168- const auto old_size = this ->_vertex_properties .size ();
169- this ->_vertex_properties .reserve (this ->_n_vertices );
170- for (size_type i = old_size; i < this ->_n_vertices ; ++i)
171- this ->_vertex_properties .push_back (std::make_unique<vertex_properties_type>());
172- }
154+ if constexpr (traits::c_non_empty_properties<vertex_properties_type>)
155+ this ->_vertex_properties .resize (this ->_n_vertices );
173156 }
174157
175158 void add_vertices_with (
@@ -183,11 +166,12 @@ class hypergraph final {
183166 this ->_n_vertices += n;
184167
185168 if constexpr (traits::c_non_empty_properties<vertex_properties_type>) {
186- for (auto & properties : properties_rng) {
187- this ->_vertex_properties .emplace_back (
188- std::make_unique<vertex_properties_type>(properties)
189- );
190- }
169+ this ->_vertex_properties .append_range (properties_rng);
170+ // this->_vertex_properties.insert(
171+ // this->_vertex_properties.end(),
172+ // std::ranges::begin(properties_rng),
173+ // std::ranges::end(properties_rng)
174+ // );
191175 }
192176 }
193177
@@ -242,7 +226,7 @@ class hypergraph final {
242226
243227 [[nodiscard]] gl_attr_force_inline vertex_type vertex_unchecked (const id_type vertex_id) const {
244228 if constexpr (traits::c_non_empty_properties<vertex_properties_type>)
245- return vertex_type{vertex_id, * this ->_vertex_properties [vertex_id]};
229+ return vertex_type{vertex_id, this ->_vertex_properties [vertex_id]};
246230 else
247231 return vertex_type{vertex_id};
248232 }
@@ -260,19 +244,19 @@ class hypergraph final {
260244 return std::views::iota (initial_id_v<id_type>, this ->_n_vertices );
261245 }
262246
263- [[nodiscard]] gl_attr_force_inline vertex_properties_type& vertex_properties (
247+ [[nodiscard]] const gl_attr_force_inline vertex_properties_type& vertex_properties (
264248 const id_type vertex_id
265249 ) const
266250 requires(traits::c_non_empty_properties<vertex_properties_type>)
267251 {
268252 this ->_verify_vertex_id (vertex_id);
269- return * this ->_vertex_properties [vertex_id];
253+ return this ->_vertex_properties [vertex_id];
270254 }
271255
272256 [[nodiscard]] gl_attr_force_inline auto vertex_properties_map () const noexcept
273257 requires(traits::c_non_empty_properties<vertex_properties_type>)
274258 {
275- return util::deref_view (this ->_vertex_properties );
259+ return std::views::all (this ->_vertex_properties );
276260 }
277261
278262 // --- hyperedge modifiers ---
@@ -282,12 +266,7 @@ class hypergraph final {
282266 const auto new_hyperedge_id = static_cast <id_type>(this ->_n_hyperedges ++);
283267
284268 if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
285- return hyperedge_type{
286- new_hyperedge_id,
287- *this ->_hyperedge_properties .emplace_back (
288- std::make_unique<hyperedge_properties_type>()
289- )
290- };
269+ return hyperedge_type{new_hyperedge_id, this ->_hyperedge_properties .emplace_back ()};
291270 else
292271 return hyperedge_type{new_hyperedge_id};
293272 }
@@ -298,9 +277,7 @@ class hypergraph final {
298277 this ->_impl .add_hyperedges (1uz);
299278 return hyperedge_type{
300279 static_cast <id_type>(this ->_n_hyperedges ++),
301- *this ->_hyperedge_properties .emplace_back (
302- std::make_unique<hyperedge_properties_type>(std::move (properties))
303- )
280+ this ->_hyperedge_properties .emplace_back (std::move (properties))
304281 };
305282 }
306283
@@ -462,13 +439,8 @@ class hypergraph final {
462439 this ->_impl .add_hyperedges (n);
463440 this ->_n_hyperedges += n;
464441
465- if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>) {
466- const auto old_size = this ->_hyperedge_properties .size ();
467- this ->_hyperedge_properties .reserve (this ->_n_hyperedges );
468- for (auto i = old_size; i < this ->_n_hyperedges ; ++i)
469- this ->_hyperedge_properties .push_back (std::make_unique<hyperedge_properties_type>()
470- );
471- }
442+ if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
443+ this ->_hyperedge_properties .resize (this ->_n_hyperedges );
472444 }
473445
474446 void add_hyperedges_with (
@@ -481,13 +453,13 @@ class hypergraph final {
481453 this ->_impl .add_hyperedges (n);
482454 this ->_n_hyperedges += n;
483455
484- if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>) {
485- for ( auto & properties : properties_rng) {
486- this ->_hyperedge_properties .emplace_back (
487- std::make_unique<hyperedge_properties_type>(properties)
488- );
489- }
490- }
456+ if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
457+ this -> _hyperedge_properties . append_range ( properties_rng);
458+ // this->_hyperedge_properties.insert (
459+ // this->_hyperedge_properties.end(),
460+ // std::ranges::begin(properties_rng),
461+ // std::ranges::end(properties_rng)
462+ // );
491463 }
492464
493465 gl_attr_force_inline void remove_hyperedge (const id_type hyperedge_id) {
@@ -544,7 +516,7 @@ class hypergraph final {
544516 [[nodiscard]] gl_attr_force_inline hyperedge_type hyperedge_unchecked (const id_type hyperedge_id
545517 ) const {
546518 if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
547- return hyperedge_type{hyperedge_id, * this ->_hyperedge_properties [hyperedge_id]};
519+ return hyperedge_type{hyperedge_id, this ->_hyperedge_properties [hyperedge_id]};
548520 else
549521 return hyperedge_type{hyperedge_id};
550522 }
@@ -562,19 +534,19 @@ class hypergraph final {
562534 return std::views::iota (initial_id_v<id_type>, this ->_n_hyperedges );
563535 }
564536
565- [[nodiscard]] gl_attr_force_inline hyperedge_properties_type& hyperedge_properties (
537+ [[nodiscard]] const gl_attr_force_inline hyperedge_properties_type& hyperedge_properties (
566538 const id_type id
567539 ) const
568540 requires(traits::c_non_empty_properties<hyperedge_properties_type>)
569541 {
570542 this ->_verify_hyperedge_id (id);
571- return * this ->_hyperedge_properties [id];
543+ return this ->_hyperedge_properties [id];
572544 }
573545
574546 [[nodiscard]] gl_attr_force_inline auto hyperedge_properties_map () const noexcept
575547 requires(traits::c_non_empty_properties<hyperedge_properties_type>)
576548 {
577- return util::deref_view (this ->_hyperedge_properties );
549+ return std::views::all (this ->_hyperedge_properties );
578550 }
579551
580552 // --- incidence modifiers ---
@@ -1150,21 +1122,15 @@ class hypergraph final {
11501122 // --- comparison ---
11511123
11521124 [[nodiscard]] friend bool operator ==(const hypergraph& lhs, const hypergraph& rhs) noexcept {
1153- constexpr auto val_eq = [](const auto & ptr_a, const auto & ptr_b) {
1154- return *ptr_a == *ptr_b;
1155- };
1156-
11571125 if (lhs._n_vertices != rhs._n_vertices or lhs._n_hyperedges != rhs._n_hyperedges )
11581126 return false ;
11591127
11601128 if constexpr (traits::c_non_empty_properties<vertex_properties_type>)
1161- if (not std::ranges::equal ( lhs._vertex_properties , rhs._vertex_properties , val_eq) )
1129+ if (lhs._vertex_properties != rhs._vertex_properties )
11621130 return false ;
11631131
11641132 if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>)
1165- if (not std::ranges::equal (
1166- lhs._hyperedge_properties , rhs._hyperedge_properties , val_eq
1167- ))
1133+ if (lhs._hyperedge_properties != rhs._hyperedge_properties )
11681134 return false ;
11691135
11701136 return lhs._impl == rhs._impl ;
@@ -1261,25 +1227,11 @@ class hypergraph final {
12611227
12621228private:
12631229 hypergraph (const hypergraph& other)
1264- : _n_vertices{other._n_vertices }, _n_hyperedges{other._n_hyperedges }, _impl{other._impl } {
1265- // Deep copy vertex properties
1266- if constexpr (traits::c_non_empty_properties<vertex_properties_type>) {
1267- this ->_vertex_properties .reserve (other._vertex_properties .size ());
1268- for (const auto & property : other._vertex_properties )
1269- this ->_vertex_properties .push_back (
1270- std::make_unique<vertex_properties_type>(*property)
1271- );
1272- }
1273-
1274- // Deep copy hyperedge properties
1275- if constexpr (traits::c_non_empty_properties<hyperedge_properties_type>) {
1276- this ->_hyperedge_properties .reserve (other._hyperedge_properties .size ());
1277- for (const auto & property : other._hyperedge_properties )
1278- this ->_hyperedge_properties .push_back (
1279- std::make_unique<hyperedge_properties_type>(*property)
1280- );
1281- }
1282- }
1230+ : _n_vertices{other._n_vertices },
1231+ _n_hyperedges{other._n_hyperedges },
1232+ _impl{other._impl },
1233+ _vertex_properties{other._vertex_properties },
1234+ _hyperedge_properties{other._hyperedge_properties } {}
12831235
12841236 // --- vertex methods ---
12851237
@@ -1308,7 +1260,7 @@ class hypergraph final {
13081260 requires(traits::c_non_empty_properties<vertex_properties_type>)
13091261 {
13101262 return [&pmap = this ->_vertex_properties ](const id_type id) {
1311- return vertex_type{id, * pmap[to_idx (id)]};
1263+ return vertex_type{id, pmap[to_idx (id)]};
13121264 };
13131265 }
13141266
@@ -1339,7 +1291,7 @@ class hypergraph final {
13391291 requires(traits::c_non_empty_properties<hyperedge_properties_type>)
13401292 {
13411293 return [&pmap = this ->_hyperedge_properties ](const id_type id) {
1342- return hyperedge_type{id, * pmap[to_idx (id)]};
1294+ return hyperedge_type{id, pmap[to_idx (id)]};
13431295 };
13441296 }
13451297
@@ -1571,8 +1523,8 @@ class hypergraph final {
15711523
15721524 implementation_type _impl{};
15731525
1574- [[no_unique_address]] vertex_properties_map_type _vertex_properties{};
1575- [[no_unique_address]] hyperedge_properties_map_type _hyperedge_properties{};
1526+ [[no_unique_address]] mutable vertex_properties_map_type _vertex_properties{};
1527+ [[no_unique_address]] mutable hyperedge_properties_map_type _hyperedge_properties{};
15761528};
15771529
15781530// --- general hypergraph utility ---
0 commit comments