File indexing completed on 2026-05-03 08:13:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___ITERATOR_BOUNDED_ITER_H
0011 #define _LIBCPP___CXX03___ITERATOR_BOUNDED_ITER_H
0012
0013 #include <__cxx03/__assert>
0014 #include <__cxx03/__compare/ordering.h>
0015 #include <__cxx03/__compare/three_way_comparable.h>
0016 #include <__cxx03/__config>
0017 #include <__cxx03/__iterator/iterator_traits.h>
0018 #include <__cxx03/__memory/pointer_traits.h>
0019 #include <__cxx03/__type_traits/enable_if.h>
0020 #include <__cxx03/__type_traits/integral_constant.h>
0021 #include <__cxx03/__type_traits/is_convertible.h>
0022 #include <__cxx03/__utility/move.h>
0023
0024 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0025 # pragma GCC system_header
0026 #endif
0027
0028 _LIBCPP_PUSH_MACROS
0029 #include <__cxx03/__undef_macros>
0030
0031 _LIBCPP_BEGIN_NAMESPACE_STD
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > >
0051 struct __bounded_iter {
0052 using value_type = typename iterator_traits<_Iterator>::value_type;
0053 using difference_type = typename iterator_traits<_Iterator>::difference_type;
0054 using pointer = typename iterator_traits<_Iterator>::pointer;
0055 using reference = typename iterator_traits<_Iterator>::reference;
0056 using iterator_category = typename iterator_traits<_Iterator>::iterator_category;
0057 #if _LIBCPP_STD_VER >= 20
0058 using iterator_concept = contiguous_iterator_tag;
0059 #endif
0060
0061
0062
0063
0064
0065 _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default;
0066
0067 _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default;
0068 _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default;
0069
0070 template <class _OtherIterator, __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value, int> = 0>
0071 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT
0072 : __current_(__other.__current_),
0073 __begin_(__other.__begin_),
0074 __end_(__other.__end_) {}
0075
0076
0077 _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default;
0078 _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default;
0079
0080 private:
0081
0082
0083
0084
0085
0086
0087
0088
0089 _LIBCPP_HIDE_FROM_ABI
0090 _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter(_Iterator __current, _Iterator __begin, _Iterator __end)
0091 : __current_(__current), __begin_(__begin), __end_(__end) {
0092 _LIBCPP_ASSERT_INTERNAL(
0093 __begin <= __current, "__bounded_iter(current, begin, end): current and begin are inconsistent");
0094 _LIBCPP_ASSERT_INTERNAL(
0095 __current <= __end, "__bounded_iter(current, begin, end): current and end are inconsistent");
0096 }
0097
0098 template <class _It>
0099 friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It);
0100
0101 public:
0102
0103
0104
0105
0106
0107
0108
0109 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT {
0110 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0111 __current_ != __end_, "__bounded_iter::operator*: Attempt to dereference an iterator at the end");
0112 return *__current_;
0113 }
0114
0115 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT {
0116 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0117 __current_ != __end_, "__bounded_iter::operator->: Attempt to dereference an iterator at the end");
0118 return std::__to_address(__current_);
0119 }
0120
0121 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT {
0122 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0123 __n >= __begin_ - __current_, "__bounded_iter::operator[]: Attempt to index an iterator past the start");
0124 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0125 __n < __end_ - __current_, "__bounded_iter::operator[]: Attempt to index an iterator at or past the end");
0126 return __current_[__n];
0127 }
0128
0129
0130
0131
0132 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator++() _NOEXCEPT {
0133 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0134 __current_ != __end_, "__bounded_iter::operator++: Attempt to advance an iterator past the end");
0135 ++__current_;
0136 return *this;
0137 }
0138 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator++(int) _NOEXCEPT {
0139 __bounded_iter __tmp(*this);
0140 ++*this;
0141 return __tmp;
0142 }
0143
0144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator--() _NOEXCEPT {
0145 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0146 __current_ != __begin_, "__bounded_iter::operator--: Attempt to rewind an iterator past the start");
0147 --__current_;
0148 return *this;
0149 }
0150 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter operator--(int) _NOEXCEPT {
0151 __bounded_iter __tmp(*this);
0152 --*this;
0153 return __tmp;
0154 }
0155
0156 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT {
0157 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0158 __n >= __begin_ - __current_, "__bounded_iter::operator+=: Attempt to rewind an iterator past the start");
0159 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0160 __n <= __end_ - __current_, "__bounded_iter::operator+=: Attempt to advance an iterator past the end");
0161 __current_ += __n;
0162 return *this;
0163 }
0164 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
0165 operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
0166 __bounded_iter __tmp(__self);
0167 __tmp += __n;
0168 return __tmp;
0169 }
0170 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
0171 operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT {
0172 __bounded_iter __tmp(__self);
0173 __tmp += __n;
0174 return __tmp;
0175 }
0176
0177 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT {
0178 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0179 __n <= __current_ - __begin_, "__bounded_iter::operator-=: Attempt to rewind an iterator past the start");
0180 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0181 __n >= __current_ - __end_, "__bounded_iter::operator-=: Attempt to advance an iterator past the end");
0182 __current_ -= __n;
0183 return *this;
0184 }
0185 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend __bounded_iter
0186 operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT {
0187 __bounded_iter __tmp(__self);
0188 __tmp -= __n;
0189 return __tmp;
0190 }
0191 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 friend difference_type
0192 operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0193 return __x.__current_ - __y.__current_;
0194 }
0195
0196
0197
0198
0199
0200
0201
0202 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0203 operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0204 return __x.__current_ == __y.__current_;
0205 }
0206
0207 #if _LIBCPP_STD_VER <= 17
0208 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0209 operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0210 return __x.__current_ != __y.__current_;
0211 }
0212 #endif
0213
0214
0215 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0216 operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0217 return __x.__current_ < __y.__current_;
0218 }
0219 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0220 operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0221 return __x.__current_ > __y.__current_;
0222 }
0223 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0224 operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0225 return __x.__current_ <= __y.__current_;
0226 }
0227 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
0228 operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
0229 return __x.__current_ >= __y.__current_;
0230 }
0231
0232 #if _LIBCPP_STD_VER >= 20
0233 _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
0234 operator<=>(__bounded_iter const& __x, __bounded_iter const& __y) noexcept {
0235 if constexpr (three_way_comparable<_Iterator, strong_ordering>) {
0236 return __x.__current_ <=> __y.__current_;
0237 } else {
0238 if (__x.__current_ < __y.__current_)
0239 return strong_ordering::less;
0240
0241 if (__x.__current_ == __y.__current_)
0242 return strong_ordering::equal;
0243
0244 return strong_ordering::greater;
0245 }
0246 }
0247 #endif
0248
0249 private:
0250 template <class>
0251 friend struct pointer_traits;
0252 template <class, class>
0253 friend struct __bounded_iter;
0254 _Iterator __current_;
0255 _Iterator __begin_, __end_;
0256 };
0257
0258 template <class _It>
0259 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) {
0260 return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end));
0261 }
0262
0263 #if _LIBCPP_STD_VER <= 17
0264 template <class _Iterator>
0265 struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {};
0266 #endif
0267
0268 template <class _Iterator>
0269 struct pointer_traits<__bounded_iter<_Iterator> > {
0270 using pointer = __bounded_iter<_Iterator>;
0271 using element_type = typename pointer_traits<_Iterator>::element_type;
0272 using difference_type = typename pointer_traits<_Iterator>::difference_type;
0273
0274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT {
0275 return std::__to_address(__it.__current_);
0276 }
0277 };
0278
0279 _LIBCPP_END_NAMESPACE_STD
0280
0281 _LIBCPP_POP_MACROS
0282
0283 #endif