File indexing completed on 2026-05-03 08:13:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___RANGES_IOTA_VIEW_H
0011 #define _LIBCPP___CXX03___RANGES_IOTA_VIEW_H
0012
0013 #include <__cxx03/__assert>
0014 #include <__cxx03/__compare/three_way_comparable.h>
0015 #include <__cxx03/__concepts/arithmetic.h>
0016 #include <__cxx03/__concepts/constructible.h>
0017 #include <__cxx03/__concepts/convertible_to.h>
0018 #include <__cxx03/__concepts/copyable.h>
0019 #include <__cxx03/__concepts/equality_comparable.h>
0020 #include <__cxx03/__concepts/invocable.h>
0021 #include <__cxx03/__concepts/same_as.h>
0022 #include <__cxx03/__concepts/semiregular.h>
0023 #include <__cxx03/__concepts/totally_ordered.h>
0024 #include <__cxx03/__config>
0025 #include <__cxx03/__iterator/concepts.h>
0026 #include <__cxx03/__iterator/incrementable_traits.h>
0027 #include <__cxx03/__iterator/iterator_traits.h>
0028 #include <__cxx03/__iterator/unreachable_sentinel.h>
0029 #include <__cxx03/__ranges/enable_borrowed_range.h>
0030 #include <__cxx03/__ranges/movable_box.h>
0031 #include <__cxx03/__ranges/view_interface.h>
0032 #include <__cxx03/__type_traits/conditional.h>
0033 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
0034 #include <__cxx03/__type_traits/make_unsigned.h>
0035 #include <__cxx03/__type_traits/type_identity.h>
0036 #include <__cxx03/__utility/forward.h>
0037 #include <__cxx03/__utility/move.h>
0038
0039 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0040 # pragma GCC system_header
0041 #endif
0042
0043 _LIBCPP_PUSH_MACROS
0044 #include <__cxx03/__undef_macros>
0045
0046 _LIBCPP_BEGIN_NAMESPACE_STD
0047
0048 #if _LIBCPP_STD_VER >= 20
0049
0050 namespace ranges {
0051 template <class _Int>
0052 struct __get_wider_signed {
0053 consteval static auto __call() {
0054 if constexpr (sizeof(_Int) < sizeof(short))
0055 return type_identity<short>{};
0056 else if constexpr (sizeof(_Int) < sizeof(int))
0057 return type_identity<int>{};
0058 else if constexpr (sizeof(_Int) < sizeof(long))
0059 return type_identity<long>{};
0060 else
0061 return type_identity<long long>{};
0062
0063 static_assert(
0064 sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type.");
0065 }
0066
0067 using type = typename decltype(__call())::type;
0068 };
0069
0070 template <class _Start>
0071 using _IotaDiffT =
0072 typename _If< (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)),
0073 type_identity<iter_difference_t<_Start>>,
0074 __get_wider_signed<_Start> >::type;
0075
0076 template <class _Iter>
0077 concept __decrementable = incrementable<_Iter> && requires(_Iter __i) {
0078 { --__i } -> same_as<_Iter&>;
0079 { __i-- } -> same_as<_Iter>;
0080 };
0081
0082 template <class _Iter>
0083 concept __advanceable =
0084 __decrementable<_Iter> && totally_ordered<_Iter> &&
0085 requires(_Iter __i, const _Iter __j, const _IotaDiffT<_Iter> __n) {
0086 { __i += __n } -> same_as<_Iter&>;
0087 { __i -= __n } -> same_as<_Iter&>;
0088 _Iter(__j + __n);
0089 _Iter(__n + __j);
0090 _Iter(__j - __n);
0091 { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
0092 };
0093
0094 template <class>
0095 struct __iota_iterator_category {};
0096
0097 template <incrementable _Tp>
0098 struct __iota_iterator_category<_Tp> {
0099 using iterator_category = input_iterator_tag;
0100 };
0101
0102 template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
0103 requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
0104 class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
0105 struct __iterator : public __iota_iterator_category<_Start> {
0106 friend class iota_view;
0107
0108 using iterator_concept =
0109 _If<__advanceable<_Start>,
0110 random_access_iterator_tag,
0111 _If<__decrementable<_Start>,
0112 bidirectional_iterator_tag,
0113 _If<incrementable<_Start>,
0114 forward_iterator_tag,
0115 input_iterator_tag>>>;
0116
0117 using value_type = _Start;
0118 using difference_type = _IotaDiffT<_Start>;
0119
0120 _Start __value_ = _Start();
0121
0122 _LIBCPP_HIDE_FROM_ABI __iterator()
0123 requires default_initializable<_Start>
0124 = default;
0125
0126 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
0127
0128 _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
0129 return __value_;
0130 }
0131
0132 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
0133 ++__value_;
0134 return *this;
0135 }
0136
0137 _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
0138
0139 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
0140 requires incrementable<_Start>
0141 {
0142 auto __tmp = *this;
0143 ++*this;
0144 return __tmp;
0145 }
0146
0147 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
0148 requires __decrementable<_Start>
0149 {
0150 --__value_;
0151 return *this;
0152 }
0153
0154 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
0155 requires __decrementable<_Start>
0156 {
0157 auto __tmp = *this;
0158 --*this;
0159 return __tmp;
0160 }
0161
0162 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
0163 requires __advanceable<_Start>
0164 {
0165 if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
0166 if (__n >= difference_type(0)) {
0167 __value_ += static_cast<_Start>(__n);
0168 } else {
0169 __value_ -= static_cast<_Start>(-__n);
0170 }
0171 } else {
0172 __value_ += __n;
0173 }
0174 return *this;
0175 }
0176
0177 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
0178 requires __advanceable<_Start>
0179 {
0180 if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
0181 if (__n >= difference_type(0)) {
0182 __value_ -= static_cast<_Start>(__n);
0183 } else {
0184 __value_ += static_cast<_Start>(-__n);
0185 }
0186 } else {
0187 __value_ -= __n;
0188 }
0189 return *this;
0190 }
0191
0192 _LIBCPP_HIDE_FROM_ABI constexpr _Start operator[](difference_type __n) const
0193 requires __advanceable<_Start>
0194 {
0195 return _Start(__value_ + __n);
0196 }
0197
0198 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
0199 requires equality_comparable<_Start>
0200 {
0201 return __x.__value_ == __y.__value_;
0202 }
0203
0204 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
0205 requires totally_ordered<_Start>
0206 {
0207 return __x.__value_ < __y.__value_;
0208 }
0209
0210 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
0211 requires totally_ordered<_Start>
0212 {
0213 return __y < __x;
0214 }
0215
0216 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
0217 requires totally_ordered<_Start>
0218 {
0219 return !(__y < __x);
0220 }
0221
0222 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
0223 requires totally_ordered<_Start>
0224 {
0225 return !(__x < __y);
0226 }
0227
0228 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
0229 requires totally_ordered<_Start> && three_way_comparable<_Start>
0230 {
0231 return __x.__value_ <=> __y.__value_;
0232 }
0233
0234 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
0235 requires __advanceable<_Start>
0236 {
0237 __i += __n;
0238 return __i;
0239 }
0240
0241 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
0242 requires __advanceable<_Start>
0243 {
0244 return __i + __n;
0245 }
0246
0247 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
0248 requires __advanceable<_Start>
0249 {
0250 __i -= __n;
0251 return __i;
0252 }
0253
0254 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
0255 requires __advanceable<_Start>
0256 {
0257 if constexpr (__integer_like<_Start>) {
0258 if constexpr (__signed_integer_like<_Start>) {
0259 return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
0260 }
0261 if (__y.__value_ > __x.__value_) {
0262 return difference_type(-difference_type(__y.__value_ - __x.__value_));
0263 }
0264 return difference_type(__x.__value_ - __y.__value_);
0265 }
0266 return __x.__value_ - __y.__value_;
0267 }
0268 };
0269
0270 struct __sentinel {
0271 friend class iota_view;
0272
0273 private:
0274 _BoundSentinel __bound_sentinel_ = _BoundSentinel();
0275
0276 public:
0277 _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
0278 _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
0279 : __bound_sentinel_(std::move(__bound_sentinel)) {}
0280
0281 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
0282 return __x.__value_ == __y.__bound_sentinel_;
0283 }
0284
0285 _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
0286 operator-(const __iterator& __x, const __sentinel& __y)
0287 requires sized_sentinel_for<_BoundSentinel, _Start>
0288 {
0289 return __x.__value_ - __y.__bound_sentinel_;
0290 }
0291
0292 _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
0293 operator-(const __sentinel& __x, const __iterator& __y)
0294 requires sized_sentinel_for<_BoundSentinel, _Start>
0295 {
0296 return -(__y - __x);
0297 }
0298 };
0299
0300 _Start __value_ = _Start();
0301 _BoundSentinel __bound_sentinel_ = _BoundSentinel();
0302
0303 public:
0304 _LIBCPP_HIDE_FROM_ABI iota_view()
0305 requires default_initializable<_Start>
0306 = default;
0307
0308 _LIBCPP_HIDE_FROM_ABI constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) {}
0309
0310 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
0311 iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
0312 : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
0313
0314 if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
0315 _LIBCPP_ASSERT_VALID_INPUT_RANGE(
0316 bool(__value_ <= __bound_sentinel_), "iota_view: bound must be reachable from value");
0317 }
0318 }
0319
0320 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
0321 requires same_as<_Start, _BoundSentinel>
0322 : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
0323
0324 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
0325 requires same_as<_BoundSentinel, unreachable_sentinel_t>
0326 : iota_view(std::move(__first.__value_), std::move(__last)) {}
0327
0328 _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
0329 requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
0330 : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
0331
0332 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator{__value_}; }
0333
0334 _LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
0335 if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
0336 return unreachable_sentinel;
0337 else
0338 return __sentinel{__bound_sentinel_};
0339 }
0340
0341 _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
0342 requires same_as<_Start, _BoundSentinel>
0343 {
0344 return __iterator{__bound_sentinel_};
0345 }
0346
0347 _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __value_ == __bound_sentinel_; }
0348
0349 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
0350 requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
0351 (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
0352 {
0353 if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
0354 return (__value_ < 0)
0355 ? ((__bound_sentinel_ < 0)
0356 ? std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_)
0357 : std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_))
0358 : std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
0359 } else {
0360 return std::__to_unsigned_like(__bound_sentinel_ - __value_);
0361 }
0362 }
0363 };
0364
0365 template <class _Start, class _BoundSentinel>
0366 requires(!__integer_like<_Start> || !__integer_like<_BoundSentinel> ||
0367 (__signed_integer_like<_Start> == __signed_integer_like<_BoundSentinel>))
0368 iota_view(_Start, _BoundSentinel) -> iota_view<_Start, _BoundSentinel>;
0369
0370 template <class _Start, class _BoundSentinel>
0371 inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
0372
0373 namespace views {
0374 namespace __iota {
0375 struct __fn {
0376 template <class _Start>
0377 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start) const
0378 noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start))))
0379 -> decltype(ranges::iota_view(std::forward<_Start>(__start))) {
0380 return ranges::iota_view(std::forward<_Start>(__start));
0381 }
0382
0383 template <class _Start, class _BoundSentinel>
0384 _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const noexcept(
0385 noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
0386 -> decltype(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))) {
0387 return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel));
0388 }
0389 };
0390 }
0391
0392 inline namespace __cpo {
0393 inline constexpr auto iota = __iota::__fn{};
0394 }
0395 }
0396 }
0397
0398 #endif
0399
0400 _LIBCPP_END_NAMESPACE_STD
0401
0402 _LIBCPP_POP_MACROS
0403
0404 #endif