|
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