@@ -93,7 +93,7 @@ class graph final {
9393 using edge_properties_map_type = std::conditional_t <
9494 traits::c_empty_properties<edge_properties_type>,
9595 empty_properties_map,
96- std::vector<std::unique_ptr< edge_properties_type> >>;
96+ std::vector<edge_properties_type>>;
9797
9898 graph& operator =(const graph&) = delete ;
9999
@@ -355,18 +355,16 @@ class graph final {
355355 const auto new_edge_id = static_cast <id_type>(this ->_n_edges ++);
356356 this ->_impl .add_edge (new_edge_id, source_id, target_id);
357357
358- if constexpr (traits::c_non_empty_properties<edge_properties_type>) {
359- const auto & p =
360- this ->_edge_properties .emplace_back (std::make_unique<edge_properties_type>());
361- return edge_type{new_edge_id, source_id, target_id, *p};
362- }
363- else {
358+ if constexpr (traits::c_non_empty_properties<edge_properties_type>)
359+ return edge_type{
360+ new_edge_id, source_id, target_id, this ->_edge_properties .emplace_back ()
361+ };
362+ else
364363 return edge_type{new_edge_id, source_id, target_id};
365- }
366364 }
367365
368366 edge_type add_edge_with (
369- const id_type source_id, const id_type target_id, const edge_properties_type& properties
367+ const id_type source_id, const id_type target_id, edge_properties_type properties
370368 )
371369 requires(traits::c_non_empty_properties<edge_properties_type>)
372370 {
@@ -376,9 +374,12 @@ class graph final {
376374 const auto new_edge_id = static_cast <id_type>(this ->_n_edges ++);
377375 this ->_impl .add_edge (new_edge_id, source_id, target_id);
378376
379- auto & p =
380- this ->_edge_properties .emplace_back (std::make_unique<edge_properties_type>(properties));
381- return edge_type{new_edge_id, source_id, target_id, *p};
377+ return edge_type{
378+ new_edge_id,
379+ source_id,
380+ target_id,
381+ this ->_edge_properties .emplace_back (std::move (properties))
382+ };
382383 }
383384
384385 // clang-format off
@@ -402,12 +403,8 @@ class graph final {
402403 const id_type source_id, const traits::c_sized_range_of<id_type> auto & target_id_rng
403404 ) {
404405 this ->_verify_vertex_id (source_id);
405-
406- for (auto target_id : target_id_rng) {
406+ for (auto target_id : target_id_rng)
407407 this ->_verify_vertex_id (target_id);
408- if constexpr (traits::c_non_empty_properties<edge_properties_type>)
409- this ->_edge_properties .emplace_back (std::make_unique<edge_properties_type>());
410- }
411408
412409 const auto prev_n_edges = this ->_n_edges ;
413410 this ->_n_edges += std::ranges::size (target_id_rng);
@@ -416,18 +413,17 @@ class graph final {
416413 source_id,
417414 target_id_rng
418415 );
416+
417+ if constexpr (traits::c_non_empty_properties<edge_properties_type>)
418+ this ->_edge_properties .resize (this ->_n_edges );
419419 }
420420
421421 void add_edges_from (
422422 vertex_type source, const traits::c_sized_range_of<vertex_type> auto & target_rng
423423 ) {
424424 this ->_verify_vertex_id (source.id ());
425-
426- for (auto target : target_rng) {
425+ for (auto target : target_rng)
427426 this ->_verify_vertex_id (target.id ());
428- if constexpr (traits::c_non_empty_properties<edge_properties_type>)
429- this ->_edge_properties .emplace_back (std::make_unique<edge_properties_type>());
430- }
431427
432428 const auto prev_n_edges = this ->_n_edges ;
433429 this ->_n_edges += std::ranges::size (target_rng);
@@ -436,6 +432,10 @@ class graph final {
436432 source.id (),
437433 target_rng | std::views::transform (&vertex_type::id)
438434 );
435+
436+
437+ if constexpr (traits::c_non_empty_properties<edge_properties_type>)
438+ this ->_edge_properties .resize (this ->_n_edges );
439439 }
440440
441441 void remove_edge (const edge_type& edge) {
@@ -554,13 +554,13 @@ class graph final {
554554 if (id >= this ->_n_edges )
555555 throw std::out_of_range (std::format (" Got invalid edge id [{}]" , id));
556556
557- return * this ->_edge_properties [id];
557+ return this ->_edge_properties [id];
558558 }
559559
560560 [[nodiscard]] gl_attr_force_inline auto edge_properties_map () const noexcept
561561 requires(traits::c_non_empty_properties<edge_properties_type>)
562562 {
563- return util::deref_view (this ->_edge_properties );
563+ return std::views::all (this ->_edge_properties );
564564 }
565565
566566 // --- adjacency and incidence methods ---
@@ -602,10 +602,6 @@ class graph final {
602602 // --- comparison ---
603603
604604 [[nodiscard]] friend bool operator ==(const graph& lhs, const graph& rhs) noexcept {
605- constexpr auto val_eq = [](const auto & ptr_a, const auto & ptr_b) {
606- return *ptr_a == *ptr_b;
607- };
608-
609605 if (lhs._n_vertices != rhs._n_vertices or lhs._n_edges != rhs._n_edges )
610606 return false ;
611607
@@ -614,7 +610,7 @@ class graph final {
614610 return false ;
615611
616612 if constexpr (traits::c_non_empty_properties<edge_properties_type>)
617- if (not std::ranges::equal ( lhs._edge_properties , rhs._edge_properties , val_eq) )
613+ if (lhs._edge_properties != rhs._edge_properties )
618614 return false ;
619615
620616 return lhs._impl == rhs._impl ;
@@ -656,14 +652,8 @@ class graph final {
656652 : _n_vertices{other._n_vertices },
657653 _n_edges{other._n_edges },
658654 _impl{other._impl },
659- _vertex_properties{other._vertex_properties } {
660- // Deep copy edge properties
661- if constexpr (traits::c_non_empty_properties<edge_properties_type>) {
662- this ->_edge_properties .reserve (other._edge_properties .size ());
663- for (const auto & property : other._edge_properties )
664- this ->_edge_properties .push_back (std::make_unique<edge_properties_type>(*property));
665- }
666- }
655+ _vertex_properties{other._vertex_properties },
656+ _edge_properties{other._edge_properties } {}
667657
668658 // --- element validation ---
669659
@@ -892,7 +882,9 @@ class graph final {
892882
893883 // / @todo Replace mutability with proper const-correct getter overloads to ensure thread safety guarantees associated with the const qualifier
894884 [[no_unique_address]] mutable vertex_properties_map_type _vertex_properties{};
895- [[no_unique_address]] edge_properties_map_type _edge_properties{};
885+
886+ // / @todo Replace mutability with proper const-correct getter overloads to ensure thread safety guarantees associated with the const qualifier
887+ [[no_unique_address]] mutable edge_properties_map_type _edge_properties{};
896888};
897889
898890// --- general graph utility ---
0 commit comments