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___FLAT_SET_RA_ITERATOR_H 11 #define _LIBCPP___FLAT_SET_RA_ITERATOR_H 12 13 #include "__type_traits/is_same.h" 14 #include <__compare/three_way_comparable.h> 15 #include <__config> 16 #include <__iterator/incrementable_traits.h> 17 #include <__iterator/iterator_traits.h> 18 #include <__type_traits/is_constructible.h> 19 #include <__utility/move.h> 20 21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22 # pragma GCC system_header 23 #endif 24 25 _LIBCPP_PUSH_MACROS 26 #include <__undef_macros> 27 28 #if _LIBCPP_STD_VER >= 23 29 30 _LIBCPP_BEGIN_NAMESPACE_STD 31 32 /** 33 * __ra_iterator is a random access iterator that wraps an underlying iterator. 34 * It also stores the underlying container type in its type so that algorithms 35 * can optimize based on the underlying container type, and to avoid inadvertently 36 * mixing iterators coming from different containers.. 37 */ 38 template <class _Container, class _Iterator> 39 struct __ra_iterator { 40 private: 41 _Iterator __iter_; 42 43 friend _Container; 44 45 // note: checking the concept random_access_iterator does not work for incomplete types 46 static_assert(_IsSame<typename iterator_traits<_Iterator>::iterator_category, random_access_iterator_tag>::value, 47 "Underlying iterator must be a random access iterator"); 48 49 public: 50 using iterator_concept = random_access_iterator_tag; // deliberately lower contiguous_iterator 51 using iterator_category = random_access_iterator_tag; 52 using value_type = iter_value_t<_Iterator>; 53 using difference_type = iter_difference_t<_Iterator>; 54 55 _LIBCPP_HIDE_FROM_ABI __ra_iterator() 56 requires is_default_constructible_v<_Iterator> 57 = default; 58 __ra_iterator__ra_iterator59 _LIBCPP_HIDE_FROM_ABI explicit constexpr __ra_iterator(_Iterator __iter) : __iter_(std::move(__iter)) {} 60 __base__ra_iterator61 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __base() const noexcept(noexcept(_Iterator(__iter_))) { return __iter_; } 62 decltype__ra_iterator63 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__iter_; } 64 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator->() const 65 requires requires { __iter_.operator->(); } 66 { 67 return __iter_.operator->(); 68 } 69 70 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator++() { 71 ++__iter_; 72 return *this; 73 } 74 75 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator++(int) { 76 __ra_iterator __tmp(*this); 77 ++*this; 78 return __tmp; 79 } 80 81 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator--() { 82 --__iter_; 83 return *this; 84 } 85 86 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator--(int) { 87 __ra_iterator __tmp(*this); 88 --*this; 89 return __tmp; 90 } 91 92 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator+=(difference_type __x) { 93 __iter_ += __x; 94 return *this; 95 } 96 97 _LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator-=(difference_type __x) { 98 __iter_ -= __x; 99 return *this; 100 } 101 decltype__ra_iterator102 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const { return *(*this + __n); } 103 104 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __ra_iterator& __x, const __ra_iterator& __y) { 105 return __x.__iter_ == __y.__iter_; 106 } 107 108 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __ra_iterator& __x, const __ra_iterator& __y) { 109 return __x.__iter_ < __y.__iter_; 110 } 111 112 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __ra_iterator& __x, const __ra_iterator& __y) { 113 return __y < __x; 114 } 115 116 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __ra_iterator& __x, const __ra_iterator& __y) { 117 return !(__y < __x); 118 } 119 120 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __ra_iterator& __x, const __ra_iterator& __y) { 121 return !(__x < __y); 122 } 123 124 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y) 125 requires three_way_comparable<_Iterator> 126 { 127 return __x.__iter_ <=> __y.__iter_; 128 } 129 130 _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(const __ra_iterator& __i, difference_type __n) { 131 auto __tmp = __i; 132 __tmp += __n; 133 return __tmp; 134 } 135 136 _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(difference_type __n, const __ra_iterator& __i) { 137 return __i + __n; 138 } 139 140 _LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator-(const __ra_iterator& __i, difference_type __n) { 141 auto __tmp = __i; 142 __tmp -= __n; 143 return __tmp; 144 } 145 146 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __ra_iterator& __x, const __ra_iterator& __y) { 147 return __x.__iter_ - __y.__iter_; 148 } 149 }; 150 151 _LIBCPP_END_NAMESPACE_STD 152 153 #endif // _LIBCPP_STD_VER >= 23 154 155 _LIBCPP_POP_MACROS 156 157 #endif // _LIBCPP___FLAT_SET_RA_ITERATOR_H 158