• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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