1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H 10 #define TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H 11 12 #include "test_macros.h" 13 #include "test_iterators.h" 14 15 template <class> 16 class assignable_iterator; 17 18 template <class It> 19 class simple_iterator 20 { 21 It it_; 22 23 public: 24 typedef std::input_iterator_tag iterator_category; 25 typedef typename std::iterator_traits<It>::value_type value_type; 26 typedef typename std::iterator_traits<It>::difference_type difference_type; 27 typedef It pointer; 28 typedef typename std::iterator_traits<It>::reference reference; 29 base(const simple_iterator & i)30 friend constexpr It base(const simple_iterator& i) {return i.it_;} 31 32 simple_iterator() = default; simple_iterator(It it)33 explicit constexpr simple_iterator(It it) : it_(it) {} 34 35 constexpr reference operator*() const {return *it_;} 36 37 constexpr simple_iterator& operator++() {++it_; return *this;} 38 constexpr simple_iterator operator++(int) 39 {simple_iterator tmp(*this); ++(*this); return tmp;} 40 }; 41 42 template <class It> 43 class value_iterator 44 { 45 It it_; 46 47 public: 48 typedef std::input_iterator_tag iterator_category; 49 typedef typename std::iterator_traits<It>::value_type value_type; 50 typedef typename std::iterator_traits<It>::difference_type difference_type; 51 typedef It pointer; 52 typedef typename std::iterator_traits<It>::reference reference; 53 base(const value_iterator & i)54 friend constexpr It base(const value_iterator& i) {return i.it_;} 55 56 value_iterator() = default; value_iterator(It it)57 explicit constexpr value_iterator(It it) : it_(it) {} 58 59 constexpr value_type operator*() const {return std::move(*it_);} 60 61 constexpr value_iterator& operator++() {++it_; return *this;} 62 constexpr value_iterator operator++(int) 63 {value_iterator tmp(*this); ++(*this); return tmp;} 64 }; 65 66 template <class It> 67 class void_plus_plus_iterator 68 { 69 It it_; 70 71 public: 72 typedef std::input_iterator_tag iterator_category; 73 typedef typename std::iterator_traits<It>::value_type value_type; 74 typedef typename std::iterator_traits<It>::difference_type difference_type; 75 typedef It pointer; 76 typedef typename std::iterator_traits<It>::reference reference; 77 base(const void_plus_plus_iterator & i)78 friend constexpr It base(const void_plus_plus_iterator& i) {return i.it_;} 79 80 void_plus_plus_iterator() = default; void_plus_plus_iterator(It it)81 explicit constexpr void_plus_plus_iterator(It it) : it_(it) {} 82 83 constexpr value_type operator*() const {return std::move(*it_);} 84 85 constexpr void_plus_plus_iterator& operator++() {++it_; return *this;} 86 constexpr void operator++(int) {++(*this);} 87 }; 88 89 // Not referenceable, constructible, and not move constructible. 90 template <class It> 91 class value_type_not_move_constructible_iterator 92 { 93 It it_; 94 95 public: 96 template<class T> 97 struct hold { 98 T value_; holdhold99 hold(T v) : value_(v) {} 100 hold(const hold&) = delete; 101 hold(hold&&) = delete; 102 }; 103 104 typedef std::input_iterator_tag iterator_category; 105 typedef typename std::iterator_traits<It>::value_type underlying_value_type; 106 typedef hold<underlying_value_type> value_type; 107 typedef typename std::iterator_traits<It>::difference_type difference_type; 108 typedef It pointer; 109 typedef typename std::iterator_traits<It>::reference reference; 110 base(const value_type_not_move_constructible_iterator & i)111 friend constexpr It base(const value_type_not_move_constructible_iterator& i) {return i.it_;} 112 113 value_type_not_move_constructible_iterator() = default; value_type_not_move_constructible_iterator(It it)114 explicit constexpr value_type_not_move_constructible_iterator(It it) : it_(it) {} 115 116 constexpr underlying_value_type operator*() const {return std::move(*it_);} 117 118 constexpr value_type_not_move_constructible_iterator& operator++() {++it_; return *this;} 119 constexpr void operator++(int) {++(*this);} 120 }; 121 122 template <class It> 123 class comparable_iterator 124 { 125 It it_; 126 127 public: 128 typedef std::input_iterator_tag iterator_category; 129 typedef typename std::iterator_traits<It>::value_type value_type; 130 typedef typename std::iterator_traits<It>::difference_type difference_type; 131 typedef It pointer; 132 typedef typename std::iterator_traits<It>::reference reference; 133 base(const comparable_iterator & i)134 friend constexpr It base(const comparable_iterator& i) {return i.it_;} 135 136 comparable_iterator() = default; comparable_iterator(It it)137 explicit constexpr comparable_iterator(It it) : it_(it) {} 138 139 constexpr reference operator*() const {return *it_;} 140 141 constexpr comparable_iterator& operator++() {++it_; return *this;} 142 constexpr comparable_iterator operator++(int) 143 {comparable_iterator tmp(*this); ++(*this); return tmp;} 144 145 friend constexpr bool operator==(const comparable_iterator& lhs, const simple_iterator<It>& rhs) { 146 return base(lhs) == base(rhs); 147 } 148 friend constexpr bool operator==(const simple_iterator<It>& lhs, const comparable_iterator& rhs) { 149 return base(lhs) == base(rhs); 150 } 151 152 friend constexpr auto operator-(const comparable_iterator& lhs, const simple_iterator<It>& rhs) { 153 return base(lhs) - base(rhs); 154 } 155 friend constexpr auto operator-(const simple_iterator<It>& lhs, const comparable_iterator& rhs) { 156 return base(lhs) - base(rhs); 157 } 158 }; 159 160 template<class T> 161 struct sentinel_type { 162 T base_; 163 164 template<class U> 165 friend constexpr bool operator==(const sentinel_type& lhs, const U& rhs) { return lhs.base_ == base(rhs); } 166 template<class U> 167 friend constexpr bool operator==(const U& lhs, const sentinel_type& rhs) { return base(lhs) == rhs.base_; } 168 }; 169 170 template<class T> 171 struct sized_sentinel_type { 172 T base_; 173 174 template<class U> 175 friend constexpr bool operator==(const sized_sentinel_type& lhs, const U& rhs) { return lhs.base_ - base(rhs); } 176 template<class U> 177 friend constexpr bool operator==(const U& lhs, const sized_sentinel_type& rhs) { return base(lhs) - rhs.base_; } 178 template<class U> 179 friend constexpr auto operator- (const sized_sentinel_type& lhs, const U& rhs) { return lhs.base_ - base(rhs); } 180 template<class U> 181 friend constexpr auto operator- (const U& lhs, const sized_sentinel_type& rhs) { return base(lhs) - rhs.base_; } 182 }; 183 184 template <class It> 185 class assignable_iterator 186 { 187 It it_; 188 189 public: 190 typedef std::input_iterator_tag iterator_category; 191 typedef typename std::iterator_traits<It>::value_type value_type; 192 typedef typename std::iterator_traits<It>::difference_type difference_type; 193 typedef It pointer; 194 typedef typename std::iterator_traits<It>::reference reference; 195 base(const assignable_iterator & i)196 friend constexpr It base(const assignable_iterator& i) {return i.it_;} 197 198 assignable_iterator() = default; assignable_iterator(It it)199 explicit constexpr assignable_iterator(It it) : it_(it) {} 200 assignable_iterator(const forward_iterator<It> & it)201 assignable_iterator(const forward_iterator<It>& it) : it_(base(it)) {} assignable_iterator(const sentinel_type<It> & it)202 assignable_iterator(const sentinel_type<It>& it) : it_(base(it)) {} 203 204 constexpr reference operator*() const {return *it_;} 205 206 constexpr assignable_iterator& operator++() {++it_; return *this;} 207 constexpr assignable_iterator operator++(int) 208 {assignable_iterator tmp(*this); ++(*this); return tmp;} 209 210 assignable_iterator& operator=(const forward_iterator<It> &other) { 211 it_ = base(other); 212 return *this; 213 } 214 215 assignable_iterator& operator=(const sentinel_type<It> &other) { 216 it_ = base(other); 217 return *this; 218 } 219 }; 220 221 #ifndef TEST_HAS_NO_EXCEPTIONS 222 template<class T> 223 struct sentinel_throws_on_convert { 224 T base_; 225 226 template<class U> 227 friend constexpr bool operator==(const sentinel_throws_on_convert& lhs, const U& rhs) { return lhs.base_ == base(rhs); } 228 template<class U> 229 friend constexpr bool operator==(const U& lhs, const sentinel_throws_on_convert& rhs) { return base(lhs) == rhs.base_; } 230 231 operator sentinel_type<int*>() const { throw 42; } 232 }; 233 234 template <class It> 235 class maybe_valueless_iterator 236 { 237 It it_; 238 239 public: 240 typedef std::input_iterator_tag iterator_category; 241 typedef typename std::iterator_traits<It>::value_type value_type; 242 typedef typename std::iterator_traits<It>::difference_type difference_type; 243 typedef It pointer; 244 typedef typename std::iterator_traits<It>::reference reference; 245 base(const maybe_valueless_iterator & i)246 friend constexpr It base(const maybe_valueless_iterator& i) {return i.it_;} 247 248 maybe_valueless_iterator() = default; maybe_valueless_iterator(It it)249 explicit constexpr maybe_valueless_iterator(It it) : it_(it) {} 250 maybe_valueless_iterator(const forward_iterator<It> & it)251 maybe_valueless_iterator(const forward_iterator<It>& it) : it_(base(it)) {} 252 253 constexpr reference operator*() const {return *it_;} 254 255 constexpr maybe_valueless_iterator& operator++() {++it_; return *this;} 256 constexpr maybe_valueless_iterator operator++(int) 257 {maybe_valueless_iterator tmp(*this); ++(*this); return tmp;} 258 259 maybe_valueless_iterator& operator=(const forward_iterator<It> &other) { 260 it_ = base(other); 261 return *this; 262 } 263 }; 264 #endif // TEST_HAS_NO_EXCEPTIONS 265 266 #endif // TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H 267