1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_BASE_CONTAINERS_ITERATOR_H
17 #define API_BASE_CONTAINERS_ITERATOR_H
18
19 // Allow "std::random_access_iterator_tag" compatibility
20 #define BASE_STD_COMPATIBILITY
21
22 #ifdef BASE_STD_COMPATIBILITY
23 // include std::iterators so we can have compatibility
24 // and this spoils a lot.
25 // we only need the "std::random_access_iterator_tag"...
26 #include <iterator>
27 #endif
28
29 #include <base/namespace.h>
30
31 BASE_BEGIN_NAMESPACE()
32 #ifdef BASE_STD_COMPATIBILITY
33 using random_access_iterator_tag = std::random_access_iterator_tag; // yeah. we need this for std compatibility.
34 #else
35 struct random_access_iterator_tag {};
36 #endif
37
38 // Iterators are somewhat simplified from c++11 with a hint of c++17...
39 // but they are fully trivial..
40 template<class T>
41 class const_iterator {
42 public:
43 using base_container = T;
44 using base_iterator = typename T::iterator;
45 using const_base_iterator = typename T::const_iterator;
46 using iterator_category = random_access_iterator_tag;
47 using value_type = typename T::value_type;
48 using difference_type = typename T::difference_type;
49 using pointer = typename T::const_pointer;
50 using reference = typename T::const_reference;
51 constexpr const_iterator() noexcept = default;
52 ~const_iterator() = default;
const_iterator(const pointer ptr)53 constexpr explicit const_iterator(const pointer ptr) noexcept : it_ { ptr } {}
const_iterator(const base_iterator & other)54 constexpr const_iterator(const base_iterator& other) noexcept : it_ { other.ptr() } {}
55 constexpr const_iterator& operator++() noexcept
56 {
57 ++it_;
58 return *this;
59 }
60 constexpr const_iterator operator++(int) noexcept
61 {
62 const_iterator t(*this);
63 ++*this;
64 return t;
65 }
66 constexpr const_iterator& operator--() noexcept
67 {
68 --it_;
69 return *this;
70 }
71 constexpr const_iterator operator--(int) noexcept
72 {
73 const_iterator t(*this);
74 --*this;
75 return t;
76 }
77 constexpr reference operator*() const noexcept
78 {
79 return *it_;
80 }
81 constexpr pointer operator->() const noexcept
82 {
83 return it_;
84 }
85 constexpr const_iterator operator+(difference_type n) const noexcept
86 {
87 return const_iterator(it_ + n);
88 }
89 constexpr const_iterator& operator+=(difference_type n) noexcept
90 {
91 it_ += n;
92 return *this;
93 }
94 constexpr const_iterator operator-(difference_type n) const noexcept
95 {
96 return const_iterator(it_ - n);
97 }
98 constexpr const_iterator& operator-=(difference_type n) noexcept
99 {
100 it_ -= n;
101 return *this;
102 }
103 constexpr bool operator==(const const_iterator& other) const noexcept
104 {
105 return it_ == other.it_;
106 }
107 constexpr bool operator!=(const const_iterator& other) const noexcept
108 {
109 return it_ != other.it_;
110 }
111 constexpr difference_type operator-(const const_iterator& other) const noexcept
112 {
113 return static_cast<difference_type>(it_ - other.it_);
114 }
115 constexpr bool operator<(const const_iterator& other) const noexcept
116 {
117 return it_ < other.it_;
118 }
119 constexpr bool operator<=(const const_iterator& other) const noexcept
120 {
121 return it_ <= other.it_;
122 }
123 constexpr bool operator>(const const_iterator& other) const noexcept
124 {
125 return it_ > other.it_;
126 }
127 constexpr bool operator>=(const const_iterator& other) const noexcept
128 {
129 return it_ >= other.it_;
130 }
ptr()131 pointer ptr() const
132 {
133 return it_;
134 }
135
136 protected:
137 pointer it_;
138 };
139
140 template<class T>
141 class iterator {
142 public:
143 using base_container = T;
144 using iterator_category = random_access_iterator_tag;
145 using base_iterator = typename T::iterator;
146 using const_base_iterator = typename T::const_iterator;
147 using value_type = typename T::value_type;
148 using difference_type = typename T::difference_type;
149 using pointer = typename T::pointer;
150 using reference = typename T::reference;
151 constexpr iterator() noexcept = default;
152 ~iterator() = default;
iterator(const pointer ptr)153 constexpr explicit iterator(const pointer ptr) noexcept : it_ { ptr } {}
154 constexpr iterator& operator++() noexcept
155 {
156 ++it_;
157 return *this;
158 }
159 constexpr iterator operator++(int) noexcept
160 {
161 iterator t(*this);
162 ++*this;
163 return t;
164 }
165 constexpr iterator& operator--() noexcept
166 {
167 --it_;
168 return *this;
169 }
170 constexpr iterator operator--(int) noexcept
171 {
172 iterator t(*this);
173 --*this;
174 return t;
175 }
176 constexpr reference operator*() const noexcept
177 {
178 return *it_;
179 }
180 constexpr pointer operator->() const noexcept
181 {
182 return it_;
183 }
184 constexpr reference operator*() noexcept
185 {
186 return *it_;
187 }
188 constexpr pointer operator->() noexcept
189 {
190 return it_;
191 }
192
193 constexpr iterator operator+(difference_type n) const noexcept
194 {
195 return iterator(it_ + n);
196 }
197 constexpr iterator& operator+=(difference_type n) noexcept
198 {
199 it_ += n;
200 return *this;
201 }
202 constexpr iterator operator-(difference_type n) const noexcept
203 {
204 return iterator(it_ - n);
205 }
206 constexpr iterator& operator-=(difference_type n) noexcept
207 {
208 it_ -= n;
209 return *this;
210 }
211 constexpr bool operator==(const iterator& other) const noexcept
212 {
213 return it_ == other.it_;
214 }
215 constexpr bool operator!=(const iterator& other) const noexcept
216 {
217 return it_ != other.it_;
218 }
219 constexpr difference_type operator-(const iterator& other) const noexcept
220 {
221 return static_cast<difference_type>(it_ - other.it_);
222 }
223
224 constexpr bool operator<(const iterator& other) const noexcept
225 {
226 return it_ < other.it_;
227 }
228 constexpr bool operator<=(const iterator& other) const noexcept
229 {
230 return it_ <= other.it_;
231 }
232 constexpr bool operator>(const iterator& other) const noexcept
233 {
234 return it_ > other.it_;
235 }
236 constexpr bool operator>=(const iterator& other) const noexcept
237 {
238 return it_ >= other.it_;
239 }
240
ptr()241 pointer ptr() const
242 {
243 return it_;
244 }
245
246 protected:
247 pointer it_;
248 };
249
250 template<typename Iter>
251 class reverse_iterator {
252 public:
253 using base_container = typename Iter::base_container;
254 using iterator = typename base_container::iterator;
255 using const_iterator = typename base_container::const_iterator;
256
257 using iterator_type = Iter;
258 using iterator_category = typename Iter::iterator_category;
259 using value_type = typename Iter::value_type;
260 using difference_type = typename Iter::difference_type;
261 using pointer = typename Iter::pointer;
262 using reference = typename Iter::reference;
263
264 constexpr reverse_iterator() = default;
265 ~reverse_iterator() = default;
reverse_iterator(iterator_type it)266 constexpr explicit reverse_iterator(iterator_type it) noexcept : it_(it) {}
reverse_iterator(const reverse_iterator & other)267 constexpr reverse_iterator(const reverse_iterator& other) noexcept : it_(other.base()) {}
268 template<class U>
269 constexpr reverse_iterator& operator=(const reverse_iterator<U>& other)
270 {
271 it_ = other.base();
272 return *this;
273 }
274 constexpr reverse_iterator& operator++()
275 {
276 --it_;
277 return *this;
278 }
279 constexpr reverse_iterator operator++(int)
280 {
281 reverse_iterator t(*this);
282 --it_;
283 return t;
284 }
285 constexpr reverse_iterator& operator--()
286 {
287 ++it_;
288 return *this;
289 }
290 constexpr reverse_iterator operator--(int)
291 {
292 reverse_iterator t(*this);
293 ++it_;
294 return t;
295 }
296
297 constexpr reference operator*() const
298 {
299 iterator_type it = it_;
300 return (--it).operator*();
301 }
302 constexpr pointer operator->() const
303 {
304 iterator_type it = it_;
305 return (--it).operator->();
306 }
307
308 constexpr reverse_iterator operator+(difference_type n) const
309 {
310 return reverse_iterator(it_ - n);
311 }
312 constexpr reverse_iterator& operator+=(difference_type n)
313 {
314 it_ -= n;
315 return *this;
316 }
317 constexpr reverse_iterator operator-(difference_type n) const
318 {
319 return reverse_iterator(it_ + n);
320 }
321 constexpr reverse_iterator& operator-=(difference_type n)
322 {
323 it_ += n;
324 return *this;
325 }
326 constexpr difference_type operator-(const reverse_iterator& other) const
327 {
328 return other.it_ - it_;
329 }
330 constexpr bool operator==(const reverse_iterator& other) const
331 {
332 return it_ == other.it_;
333 }
334 constexpr bool operator!=(const reverse_iterator& other) const
335 {
336 return it_ != other.it_;
337 }
base()338 constexpr iterator_type base() const
339 {
340 return it_;
341 }
342 constexpr bool operator<(const reverse_iterator& other) const noexcept
343 {
344 return it_ > other.it_;
345 }
346 constexpr bool operator<=(const reverse_iterator& other) const noexcept
347 {
348 return it_ >= other.it_;
349 }
350 constexpr bool operator>(const reverse_iterator& other) const noexcept
351 {
352 return it_ < other.it_;
353 }
354 constexpr bool operator>=(const reverse_iterator& other) const noexcept
355 {
356 return it_ <= other.it_;
357 }
358
359 private:
360 Iter it_;
361 };
362
363 template<class Iter>
364 class move_iterator {
365 public:
366 using iterator_type = Iter;
367 using iterator_category = typename Iter::iterator_category;
368 using value_type = typename Iter::value_type;
369 using difference_type = typename Iter::difference_type;
370 using pointer = Iter;
371 using reference = value_type&&;
372
373 /** constructs a new iterator adaptor */
374 constexpr move_iterator() = default;
375
move_iterator(iterator_type x)376 constexpr explicit move_iterator(iterator_type x) : current_(x) {}
377
378 template<class U>
move_iterator(const move_iterator<U> & other)379 constexpr move_iterator(const move_iterator<U>& other) : current_(other.current)
380 {}
381
382 /** assigns another iterator */
383 template<class U>
384 constexpr move_iterator& operator=(const move_iterator<U>& other)
385 {
386 current_ = other.current;
387 return *this;
388 }
389
390 /** accesses the underlying iterator */
base()391 constexpr iterator_type base() const
392 {
393 return current_;
394 }
395
396 /** accesses the pointed-to element */
397 constexpr reference operator*() const
398 {
399 return static_cast<reference>(*current_);
400 }
401
402 constexpr pointer operator->() const
403 {
404 return current_;
405 }
406
407 /** accesses an element by index */
408 constexpr reference operator[](difference_type n) const
409 {
410 return static_cast<reference>(current_[n]);
411 }
412
413 /** advances or decrements the iterator */
414 constexpr move_iterator& operator++()
415 {
416 ++current_;
417 return *this;
418 }
419 constexpr move_iterator& operator--()
420 {
421 --current_;
422 return *this;
423 }
424 constexpr move_iterator operator++(int)
425 {
426 move_iterator before(*this);
427 ++current_;
428 return before;
429 }
430
431 constexpr move_iterator operator--(int)
432 {
433 move_iterator before(*this);
434 --current_;
435 return before;
436 }
437
438 constexpr move_iterator operator+(difference_type n) const
439 {
440 return move_iterator(current_ + n);
441 }
442
443 constexpr move_iterator operator-(difference_type n) const
444 {
445 return move_iterator(current_ - n);
446 }
447
448 constexpr move_iterator& operator+=(difference_type n)
449 {
450 current_ += n;
451 return *this;
452 }
453
454 constexpr move_iterator& operator-=(difference_type n)
455 {
456 current_ -= n;
457 return *this;
458 }
459
460 private:
461 Iter current_;
462 };
463
464 template<class Iterator1, class Iterator2>
465 constexpr bool operator==(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
466 {
467 return lhs.base() == rhs.base();
468 }
469
470 template<class Iterator1, class Iterator2>
471 constexpr bool operator!=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
472 {
473 return lhs.base() != rhs.base();
474 }
475
476 template<class Iterator1, class Iterator2>
477 constexpr bool operator<(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
478 {
479 return lhs.base() < rhs.base();
480 }
481
482 template<class Iterator1, class Iterator2>
483 constexpr bool operator<=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
484 {
485 return lhs.base() <= rhs.base();
486 }
487
488 template<class Iterator1, class Iterator2>
489 constexpr bool operator>(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
490 {
491 return lhs.base() > rhs.base();
492 }
493
494 template<class Iterator1, class Iterator2>
495 constexpr bool operator>=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
496 {
497 return lhs.base() >= rhs.base();
498 }
499
500 template<class Iter>
501 constexpr move_iterator<Iter> operator+(typename move_iterator<Iter>::difference_type n, const move_iterator<Iter>& it)
502 {
503 return move_iterator(it.base() + n);
504 }
505
506 template<class Iterator1, class Iterator2>
507 constexpr auto operator-(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
508 -> decltype(lhs.base() - rhs.base())
509 {
510 return lhs.base() - rhs.base();
511 }
512 template<class Iter>
make_move_iterator(Iter i)513 constexpr move_iterator<Iter> make_move_iterator(Iter i)
514 {
515 return move_iterator<Iter> { i };
516 }
517 BASE_END_NAMESPACE()
518
519 #endif // API_BASE_CONTAINERS_ITERATOR_H
520