@@ -23,12 +23,15 @@ class graph final {
2323 using implementation_type = typename implementation_tag::template type<traits_type>;
2424
2525 using vertex_type = typename traits_type::vertex_type;
26- using vertex_ptr_type = typename traits_type::vertex_ptr_type;
27- using vertex_properties_type = typename traits_type::vertex_properties_type;
26+ // using vetex_list_type = std::vector<vertex_type>;
27+ // using vertex_iterator_type =
28+ // types::dereferencing_iterator<typename vetex_list_type::const_iterator>;
2829
29- using vetex_list_type = std::vector<vertex_ptr_type>;
30- using vertex_iterator_type =
31- types::dereferencing_iterator<typename vetex_list_type::const_iterator>;
30+ using vertex_properties_type = typename traits_type::vertex_properties_type;
31+ using vertex_properties_map_type = std::conditional_t <
32+ type_traits::is_default_properties_type_v<vertex_properties_type>,
33+ types::empty_properties_map,
34+ std::vector<std::unique_ptr<vertex_properties_type>>>;
3235
3336 // TODO: reverese iterators should be available for bidirectional ranges
3437
@@ -45,10 +48,24 @@ class graph final {
4548
4649 graph () = default ;
4750
48- graph (const types::size_type n_vertices) : _impl(n_vertices) {
51+ graph (const types::size_type n_vertices)
52+ requires (type_traits::is_default_properties_type_v<vertex_properties_type>)
53+ : _vertex_properties(), _impl(n_vertices) {
4954 this ->_vertices .reserve (n_vertices);
50- for (auto vertex_id = constants::initial_id; vertex_id < n_vertices; ++vertex_id)
51- this ->_vertices .push_back (detail::make_vertex<vertex_type>(vertex_id));
55+ for (auto id : std::views::iota (constants::initial_id, n_vertices))
56+ this ->_vertices .emplace_back (vertex_id, this ->_vertex_properties );
57+ }
58+
59+ graph (const types::size_type n_vertices)
60+ requires (not type_traits::is_default_properties_type_v<vertex_properties_type>)
61+ : _impl(n_vertices) {
62+ this ->_vertices .reserve (n_vertices);
63+ this ->_vertex_properties .reserve (n_vertices);
64+ for (auto [id, properties] : std::views::enumerate (this ->_vertex_properties ))
65+ this ->_vertices .emplace_back (
66+ vertex_id,
67+ *this ->_vertex_properties .emplace_back (std::make_unique<vertex_properties_type>())
68+ );
5269 }
5370
5471 graph (graph&&) = default ;
@@ -59,7 +76,7 @@ class graph final {
5976 // --- general methods ---
6077
6178 [[nodiscard]] gl_attr_force_inline types::size_type n_vertices () const {
62- return this ->_vertices . size () ;
79+ return this ->_n_vertices ;
6380 }
6481
6582 [[nodiscard]] gl_attr_force_inline types::size_type n_unique_edges () const {
@@ -68,14 +85,31 @@ class graph final {
6885
6986 // --- vertex methods ---
7087
71- [[nodiscard]] gl_attr_force_inline types::iterator_range<vertex_iterator_type> vertices (
72- ) const {
73- return make_iterator_range (deref_cbegin (this ->_vertices ), deref_cend (this ->_vertices ));
88+ // TODO: return a view
89+ // [[nodiscard]] gl_attr_force_inline types::iterator_range<vertex_iterator_type> vertices(
90+ // ) const {
91+ // return make_iterator_range(deref_cbegin(this->_vertices), deref_cend(this->_vertices));
92+ // }
93+
94+ [[nodiscard]] gl_attr_force_inline auto vertices () const
95+ requires(type_traits::is_default_properties_type_v<vertex_properties_type>)
96+ {
97+ return std::views::enumerate (this ->_vertex_properties )
98+ | std::views::transform ([](auto [id, properties]) {
99+ return vertex_descriptor{id, *properties};
100+ });
101+ }
102+
103+ [[nodiscard]] gl_attr_force_inline auto vertices () const
104+ requires(not type_traits::is_default_properties_type_v<vertex_properties_type>)
105+ {
106+ return this ->vertex_ids ()
107+ | std::views::transform ([](const types::id_type id) { return vertex_descriptor{id}; });
74108 }
75109
76110 [[nodiscard]] gl_attr_force_inline std::ranges::iota_view<types::id_type, types::id_type>
77111 vertex_ids () const {
78- return std::views::iota (constants::initial_id, this ->n_vertices () );
112+ return std::views::iota (constants::initial_id, this ->_n_vertices );
79113 }
80114
81115 // clang-format off
@@ -85,52 +119,58 @@ class graph final {
85119 const types::id_type vertex_id
86120 ) const {
87121 this ->_verify_vertex_id (vertex_id);
88- return *this ->_vertices [vertex_id];
122+ if constexpr (type_traits::is_default_properties_type_v<vertex_properties_type>)
123+ return vertex_descriptor{vertex_id};
124+ else
125+ return vertex_descriptor{vertex_id, *this ->_vertex_properties [vertex_id]};
89126 }
90127
91128 // clang-format on
92129
93130 [[nodiscard]] gl_attr_force_inline bool has_vertex (const types::id_type vertex_id) const {
94- return vertex_id < this ->n_vertices () ;
131+ return vertex_id < this ->_n_vertices ;
95132 }
96133
97- [[nodiscard]] gl_attr_force_inline bool has_vertex (const vertex_type& vertex) const {
98- return this ->has_vertex (vertex.id ()) and &vertex == this ->_vertices [vertex.id ()].get ();
99- }
100-
101- const vertex_type& add_vertex () {
134+ vertex_type add_vertex () {
102135 this ->_impl .add_vertex ();
103- this ->_vertices .push_back (detail::make_vertex<vertex_type>(this ->n_vertices ()));
104- return *this ->_vertices .back ();
136+ const auto new_vertex_id = this ->_n_vertices ++;
137+
138+ if constexpr (type_traits::is_default_properties_type_v<vertex_properties_type>)
139+ return vertex_descriptor{new_vertex_id, *this ->_vertex_properties .emplace_back ()};
140+ else
141+ return vertex_descriptor{new_vertex_id};
105142 }
106143
107- const vertex_type& add_vertex (const vertex_properties_type& properties)
144+ vertex_type add_vertex (vertex_properties_type properties)
108145 requires(not type_traits::is_default_properties_type_v<vertex_properties_type>)
109146 {
110147 this ->_impl .add_vertex ();
111- this ->_vertices .push_back (detail::make_vertex<vertex_type>(this ->n_vertices (), properties));
112- return *this ->_vertices .back ();
148+ return vertex_descriptor{
149+ this ->_n_vertices ++,
150+ *this ->_vertex_properties .emplace_back (
151+ std::make_unique<vertex_properties_type>(std::move (properties))
152+ )
153+ };
113154 }
114155
115156 void add_vertices (const types::size_type n) {
116157 this ->_impl .add_vertices (n);
117- this ->_vertices .reserve (this ->n_vertices () + n);
118-
119- for (types::size_type _ = constants::begin_idx; _ < n; ++_)
120- this ->_vertices .push_back (detail::make_vertex<vertex_type>(this ->n_vertices ()));
158+ this ->_n_vertices += n;
159+ if constexpr (type_traits::is_default_properties_type_v<vertex_properties_type>)
160+ this ->_vertex_properties .resize (this ->_n_vertices );
121161 }
122162
123163 template <type_traits::c_sized_range_of<vertex_properties_type> VertexPropertiesRange>
124- void add_vertices_with (const VertexPropertiesRange& properties_range) {
164+ void add_vertices_with (const VertexPropertiesRange& properties_range)
165+ requires(not type_traits::is_default_properties_type_v<vertex_properties_type>)
166+ {
125167 const auto n = std::ranges::size (properties_range);
126168
127169 this ->_impl .add_vertices (n);
128- this ->_vertices . reserve ( this -> n_vertices () + n) ;
170+ this ->_n_vertices += n ;
129171
130- for (const auto & properties : properties_range)
131- this ->_vertices .push_back (
132- detail::make_vertex<vertex_type>(this ->n_vertices (), properties)
133- );
172+ if constexpr (type_traits::is_default_properties_type_v<vertex_properties_type>)
173+ this ->_vertex_properties .append_range (properties_range);
134174 }
135175
136176 gl_attr_force_inline void remove_vertex (const types::size_type vertex_id) {
@@ -644,7 +684,10 @@ class graph final {
644684 }
645685 }
646686
647- vetex_list_type _vertices{};
687+ types::size_type _n_vertices = 0uz;
688+ [[no_unique_address]] vertex_properties_map_type _vertex_properties;
689+ // TODO: edge properties map
690+
648691 implementation_type _impl{};
649692};
650693
0 commit comments