• 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 MAPLE_UTIL_INCLUDE_ITERATOR_H
17 #define MAPLE_UTIL_INCLUDE_ITERATOR_H
18 #include <iterator>
19 #include "meta.h"
20 
21 namespace maple {
22 namespace utils {
23 template <typename Iterator, typename Container>
24 struct mpl_iterator_traits {
25     using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
26     using value_type = typename std::iterator_traits<Iterator>::value_type;
27     using difference_type = typename std::iterator_traits<Iterator>::difference_type;
28     using pointer = typename std::iterator_traits<Iterator>::pointer;
29     using reference = typename std::iterator_traits<Iterator>::reference;
30 
operator_dereferencempl_iterator_traits31     static reference operator_dereference(Iterator iter)
32     {
33         return *iter;
34     };
35 
operator_arrowmpl_iterator_traits36     static Iterator operator_arrow(Iterator iter)
37     {
38         return iter;
39     }
40 
operator_bracketmpl_iterator_traits41     static reference operator_bracket(Iterator iter, difference_type n)
42     {
43         return iter[n];
44     }
45 };
46 
47 template <typename Iterator, typename Container>
48 class mpl_iterator {
49     using Traits = mpl_iterator_traits<Iterator, Container>;
50 
51 public:
52     using iterator_category = typename Traits::iterator_category;
53     using value_type = typename Traits::value_type;
54     using difference_type = typename Traits::difference_type;
55     using pointer = typename Traits::pointer;
56     using reference = typename Traits::reference;
57 
mpl_iterator(Iterator iter)58     explicit mpl_iterator(Iterator iter) : iter(iter) {}
59 
60     template <typename U, typename = std::enable_if_t<ptr::const_of_v<U, pointer>>>
mpl_iterator(const mpl_iterator<U,Container> & iter)61     mpl_iterator(const mpl_iterator<U, Container> &iter) : iter(iter.base())
62     {
63     }
64 
65     ~mpl_iterator() noexcept = default;
66 
67     reference operator*() const noexcept
68     {
69         return Traits::operator_dereference(iter);
70     }
71 
72     pointer operator->() const noexcept
73     {
74         return Traits::operator_arrow(iter);
75     }
76 
77     mpl_iterator &operator++() noexcept
78     {
79         ++iter;
80         return *this;
81     }
82 
83     mpl_iterator operator++(int) noexcept
84     {
85         return mpl_iterator(iter++);
86     }
87 
88     mpl_iterator &operator--() noexcept
89     {
90         --iter;
91         return *this;
92     }
93 
94     mpl_iterator operator--(int) noexcept
95     {
96         return mpl_iterator(iter--);
97     }
98 
99     reference operator[](difference_type n) const noexcept
100     {
101         return Traits::operator_bracket(iter, n);
102     }
103 
104     mpl_iterator &operator+=(difference_type n) noexcept
105     {
106         iter += n;
107         return *this;
108     }
109 
110     mpl_iterator &operator-=(difference_type n) noexcept
111     {
112         iter -= n;
113         return *this;
114     }
115 
base()116     Iterator base() const noexcept
117     {
118         return iter;
119     }
120 
121 private:
122     Iterator iter;
123 };
124 
125 template <typename T, typename Container>
126 inline bool operator==(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
127 {
128     return lhs.base() == rhs.base();
129 }
130 
131 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
132 inline bool operator==(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
133 {
134     return lhs.base() == rhs.base();
135 }
136 
137 template <typename T, typename Container>
138 inline bool operator!=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
139 {
140     return !(lhs == rhs);
141 }
142 
143 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
144 inline bool operator!=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
145 {
146     return !(lhs == rhs);
147 }
148 
149 template <typename T, typename Container>
150 inline bool operator<(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
151 {
152     return lhs.base() < rhs.base();
153 }
154 
155 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
156 inline bool operator<(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
157 {
158     return lhs.base() < rhs.base();
159 }
160 
161 template <typename T, typename Container>
162 inline bool operator<=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
163 {
164     return lhs.base() <= rhs.base();
165 }
166 
167 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
168 inline bool operator<=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
169 {
170     return lhs.base() <= rhs.base();
171 }
172 
173 template <typename T, typename Container>
174 inline bool operator>(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
175 {
176     return lhs.base() > rhs.base();
177 }
178 
179 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
180 inline bool operator>(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
181 {
182     return lhs.base() > rhs.base();
183 }
184 
185 template <typename T, typename Container>
186 inline bool operator>=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept
187 {
188     return lhs.base() >= rhs.base();
189 }
190 
191 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
192 inline bool operator>=(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
193 {
194     return lhs.base() >= rhs.base();
195 }
196 
197 template <typename T, typename Container>
198 mpl_iterator<T, Container> operator+(const mpl_iterator<T, Container> &iter,
199                                      typename mpl_iterator<T, Container>::difference_type n) noexcept
200 {
201     return mpl_iterator<T, Container>(iter.base() + n);
202 }
203 
204 template <typename T, typename Container>
205 mpl_iterator<T, Container> operator+(typename mpl_iterator<T, Container>::difference_type n,
206                                      const mpl_iterator<T, Container> &iter) noexcept
207 {
208     return mpl_iterator<T, Container>(n + iter.base());
209 }
210 
211 template <typename T, typename Container>
212 mpl_iterator<T, Container> operator-(const mpl_iterator<T, Container> &iter,
213                                      typename mpl_iterator<T, Container>::difference_type n) noexcept
214 {
215     return mpl_iterator<T, Container>(iter.base() - n);
216 }
217 
218 template <typename T, typename Container>
219 inline auto operator-(const mpl_iterator<T, Container> &lhs, const mpl_iterator<T, Container> &rhs) noexcept ->
220     typename mpl_iterator<T, Container>::difference_type
221 {
222     return lhs.base() - rhs.base();
223 }
224 
225 template <typename T, typename U, typename Container, typename = std::enable_if_t<ptr::is_ncv_same_v<T, U>>>
226 inline auto operator-(const mpl_iterator<T, Container> &lhs, const mpl_iterator<U, Container> &rhs) noexcept
227     -> decltype(lhs.base() - rhs.base())
228 {
229     return lhs.base() - rhs.base();
230 }
231 }  // namespace utils
232 }  // namespace maple
233 
234 #endif  // MAPLE_UTIL_INCLUDE_ITERATOR_H
235