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