1 /*
2 * Copyright (C) 2023 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 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 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<iterator> & other)267 constexpr reverse_iterator(const reverse_iterator<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 }
273 constexpr reverse_iterator& operator++()
274 {
275 it_--;
276 return *this;
277 }
278 constexpr reverse_iterator operator++(int)
279 {
280 reverse_iterator t(*this);
281 --it_;
282 return t;
283 }
284 constexpr reverse_iterator& operator--()
285 {
286 it_++;
287 return *this;
288 }
289 constexpr reverse_iterator operator--(int)
290 {
291 reverse_iterator t(*this);
292 ++it_;
293 return t;
294 }
295
296 constexpr reference operator*() const
297 {
298 iterator_type it = it_;
299 return (--it).operator*();
300 }
301 constexpr pointer operator->() const
302 {
303 iterator_type it = it_;
304 return (--it).operator->();
305 }
306
307 constexpr reverse_iterator operator+(difference_type n) const
308 {
309 return reverse_iterator(it_ - n);
310 }
311 constexpr reverse_iterator& operator+=(difference_type n)
312 {
313 it_ -= n;
314 return *this;
315 }
316 constexpr reverse_iterator operator-(difference_type n) const
317 {
318 return reverse_iterator(it_ + n);
319 }
320 constexpr reverse_iterator& operator-=(difference_type n)
321 {
322 it_ += n;
323 return *this;
324 }
325 constexpr difference_type operator-(const reverse_iterator& other) const
326 {
327 return other.it_ - it_;
328 }
329 constexpr bool operator==(const reverse_iterator& other) const
330 {
331 return it_ == other.it_;
332 }
333 constexpr bool operator!=(const reverse_iterator& other) const
334 {
335 return it_ != other.it_;
336 }
base()337 constexpr iterator_type base() const
338 {
339 return it_;
340 }
341 constexpr bool operator<(const reverse_iterator& other) const noexcept
342 {
343 return it_ > other.it_;
344 }
345 constexpr bool operator<=(const reverse_iterator& other) const noexcept
346 {
347 return it_ >= other.it_;
348 }
349 constexpr bool operator>(const reverse_iterator& other) const noexcept
350 {
351 return it_ < other.it_;
352 }
353 constexpr bool operator>=(const reverse_iterator& other) const noexcept
354 {
355 return it_ <= other.it_;
356 }
357
358 private:
359 Iter it_;
360 };
361
362 template<class Iter>
363 class move_iterator {
364 public:
365 using iterator_type = Iter;
366 using iterator_category = typename Iter::iterator_category;
367 using value_type = typename Iter::value_type;
368 using difference_type = typename Iter::difference_type;
369 using pointer = typename Iter::pointer;
370 using reference = value_type&&;
371
372 /** constructs a new iterator adaptor */
373 constexpr move_iterator() = default;
374
move_iterator(iterator_type x)375 constexpr explicit move_iterator(iterator_type x) : current_(x) {};
376
377 template<class U>
move_iterator(const move_iterator<U> & other)378 constexpr move_iterator(const move_iterator<U>& other) : current_(other.current) {};
379
380 /** assigns another iterator */
381 template<class U>
382 constexpr move_iterator& operator=(const move_iterator<U>& other)
383 {
384 current_ = other.current;
385 }
386
387 /** accesses the underlying iterator */
base()388 constexpr iterator_type base() const
389 {
390 return current_;
391 }
392
393 /** accesses the pointed-to element */
394 constexpr reference operator*() const
395 {
396 return static_cast<reference>(*current_);
397 }
398
399 constexpr pointer operator->() const
400 {
401 return *current_;
402 }
403
404 /** accesses an element by index */
405 constexpr reference operator[](difference_type n) const
406 {
407 return static_cast<reference>(current_[n]);
408 }
409
410 /** advances or decrements the iterator */
411 constexpr move_iterator& operator++()
412 {
413 ++current_;
414 return *this;
415 }
416 constexpr move_iterator& operator--()
417 {
418 --current_;
419 return *this;
420 }
421 constexpr move_iterator operator++(int)
422 {
423 move_iterator before(*this);
424 ++current_;
425 return before;
426 }
427
428 constexpr move_iterator operator--(int)
429 {
430 move_iterator before(*this);
431 --current_;
432 return before;
433 }
434
435 constexpr move_iterator operator+(difference_type n) const
436 {
437 return { current_ + n };
438 }
439
440 constexpr move_iterator operator-(difference_type n) const
441 {
442 return { current_ + n };
443 }
444
445 constexpr move_iterator& operator+=(difference_type n)
446 {
447 current_ += n;
448 return *this;
449 }
450
451 constexpr move_iterator& operator-=(difference_type n)
452 {
453 current_ -= n;
454 return *this;
455 }
456
457 private:
458 Iter current_;
459 };
460
461 template<class Iterator1, class Iterator2>
462 constexpr bool operator==(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
463 {
464 return lhs.base() == rhs.base();
465 }
466
467 template<class Iterator1, class Iterator2>
468 constexpr bool operator!=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
469 {
470 return lhs.base() != rhs.base();
471 }
472
473 template<class Iterator1, class Iterator2>
474 constexpr bool operator<(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
475 {
476 return lhs.base() < rhs.base();
477 }
478
479 template<class Iterator1, class Iterator2>
480 constexpr bool operator<=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
481 {
482 return lhs.base() <= rhs.base();
483 }
484
485 template<class Iterator1, class Iterator2>
486 constexpr bool operator>(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
487 {
488 return lhs.base() > rhs.base();
489 }
490
491 template<class Iterator1, class Iterator2>
492 constexpr bool operator>=(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
493 {
494 return lhs.base() >= rhs.base();
495 }
496
497 template<class Iter>
498 constexpr move_iterator<Iter> operator+(typename move_iterator<Iter>::difference_type n, const move_iterator<Iter>& it)
499 {
500 return { it.base() + n };
501 }
502
503 template<class Iterator1, class Iterator2>
504 constexpr auto operator-(const move_iterator<Iterator1>& lhs, const move_iterator<Iterator2>& rhs)
505 -> decltype(lhs.base() - rhs.base())
506 {
507 return lhs.base() - rhs.base();
508 }
509 template<class Iter>
make_move_iterator(Iter i)510 constexpr move_iterator<Iter> make_move_iterator(Iter i)
511 {
512 return move_iterator<Iter> { i };
513 }
514 BASE_END_NAMESPACE()
515
516 #endif // API_BASE_CONTAINERS_ITERATOR_H