1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 11 #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 12 13 #include <__algorithm/unwrap_iter.h> 14 #include <__compare/compare_three_way_result.h> 15 #include <__compare/three_way_comparable.h> 16 #include <__concepts/convertible_to.h> 17 #include <__config> 18 #include <__iterator/advance.h> 19 #include <__iterator/concepts.h> 20 #include <__iterator/incrementable_traits.h> 21 #include <__iterator/iter_move.h> 22 #include <__iterator/iter_swap.h> 23 #include <__iterator/iterator.h> 24 #include <__iterator/iterator_traits.h> 25 #include <__iterator/next.h> 26 #include <__iterator/prev.h> 27 #include <__iterator/readable_traits.h> 28 #include <__memory/addressof.h> 29 #include <__ranges/access.h> 30 #include <__ranges/concepts.h> 31 #include <__ranges/subrange.h> 32 #include <__utility/move.h> 33 #include <type_traits> 34 35 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 36 # pragma GCC system_header 37 #endif 38 39 _LIBCPP_BEGIN_NAMESPACE_STD 40 41 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 42 template <class _Iter> 43 class _LIBCPP_TEMPLATE_VIS reverse_iterator 44 #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) 45 : public iterator<typename iterator_traits<_Iter>::iterator_category, 46 typename iterator_traits<_Iter>::value_type, 47 typename iterator_traits<_Iter>::difference_type, 48 typename iterator_traits<_Iter>::pointer, 49 typename iterator_traits<_Iter>::reference> 50 #endif 51 { 52 _LIBCPP_SUPPRESS_DEPRECATED_POP 53 private: 54 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 55 _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break 56 #endif 57 58 #if _LIBCPP_STD_VER > 17 59 static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, 60 "reverse_iterator<It> requires It to be a bidirectional iterator."); 61 #endif // _LIBCPP_STD_VER > 17 62 63 protected: 64 _Iter current; 65 public: 66 using iterator_type = _Iter; 67 68 using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, 69 random_access_iterator_tag, 70 typename iterator_traits<_Iter>::iterator_category>; 71 using pointer = typename iterator_traits<_Iter>::pointer; 72 #if _LIBCPP_STD_VER > 17 73 using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>; 74 using value_type = iter_value_t<_Iter>; 75 using difference_type = iter_difference_t<_Iter>; 76 using reference = iter_reference_t<_Iter>; 77 #else 78 using value_type = typename iterator_traits<_Iter>::value_type; 79 using difference_type = typename iterator_traits<_Iter>::difference_type; 80 using reference = typename iterator_traits<_Iter>::reference; 81 #endif 82 83 #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES 84 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 85 reverse_iterator() : __t(), current() {} 86 87 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 88 explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} 89 90 template <class _Up, class = __enable_if_t< 91 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 92 > > 93 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 94 reverse_iterator(const reverse_iterator<_Up>& __u) 95 : __t(__u.base()), current(__u.base()) 96 { } 97 98 template <class _Up, class = __enable_if_t< 99 !is_same<_Up, _Iter>::value && 100 is_convertible<_Up const&, _Iter>::value && 101 is_assignable<_Iter&, _Up const&>::value 102 > > 103 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 104 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 105 __t = current = __u.base(); 106 return *this; 107 } 108 #else 109 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 110 reverse_iterator() : current() {} 111 112 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 113 explicit reverse_iterator(_Iter __x) : current(__x) {} 114 115 template <class _Up, class = __enable_if_t< 116 !is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value 117 > > 118 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 119 reverse_iterator(const reverse_iterator<_Up>& __u) 120 : current(__u.base()) 121 { } 122 123 template <class _Up, class = __enable_if_t< 124 !is_same<_Up, _Iter>::value && 125 is_convertible<_Up const&, _Iter>::value && 126 is_assignable<_Iter&, _Up const&>::value 127 > > 128 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 129 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { 130 current = __u.base(); 131 return *this; 132 } 133 #endif 134 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 135 _Iter base() const {return current;} 136 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 137 reference operator*() const {_Iter __tmp = current; return *--__tmp;} 138 139 #if _LIBCPP_STD_VER > 17 140 _LIBCPP_INLINE_VISIBILITY 141 constexpr pointer operator->() const 142 requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } 143 { 144 if constexpr (is_pointer_v<_Iter>) { 145 return std::prev(current); 146 } else { 147 return std::prev(current).operator->(); 148 } 149 } 150 #else 151 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 152 pointer operator->() const { 153 return std::addressof(operator*()); 154 } 155 #endif // _LIBCPP_STD_VER > 17 156 157 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 158 reverse_iterator& operator++() {--current; return *this;} 159 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 160 reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} 161 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 162 reverse_iterator& operator--() {++current; return *this;} 163 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 164 reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} 165 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 166 reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} 167 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 168 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} 169 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 170 reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} 171 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 172 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} 173 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 174 reference operator[](difference_type __n) const {return *(*this + __n);} 175 176 #if _LIBCPP_STD_VER > 17 177 _LIBCPP_HIDE_FROM_ABI friend constexpr 178 iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) 179 noexcept(is_nothrow_copy_constructible_v<_Iter> && 180 noexcept(ranges::iter_move(--declval<_Iter&>()))) { 181 auto __tmp = __i.base(); 182 return ranges::iter_move(--__tmp); 183 } 184 185 template <indirectly_swappable<_Iter> _Iter2> 186 _LIBCPP_HIDE_FROM_ABI friend constexpr 187 void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) 188 noexcept(is_nothrow_copy_constructible_v<_Iter> && 189 is_nothrow_copy_constructible_v<_Iter2> && 190 noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) { 191 auto __xtmp = __x.base(); 192 auto __ytmp = __y.base(); 193 ranges::iter_swap(--__xtmp, --__ytmp); 194 } 195 #endif // _LIBCPP_STD_VER > 17 196 }; 197 198 template <class _Iter> 199 struct __is_reverse_iterator : false_type {}; 200 201 template <class _Iter> 202 struct __is_reverse_iterator<reverse_iterator<_Iter> > : true_type {}; 203 204 template <class _Iter1, class _Iter2> 205 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 206 bool 207 operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 208 #if _LIBCPP_STD_VER > 17 209 requires requires { 210 { __x.base() == __y.base() } -> convertible_to<bool>; 211 } 212 #endif // _LIBCPP_STD_VER > 17 213 { 214 return __x.base() == __y.base(); 215 } 216 217 template <class _Iter1, class _Iter2> 218 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 219 bool 220 operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 221 #if _LIBCPP_STD_VER > 17 222 requires requires { 223 { __x.base() > __y.base() } -> convertible_to<bool>; 224 } 225 #endif // _LIBCPP_STD_VER > 17 226 { 227 return __x.base() > __y.base(); 228 } 229 230 template <class _Iter1, class _Iter2> 231 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 232 bool 233 operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 234 #if _LIBCPP_STD_VER > 17 235 requires requires { 236 { __x.base() != __y.base() } -> convertible_to<bool>; 237 } 238 #endif // _LIBCPP_STD_VER > 17 239 { 240 return __x.base() != __y.base(); 241 } 242 243 template <class _Iter1, class _Iter2> 244 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 245 bool 246 operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 247 #if _LIBCPP_STD_VER > 17 248 requires requires { 249 { __x.base() < __y.base() } -> convertible_to<bool>; 250 } 251 #endif // _LIBCPP_STD_VER > 17 252 { 253 return __x.base() < __y.base(); 254 } 255 256 template <class _Iter1, class _Iter2> 257 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 258 bool 259 operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 260 #if _LIBCPP_STD_VER > 17 261 requires requires { 262 { __x.base() <= __y.base() } -> convertible_to<bool>; 263 } 264 #endif // _LIBCPP_STD_VER > 17 265 { 266 return __x.base() <= __y.base(); 267 } 268 269 template <class _Iter1, class _Iter2> 270 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 271 bool 272 operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 273 #if _LIBCPP_STD_VER > 17 274 requires requires { 275 { __x.base() >= __y.base() } -> convertible_to<bool>; 276 } 277 #endif // _LIBCPP_STD_VER > 17 278 { 279 return __x.base() >= __y.base(); 280 } 281 282 #if _LIBCPP_STD_VER > 17 283 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> 284 _LIBCPP_HIDE_FROM_ABI constexpr 285 compare_three_way_result_t<_Iter1, _Iter2> 286 operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 287 { 288 return __y.base() <=> __x.base(); 289 } 290 #endif // _LIBCPP_STD_VER > 17 291 292 #ifndef _LIBCPP_CXX03_LANG 293 template <class _Iter1, class _Iter2> 294 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 295 auto 296 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 297 -> decltype(__y.base() - __x.base()) 298 { 299 return __y.base() - __x.base(); 300 } 301 #else 302 template <class _Iter1, class _Iter2> 303 inline _LIBCPP_INLINE_VISIBILITY 304 typename reverse_iterator<_Iter1>::difference_type 305 operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) 306 { 307 return __y.base() - __x.base(); 308 } 309 #endif 310 311 template <class _Iter> 312 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 313 reverse_iterator<_Iter> 314 operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) 315 { 316 return reverse_iterator<_Iter>(__x.base() - __n); 317 } 318 319 #if _LIBCPP_STD_VER > 17 320 template <class _Iter1, class _Iter2> 321 requires (!sized_sentinel_for<_Iter1, _Iter2>) 322 inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true; 323 #endif // _LIBCPP_STD_VER > 17 324 325 #if _LIBCPP_STD_VER > 11 326 template <class _Iter> 327 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 328 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) 329 { 330 return reverse_iterator<_Iter>(__i); 331 } 332 #endif 333 334 #if _LIBCPP_STD_VER <= 17 335 template <class _Iter> 336 using __unconstrained_reverse_iterator = reverse_iterator<_Iter>; 337 #else 338 339 // __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working 340 // around a language issue in C++20. 341 // In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will 342 // result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not 343 // an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a 344 // C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with 345 // tweaks to make it support hostile iterators. 346 // 347 // A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match 348 // and the other requires an implicit conversion, for example: 349 // friend bool operator==(const BaseIter&, const DerivedIter&); 350 // 351 // C++20 rules for rewriting equality operators create another overload of this function with parameters reversed: 352 // friend bool operator==(const DerivedIter&, const BaseIter&); 353 // 354 // This creates an ambiguity in overload resolution. 355 // 356 // Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function 357 // body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however, 358 // it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its 359 // base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload 360 // resolution. This class simply removes the problematic constraints from comparison functions. 361 template <class _Iter> 362 class __unconstrained_reverse_iterator { 363 _Iter __iter_; 364 365 public: 366 static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>); 367 368 using iterator_type = _Iter; 369 using iterator_category = 370 _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; 371 using pointer = __iterator_pointer_type<_Iter>; 372 using value_type = iter_value_t<_Iter>; 373 using difference_type = iter_difference_t<_Iter>; 374 using reference = iter_reference_t<_Iter>; 375 376 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; 377 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; 378 _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} 379 380 _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; } 381 _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { 382 auto __tmp = __iter_; 383 return *--__tmp; 384 } 385 386 _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { 387 if constexpr (is_pointer_v<_Iter>) { 388 return std::prev(__iter_); 389 } else { 390 return std::prev(__iter_).operator->(); 391 } 392 } 393 394 _LIBCPP_HIDE_FROM_ABI friend constexpr 395 iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) 396 noexcept(is_nothrow_copy_constructible_v<_Iter> && 397 noexcept(ranges::iter_move(--declval<_Iter&>()))) { 398 auto __tmp = __i.base(); 399 return ranges::iter_move(--__tmp); 400 } 401 402 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() { 403 --__iter_; 404 return *this; 405 } 406 407 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) { 408 auto __tmp = *this; 409 --__iter_; 410 return __tmp; 411 } 412 413 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() { 414 ++__iter_; 415 return *this; 416 } 417 418 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) { 419 auto __tmp = *this; 420 ++__iter_; 421 return __tmp; 422 } 423 424 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) { 425 __iter_ -= __n; 426 return *this; 427 } 428 429 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) { 430 __iter_ += __n; 431 return *this; 432 } 433 434 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const { 435 return __unconstrained_reverse_iterator(__iter_ - __n); 436 } 437 438 _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const { 439 return __unconstrained_reverse_iterator(__iter_ + __n); 440 } 441 442 _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const { 443 return __other.__iter_ - __iter_; 444 } 445 446 _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); } 447 448 // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the 449 // rationale. 450 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 451 operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 452 return __lhs.base() == __rhs.base(); 453 } 454 455 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 456 operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 457 return __lhs.base() != __rhs.base(); 458 } 459 460 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 461 operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 462 return __lhs.base() > __rhs.base(); 463 } 464 465 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 466 operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 467 return __lhs.base() < __rhs.base(); 468 } 469 470 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 471 operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 472 return __lhs.base() >= __rhs.base(); 473 } 474 475 _LIBCPP_HIDE_FROM_ABI friend constexpr bool 476 operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { 477 return __lhs.base() <= __rhs.base(); 478 } 479 }; 480 481 template <class _Iter> 482 struct __is_reverse_iterator<__unconstrained_reverse_iterator<_Iter>> : true_type {}; 483 484 #endif // _LIBCPP_STD_VER <= 17 485 486 template <template <class> class _RevIter1, template <class> class _RevIter2, class _Iter> 487 struct __unwrap_reverse_iter_impl { 488 using _UnwrappedIter = decltype(__unwrap_iter_impl<_Iter>::__unwrap(std::declval<_Iter>())); 489 using _ReverseWrapper = _RevIter1<_RevIter2<_Iter> >; 490 491 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ReverseWrapper 492 __rewrap(_ReverseWrapper __orig_iter, _UnwrappedIter __unwrapped_iter) { 493 return _ReverseWrapper( 494 _RevIter2<_Iter>(__unwrap_iter_impl<_Iter>::__rewrap(__orig_iter.base().base(), __unwrapped_iter))); 495 } 496 497 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _UnwrappedIter __unwrap(_ReverseWrapper __i) _NOEXCEPT { 498 return __unwrap_iter_impl<_Iter>::__unwrap(__i.base().base()); 499 } 500 }; 501 502 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 503 template <ranges::bidirectional_range _Range> 504 _LIBCPP_HIDE_FROM_ABI constexpr ranges:: 505 subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>> 506 __reverse_range(_Range&& __range) { 507 auto __first = ranges::begin(__range); 508 return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)}; 509 } 510 #endif 511 512 template <class _Iter, bool __b> 513 struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b> 514 : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {}; 515 516 #if _LIBCPP_STD_VER > 17 517 518 template <class _Iter, bool __b> 519 struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> 520 : __unwrap_reverse_iter_impl<reverse_iterator, __unconstrained_reverse_iterator, _Iter> {}; 521 522 template <class _Iter, bool __b> 523 struct __unwrap_iter_impl<__unconstrained_reverse_iterator<reverse_iterator<_Iter>>, __b> 524 : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, reverse_iterator, _Iter> {}; 525 526 template <class _Iter, bool __b> 527 struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> 528 : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {}; 529 530 #endif // _LIBCPP_STD_VER > 17 531 532 _LIBCPP_END_NAMESPACE_STD 533 534 #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H 535