|
4 | 4 | #include <cstddef> |
5 | 5 | #include <iterator> |
6 | 6 | #include <algorithm> |
| 7 | +#include <tuple> |
| 8 | + |
7 | 9 | #include "vtr_range.h" |
8 | 10 |
|
9 | 11 | namespace vtr { |
@@ -56,9 +58,6 @@ class vector : private std::vector<V, Allocator> { |
56 | 58 | class key_iterator; |
57 | 59 | typedef vtr::Range<key_iterator> key_range; |
58 | 60 |
|
59 | | - class pair_iterator; |
60 | | - typedef vtr::Range<pair_iterator> pair_range; |
61 | | - |
62 | 61 | public: |
63 | 62 | //Pass through std::vector's types |
64 | 63 | using typename storage::allocator_type; |
@@ -157,16 +156,41 @@ class vector : private std::vector<V, Allocator> { |
157 | 156 | } |
158 | 157 |
|
159 | 158 | /** |
160 | | - * @brief Returns a range containing the key-value pairs. |
| 159 | + * @brief Provides an iterable object to enumerate the vector. |
| 160 | + * |
| 161 | + * This function allows for easy enumeration, yielding a tuple of (index, element) |
| 162 | + * pairs in each iteration. It is similar in functionality to Python's `enumerate()`. |
| 163 | + * This function can be used in range-based with structured binding to iterate over |
| 164 | + * indices and values at the same time. |
161 | 165 | * |
162 | | - * This function returns a range object that represents the sequence of key-value |
163 | | - * pairs within the vector. The range can be used to iterate over the pairs using |
164 | | - * standard range-based loops or algorithms. |
| 166 | + * vtr::vector<IdType, ValueType> vec; |
| 167 | + * for (const auto& [idx, value] : vec) { |
| 168 | + * ... |
| 169 | + * } |
| 170 | + * It should be noted that value is returned by reference even if "&" |
| 171 | + * does not appear after auto keyword. However, it is recommended to use "&" |
| 172 | + * explicitly to avoid any confusion about value's scope. |
165 | 173 | * |
166 | | - * @return A `pair_range` object representing the range of key-value pairs. |
| 174 | + * @ return An iterable wrapper that can be used in a range-based for loop to obtain |
| 175 | + * (index, element) pairs. |
167 | 176 | */ |
168 | | - pair_range pairs() const { |
169 | | - return vtr::make_range(pair_begin(), pair_end()); |
| 177 | + auto pairs() const { |
| 178 | + struct enumerated_iterator { |
| 179 | + key_type i; |
| 180 | + vector::const_iterator iter; |
| 181 | + |
| 182 | + bool operator!=(const enumerated_iterator& other) const { return iter != other.iter; } |
| 183 | + void operator++() { i = key_type(size_t(i) + 1); iter++; } |
| 184 | + std::tuple<key_type, decltype(*iter)&> operator*() { return std::tie(i, *iter); } |
| 185 | + }; |
| 186 | + |
| 187 | + struct enumerated_wrapper { |
| 188 | + const vector& vec; |
| 189 | + auto begin() { return enumerated_iterator{ key_type(0), vec.begin() }; } |
| 190 | + auto end() { return enumerated_iterator{ key_type(vec.size()), vec.end() }; } |
| 191 | + }; |
| 192 | + |
| 193 | + return enumerated_wrapper{ *this }; |
170 | 194 | } |
171 | 195 |
|
172 | 196 | public: |
@@ -218,59 +242,9 @@ class vector : private std::vector<V, Allocator> { |
218 | 242 | value_type value_; |
219 | 243 | }; |
220 | 244 |
|
221 | | - /** |
222 | | - * @brief A bidirectional iterator for a vtr:vector object. |
223 | | - * |
224 | | - * The `pair_iterator` class provides a way to iterate over key-value pairs |
225 | | - * within a vtr::vector container. It supports bidirectional iteration, |
226 | | - * allowing the user to traverse the container both forwards and backwards. |
227 | | - */ |
228 | | - class pair_iterator { |
229 | | - public: |
230 | | - using iterator_category = std::bidirectional_iterator_tag; |
231 | | - using difference_type = std::ptrdiff_t; |
232 | | - using value_type = std::pair<key_type, V>; |
233 | | - using pointer = value_type*; |
234 | | - using reference = value_type&; |
235 | | - |
236 | | - /// @brief constructor |
237 | | - pair_iterator(vector<K, V, Allocator>& vec, key_type init) |
238 | | - : vec_(vec), value_(init, vec[init]) {} |
239 | | - |
240 | | - /// @brief ++ operator |
241 | | - pair_iterator& operator++() { |
242 | | - value_ = std::make_pair(key_type(size_t(value_.first) + 1), vec_[key_type(size_t(value_.first) + 1)]); |
243 | | - return *this; |
244 | | - } |
245 | | - /// @brief -- operator |
246 | | - pair_iterator& operator--() { |
247 | | - value_ = std::make_pair(key_type(size_t(value_.first) - 1), vec_[key_type(size_t(value_.first) - 1)]); |
248 | | - return *this; |
249 | | - } |
250 | | - /// @brief dereference operator |
251 | | - reference operator*() { return value_; } |
252 | | - /// @brief -> operator |
253 | | - pointer operator->() { return &value_; } |
254 | | - |
255 | | - /// @brief == operator |
256 | | - friend bool operator==(const pair_iterator& lhs, const pair_iterator& rhs) { return lhs.value_.first == rhs.value_.first; } |
257 | | - /// @brief != operator |
258 | | - friend bool operator!=(const pair_iterator& lhs, const pair_iterator& rhs) { return !(lhs == rhs); } |
259 | | - |
260 | | - private: |
261 | | - /// @brief Reference to the vector of key-value pairs. |
262 | | - vector<K, V, Allocator>& vec_; |
263 | | - // @brief The current key-value pair being pointed to by the iterator. |
264 | | - value_type value_; |
265 | | - }; |
266 | | - |
267 | 245 | private: |
268 | 246 | key_iterator key_begin() const { return key_iterator(key_type(0)); } |
269 | 247 | key_iterator key_end() const { return key_iterator(key_type(size())); } |
270 | | - |
271 | | - pair_iterator pair_begin() const { return pair_iterator(*const_cast<vector<K, V, Allocator>*>(this), key_type(0)); } |
272 | | - pair_iterator pair_end() const { return pair_iterator(*const_cast<vector<K, V, Allocator>*>(this), key_type(size())); } |
273 | 248 | }; |
274 | | - |
275 | 249 | } // namespace vtr |
276 | 250 | #endif |
0 commit comments