@@ -159,8 +159,9 @@ class graph final {
159159 }
160160 }
161161
162- template <type_traits::c_sized_range_of<vertex_properties_type> VertexPropertiesRange>
163- void add_vertices_with (const VertexPropertiesRange& properties_range)
162+ void add_vertices_with (
163+ const type_traits::c_sized_range_of<vertex_properties_type> auto & properties_range
164+ )
164165 requires(not type_traits::is_default_properties_type_v<vertex_properties_type>)
165166 {
166167 const auto n = std::ranges::size (properties_range);
@@ -186,8 +187,9 @@ class graph final {
186187 this ->remove_vertex (vertex.id ());
187188 }
188189
189- template <type_traits::c_sized_range_of<types::id_type> IdRange>
190- void remove_vertices_from (const IdRange& vertex_id_range) {
190+ void remove_vertices_from (
191+ const type_traits::c_sized_range_of<types::id_type> auto & vertex_id_range
192+ ) {
191193 // sorts the ids in a descending order and removes duplicate ids
192194 std::set<types::id_type, std::greater<types::id_type>> vertex_id_set (
193195 std::ranges::begin (vertex_id_range), std::ranges::end (vertex_id_range)
@@ -198,26 +200,14 @@ class graph final {
198200 this ->_remove_vertex_impl (vertex_id);
199201 }
200202
201- template <type_traits::c_sized_range_of<types::const_ref_wrap<vertex_type>> VertexRefRange>
202- void remove_vertices_from (const VertexRefRange& vertex_ref_range) {
203- // TODO [C++26]: replace with std::greater
204- struct vertex_ref_greater_comparator {
205- [[nodiscard]] bool operator ()(
206- const types::const_ref_wrap<vertex_type>& lhs,
207- const types::const_ref_wrap<vertex_type>& rhs
208- ) const {
209- return lhs.get () > rhs.get ();
210- }
211- };
212-
213- // sorts the ids in a descending order and removes duplicate ids
214- std::set<types::const_ref_wrap<vertex_type>, vertex_ref_greater_comparator> vertex_ref_set (
215- std::ranges::begin (vertex_ref_range), std::ranges::end (vertex_ref_range)
216- );
217-
203+ void remove_vertices_from (const type_traits::c_sized_range_of<vertex_type> auto & vertex_range) {
218204 // TODO: optimize
219- for (const auto & vertex_ref : vertex_ref_set)
220- this ->_remove_vertex_impl (vertex_ref.get ().id ());
205+ // sort the ids in a descending order and removes duplicate ids
206+ std::set<vertex_type> vertex_set (
207+ std::ranges::begin (vertex_range), std::ranges::end (vertex_range)
208+ );
209+ for (const auto & vertex : vertex_set)
210+ this ->_remove_vertex_impl (vertex.id ());
221211 }
222212
223213 [[nodiscard]] gl_attr_force_inline types::size_type in_degree (const types::id_type vertex_id
@@ -324,8 +314,11 @@ class graph final {
324314 return this ->add_edge (first.id (), second.id (), properties);
325315 }
326316
327- template <type_traits::c_sized_range_of<types::id_type> IdRange>
328- void add_edges_from (const types::id_type source_id, const IdRange& target_id_range) {
317+ void add_edges_from (
318+ const types::id_type source_id,
319+ const type_traits::c_sized_range_of<types::id_type> auto & target_id_range
320+ ) {
321+ // TODO: validate no duplicate target ids
329322 this ->_verify_vertex_id (source_id);
330323
331324 for (const auto target_id : target_id_range) {
@@ -342,23 +335,25 @@ class graph final {
342335 }
343336
344337 // TODO: range of convertible_to<const vertex_type&>
345- template <type_traits::c_sized_range_of<types::const_ref_wrap<vertex_type>> VertexRefRange>
346338 gl_attr_force_inline void add_edges_from (
347- const vertex_type& source, const VertexRefRange& target_range
339+ const vertex_type& source,
340+ const type_traits::c_sized_range_of<vertex_type> auto & target_range
348341 ) {
342+ // TODO: validate no duplicate targets
349343 this ->_verify_vertex_id (source.id ());
350344
351- for (const auto & target_ref : target_range) {
352- const auto & target = target_ref.get ();
345+ for (const auto & target : target_range) {
353346 this ->_verify_vertex_id (target.id ());
354347 if constexpr (not type_traits::is_default_properties_type_v<edge_properties_type>)
355348 this ->_edge_properties .emplace_back (std::make_unique<edge_properties_type>());
356349 }
357350
358351 const auto prev_n_edges = this ->_n_unique_edges ;
359- this ->_n_unique_edges += std::ranges::size (target_id_range );
352+ this ->_n_unique_edges += std::ranges::size (target_range );
360353 this ->_impl .add_edges_from (
361- std::views::iota (prev_n_edges, this ->_n_unique_edges ), source_id, target_id_range
354+ std::views::iota (prev_n_edges, this ->_n_unique_edges ),
355+ source.id (),
356+ target_range | std::views::transform (&vertex_type::id)
362357 );
363358 }
364359
@@ -370,8 +365,9 @@ class graph final {
370365 return this ->_impl .has_edge (first_id, second_id);
371366 }
372367
373- [[nodiscard]] gl_attr_force_inline has_edge (const vertex_type& first, const vertex_type& second)
374- const {
368+ [[nodiscard]] gl_attr_force_inline bool has_edge (
369+ const vertex_type& first, const vertex_type& second
370+ ) const {
375371 return this ->has_edge (first.id (), second.id ());
376372 }
377373
@@ -393,21 +389,12 @@ class graph final {
393389 return this ->_impl .get_edge (first.id (), second.id ());
394390 }
395391
396- [[nodiscard]] inline std::vector<types::const_ref_wrap< edge_type> > get_edges (
392+ [[nodiscard]] inline std::vector<edge_type> get_edges (
397393 const types::id_type first_id, const types::id_type second_id
398394 ) const {
399- using edge_ref_set = std::vector<types::const_ref_wrap<edge_type>>;
400-
401395 this ->_verify_vertex_id (first_id);
402396 this ->_verify_vertex_id (second_id);
403-
404- if constexpr (std::same_as<implementation_tag, impl::list_t >) {
405- return this ->_impl .get_edges (first_id, second_id);
406- }
407- else {
408- const auto edge_opt = this ->_impl .get_edge (first_id, second_id);
409- return edge_opt.has_value () ? edge_ref_set{edge_opt.value ()} : edge_ref_set{};
410- }
397+ return this ->_impl .get_edges (first_id, second_id);
411398 }
412399
413400 [[nodiscard]] std::vector<types::const_ref_wrap<edge_type>> get_edges (
@@ -424,8 +411,7 @@ class graph final {
424411 }
425412
426413 // TODO: range of convertible_to<const edge_type&>
427- template <type_traits::c_range_of<types::const_ref_wrap<edge_type>> EdgeRefRange>
428- inline void remove_edges_from (const EdgeRefRange edges) {
414+ inline void remove_edges_from (const type_traits::c_range_of<edge_type> auto & edges) {
429415 // TODO: optimize
430416 for (const auto & edge_ref : edges)
431417 this ->_impl .remove_edge (edge_ref.get ());
0 commit comments