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