1349cc55cSDimitry Andric // -*- C++ -*-
2349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
3349cc55cSDimitry Andric //
4349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7349cc55cSDimitry Andric //
8349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric
10349cc55cSDimitry Andric #ifndef _LIBCPP___RANGES_IOTA_VIEW_H
11349cc55cSDimitry Andric #define _LIBCPP___RANGES_IOTA_VIEW_H
12349cc55cSDimitry Andric
1381ad6265SDimitry Andric #include <__assert>
14349cc55cSDimitry Andric #include <__compare/three_way_comparable.h>
15349cc55cSDimitry Andric #include <__concepts/arithmetic.h>
16349cc55cSDimitry Andric #include <__concepts/constructible.h>
17349cc55cSDimitry Andric #include <__concepts/convertible_to.h>
18349cc55cSDimitry Andric #include <__concepts/copyable.h>
19349cc55cSDimitry Andric #include <__concepts/equality_comparable.h>
20349cc55cSDimitry Andric #include <__concepts/invocable.h>
21349cc55cSDimitry Andric #include <__concepts/same_as.h>
22349cc55cSDimitry Andric #include <__concepts/semiregular.h>
23349cc55cSDimitry Andric #include <__concepts/totally_ordered.h>
24349cc55cSDimitry Andric #include <__config>
25349cc55cSDimitry Andric #include <__iterator/concepts.h>
26349cc55cSDimitry Andric #include <__iterator/incrementable_traits.h>
27349cc55cSDimitry Andric #include <__iterator/iterator_traits.h>
28349cc55cSDimitry Andric #include <__iterator/unreachable_sentinel.h>
29349cc55cSDimitry Andric #include <__ranges/enable_borrowed_range.h>
3006c3fb27SDimitry Andric #include <__ranges/movable_box.h>
31349cc55cSDimitry Andric #include <__ranges/view_interface.h>
3206c3fb27SDimitry Andric #include <__type_traits/conditional.h>
33*0fca6ea1SDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
3406c3fb27SDimitry Andric #include <__type_traits/make_unsigned.h>
3506c3fb27SDimitry Andric #include <__type_traits/type_identity.h>
36349cc55cSDimitry Andric #include <__utility/forward.h>
37349cc55cSDimitry Andric #include <__utility/move.h>
38349cc55cSDimitry Andric
39349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
40349cc55cSDimitry Andric # pragma GCC system_header
41349cc55cSDimitry Andric #endif
42349cc55cSDimitry Andric
43b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
44b3edf446SDimitry Andric #include <__undef_macros>
45b3edf446SDimitry Andric
46349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
47349cc55cSDimitry Andric
4806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
49349cc55cSDimitry Andric
50349cc55cSDimitry Andric namespace ranges {
51349cc55cSDimitry Andric template <class _Int>
52349cc55cSDimitry Andric struct __get_wider_signed {
__call__get_wider_signed5306c3fb27SDimitry Andric consteval static auto __call() {
54cb14a3feSDimitry Andric if constexpr (sizeof(_Int) < sizeof(short))
55cb14a3feSDimitry Andric return type_identity<short>{};
56cb14a3feSDimitry Andric else if constexpr (sizeof(_Int) < sizeof(int))
57cb14a3feSDimitry Andric return type_identity<int>{};
58cb14a3feSDimitry Andric else if constexpr (sizeof(_Int) < sizeof(long))
59cb14a3feSDimitry Andric return type_identity<long>{};
60cb14a3feSDimitry Andric else
61cb14a3feSDimitry Andric return type_identity<long long>{};
62349cc55cSDimitry Andric
63cb14a3feSDimitry Andric static_assert(
64cb14a3feSDimitry Andric sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type.");
65349cc55cSDimitry Andric }
66349cc55cSDimitry Andric
67349cc55cSDimitry Andric using type = typename decltype(__call())::type;
68349cc55cSDimitry Andric };
69349cc55cSDimitry Andric
70349cc55cSDimitry Andric template <class _Start>
71cb14a3feSDimitry Andric using _IotaDiffT =
72cb14a3feSDimitry Andric typename _If< (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)),
73349cc55cSDimitry Andric type_identity<iter_difference_t<_Start>>,
74cb14a3feSDimitry Andric __get_wider_signed<_Start> >::type;
75349cc55cSDimitry Andric
76349cc55cSDimitry Andric template <class _Iter>
requires(_Iter __i)77349cc55cSDimitry Andric concept __decrementable = incrementable<_Iter> && requires(_Iter __i) {
78349cc55cSDimitry Andric { --__i } -> same_as<_Iter&>;
79349cc55cSDimitry Andric { __i-- } -> same_as<_Iter>;
80349cc55cSDimitry Andric };
81349cc55cSDimitry Andric
82349cc55cSDimitry Andric template <class _Iter>
83349cc55cSDimitry Andric concept __advanceable =
84349cc55cSDimitry Andric __decrementable<_Iter> && totally_ordered<_Iter> &&
requires(_Iter __i,const _Iter __j,const _IotaDiffT<_Iter> __n)85349cc55cSDimitry Andric requires(_Iter __i, const _Iter __j, const _IotaDiffT<_Iter> __n) {
86349cc55cSDimitry Andric { __i += __n } -> same_as<_Iter&>;
87349cc55cSDimitry Andric { __i -= __n } -> same_as<_Iter&>;
88349cc55cSDimitry Andric _Iter(__j + __n);
89349cc55cSDimitry Andric _Iter(__n + __j);
90349cc55cSDimitry Andric _Iter(__j - __n);
91349cc55cSDimitry Andric { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
92349cc55cSDimitry Andric };
93349cc55cSDimitry Andric
94349cc55cSDimitry Andric template <class>
95349cc55cSDimitry Andric struct __iota_iterator_category {};
96349cc55cSDimitry Andric
97349cc55cSDimitry Andric template <incrementable _Tp>
98349cc55cSDimitry Andric struct __iota_iterator_category<_Tp> {
99349cc55cSDimitry Andric using iterator_category = input_iterator_tag;
100349cc55cSDimitry Andric };
101349cc55cSDimitry Andric
10281ad6265SDimitry Andric template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
10381ad6265SDimitry Andric requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
10481ad6265SDimitry Andric class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
1051ac55f4cSDimitry Andric struct __iterator : public __iota_iterator_category<_Start> {
1061ac55f4cSDimitry Andric friend class iota_view;
107349cc55cSDimitry Andric
1081ac55f4cSDimitry Andric using iterator_concept =
109cb14a3feSDimitry Andric _If<__advanceable<_Start>,
110cb14a3feSDimitry Andric random_access_iterator_tag,
111cb14a3feSDimitry Andric _If<__decrementable<_Start>,
112cb14a3feSDimitry Andric bidirectional_iterator_tag,
113cb14a3feSDimitry Andric _If<incrementable<_Start>,
114cb14a3feSDimitry Andric forward_iterator_tag,
1151ac55f4cSDimitry Andric /*Else*/ input_iterator_tag>>>;
1161ac55f4cSDimitry Andric
1171ac55f4cSDimitry Andric using value_type = _Start;
1181ac55f4cSDimitry Andric using difference_type = _IotaDiffT<_Start>;
1191ac55f4cSDimitry Andric
1201ac55f4cSDimitry Andric _Start __value_ = _Start();
1211ac55f4cSDimitry Andric
122cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iterator()
123cb14a3feSDimitry Andric requires default_initializable<_Start>
124cb14a3feSDimitry Andric = default;
1251ac55f4cSDimitry Andric
126cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
1271ac55f4cSDimitry Andric
128cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
1291ac55f4cSDimitry Andric return __value_;
1301ac55f4cSDimitry Andric }
1311ac55f4cSDimitry Andric
132cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
1331ac55f4cSDimitry Andric ++__value_;
1341ac55f4cSDimitry Andric return *this;
1351ac55f4cSDimitry Andric }
1361ac55f4cSDimitry Andric
137cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
1381ac55f4cSDimitry Andric
139cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
140cb14a3feSDimitry Andric requires incrementable<_Start>
141cb14a3feSDimitry Andric {
1421ac55f4cSDimitry Andric auto __tmp = *this;
1431ac55f4cSDimitry Andric ++*this;
1441ac55f4cSDimitry Andric return __tmp;
1451ac55f4cSDimitry Andric }
1461ac55f4cSDimitry Andric
147cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
148cb14a3feSDimitry Andric requires __decrementable<_Start>
149cb14a3feSDimitry Andric {
1501ac55f4cSDimitry Andric --__value_;
1511ac55f4cSDimitry Andric return *this;
1521ac55f4cSDimitry Andric }
1531ac55f4cSDimitry Andric
154cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
155cb14a3feSDimitry Andric requires __decrementable<_Start>
156cb14a3feSDimitry Andric {
1571ac55f4cSDimitry Andric auto __tmp = *this;
1581ac55f4cSDimitry Andric --*this;
1591ac55f4cSDimitry Andric return __tmp;
1601ac55f4cSDimitry Andric }
1611ac55f4cSDimitry Andric
162cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
1631ac55f4cSDimitry Andric requires __advanceable<_Start>
1641ac55f4cSDimitry Andric {
1651ac55f4cSDimitry Andric if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
1661ac55f4cSDimitry Andric if (__n >= difference_type(0)) {
1671ac55f4cSDimitry Andric __value_ += static_cast<_Start>(__n);
1681ac55f4cSDimitry Andric } else {
1691ac55f4cSDimitry Andric __value_ -= static_cast<_Start>(-__n);
1701ac55f4cSDimitry Andric }
1711ac55f4cSDimitry Andric } else {
1721ac55f4cSDimitry Andric __value_ += __n;
1731ac55f4cSDimitry Andric }
1741ac55f4cSDimitry Andric return *this;
1751ac55f4cSDimitry Andric }
1761ac55f4cSDimitry Andric
177cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
1781ac55f4cSDimitry Andric requires __advanceable<_Start>
1791ac55f4cSDimitry Andric {
1801ac55f4cSDimitry Andric if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
1811ac55f4cSDimitry Andric if (__n >= difference_type(0)) {
1821ac55f4cSDimitry Andric __value_ -= static_cast<_Start>(__n);
1831ac55f4cSDimitry Andric } else {
1841ac55f4cSDimitry Andric __value_ += static_cast<_Start>(-__n);
1851ac55f4cSDimitry Andric }
1861ac55f4cSDimitry Andric } else {
1871ac55f4cSDimitry Andric __value_ -= __n;
1881ac55f4cSDimitry Andric }
1891ac55f4cSDimitry Andric return *this;
1901ac55f4cSDimitry Andric }
1911ac55f4cSDimitry Andric
192cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Start operator[](difference_type __n) const
1931ac55f4cSDimitry Andric requires __advanceable<_Start>
1941ac55f4cSDimitry Andric {
1951ac55f4cSDimitry Andric return _Start(__value_ + __n);
1961ac55f4cSDimitry Andric }
1971ac55f4cSDimitry Andric
198cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
1991ac55f4cSDimitry Andric requires equality_comparable<_Start>
2001ac55f4cSDimitry Andric {
2011ac55f4cSDimitry Andric return __x.__value_ == __y.__value_;
2021ac55f4cSDimitry Andric }
2031ac55f4cSDimitry Andric
204cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
2051ac55f4cSDimitry Andric requires totally_ordered<_Start>
2061ac55f4cSDimitry Andric {
2071ac55f4cSDimitry Andric return __x.__value_ < __y.__value_;
2081ac55f4cSDimitry Andric }
2091ac55f4cSDimitry Andric
210cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
2111ac55f4cSDimitry Andric requires totally_ordered<_Start>
2121ac55f4cSDimitry Andric {
2131ac55f4cSDimitry Andric return __y < __x;
2141ac55f4cSDimitry Andric }
2151ac55f4cSDimitry Andric
216cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
2171ac55f4cSDimitry Andric requires totally_ordered<_Start>
2181ac55f4cSDimitry Andric {
2191ac55f4cSDimitry Andric return !(__y < __x);
2201ac55f4cSDimitry Andric }
2211ac55f4cSDimitry Andric
222cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
2231ac55f4cSDimitry Andric requires totally_ordered<_Start>
2241ac55f4cSDimitry Andric {
2251ac55f4cSDimitry Andric return !(__x < __y);
2261ac55f4cSDimitry Andric }
2271ac55f4cSDimitry Andric
228cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
2291ac55f4cSDimitry Andric requires totally_ordered<_Start> && three_way_comparable<_Start>
2301ac55f4cSDimitry Andric {
2311ac55f4cSDimitry Andric return __x.__value_ <=> __y.__value_;
2321ac55f4cSDimitry Andric }
2331ac55f4cSDimitry Andric
234cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
2351ac55f4cSDimitry Andric requires __advanceable<_Start>
2361ac55f4cSDimitry Andric {
2371ac55f4cSDimitry Andric __i += __n;
2381ac55f4cSDimitry Andric return __i;
2391ac55f4cSDimitry Andric }
2401ac55f4cSDimitry Andric
241cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
2421ac55f4cSDimitry Andric requires __advanceable<_Start>
2431ac55f4cSDimitry Andric {
2441ac55f4cSDimitry Andric return __i + __n;
2451ac55f4cSDimitry Andric }
2461ac55f4cSDimitry Andric
247cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
2481ac55f4cSDimitry Andric requires __advanceable<_Start>
2491ac55f4cSDimitry Andric {
2501ac55f4cSDimitry Andric __i -= __n;
2511ac55f4cSDimitry Andric return __i;
2521ac55f4cSDimitry Andric }
2531ac55f4cSDimitry Andric
254cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
2551ac55f4cSDimitry Andric requires __advanceable<_Start>
2561ac55f4cSDimitry Andric {
2571ac55f4cSDimitry Andric if constexpr (__integer_like<_Start>) {
2581ac55f4cSDimitry Andric if constexpr (__signed_integer_like<_Start>) {
2591ac55f4cSDimitry Andric return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
2601ac55f4cSDimitry Andric }
2611ac55f4cSDimitry Andric if (__y.__value_ > __x.__value_) {
2621ac55f4cSDimitry Andric return difference_type(-difference_type(__y.__value_ - __x.__value_));
2631ac55f4cSDimitry Andric }
2641ac55f4cSDimitry Andric return difference_type(__x.__value_ - __y.__value_);
2651ac55f4cSDimitry Andric }
2661ac55f4cSDimitry Andric return __x.__value_ - __y.__value_;
2671ac55f4cSDimitry Andric }
2681ac55f4cSDimitry Andric };
2691ac55f4cSDimitry Andric
2701ac55f4cSDimitry Andric struct __sentinel {
2711ac55f4cSDimitry Andric friend class iota_view;
2721ac55f4cSDimitry Andric
2731ac55f4cSDimitry Andric private:
2741ac55f4cSDimitry Andric _BoundSentinel __bound_sentinel_ = _BoundSentinel();
2751ac55f4cSDimitry Andric
2761ac55f4cSDimitry Andric public:
277cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
27806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
27906c3fb27SDimitry Andric : __bound_sentinel_(std::move(__bound_sentinel)) {}
2801ac55f4cSDimitry Andric
281cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
2821ac55f4cSDimitry Andric return __x.__value_ == __y.__bound_sentinel_;
2831ac55f4cSDimitry Andric }
2841ac55f4cSDimitry Andric
285cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
286cb14a3feSDimitry Andric operator-(const __iterator& __x, const __sentinel& __y)
2871ac55f4cSDimitry Andric requires sized_sentinel_for<_BoundSentinel, _Start>
2881ac55f4cSDimitry Andric {
2891ac55f4cSDimitry Andric return __x.__value_ - __y.__bound_sentinel_;
2901ac55f4cSDimitry Andric }
2911ac55f4cSDimitry Andric
292cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
293cb14a3feSDimitry Andric operator-(const __sentinel& __x, const __iterator& __y)
2941ac55f4cSDimitry Andric requires sized_sentinel_for<_BoundSentinel, _Start>
2951ac55f4cSDimitry Andric {
2961ac55f4cSDimitry Andric return -(__y - __x);
2971ac55f4cSDimitry Andric }
2981ac55f4cSDimitry Andric };
299349cc55cSDimitry Andric
300349cc55cSDimitry Andric _Start __value_ = _Start();
30181ad6265SDimitry Andric _BoundSentinel __bound_sentinel_ = _BoundSentinel();
302349cc55cSDimitry Andric
303349cc55cSDimitry Andric public:
304cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI iota_view()
305cb14a3feSDimitry Andric requires default_initializable<_Start>
306cb14a3feSDimitry Andric = default;
307349cc55cSDimitry Andric
308cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) {}
309349cc55cSDimitry Andric
310cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
311cb14a3feSDimitry Andric iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
31281ad6265SDimitry Andric : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
313349cc55cSDimitry Andric // Validate the precondition if possible.
31481ad6265SDimitry Andric if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
315*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(
316*0fca6ea1SDimitry Andric bool(__value_ <= __bound_sentinel_), "iota_view: bound must be reachable from value");
317349cc55cSDimitry Andric }
318349cc55cSDimitry Andric }
319349cc55cSDimitry Andric
320cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
32181ad6265SDimitry Andric requires same_as<_Start, _BoundSentinel>
32281ad6265SDimitry Andric : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
323349cc55cSDimitry Andric
324cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
32581ad6265SDimitry Andric requires same_as<_BoundSentinel, unreachable_sentinel_t>
32681ad6265SDimitry Andric : iota_view(std::move(__first.__value_), std::move(__last)) {}
327349cc55cSDimitry Andric
328cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
32906c3fb27SDimitry Andric requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
33081ad6265SDimitry Andric : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
331349cc55cSDimitry Andric
332cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator{__value_}; }
333349cc55cSDimitry Andric
334cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
33581ad6265SDimitry Andric if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
336349cc55cSDimitry Andric return unreachable_sentinel;
337349cc55cSDimitry Andric else
33881ad6265SDimitry Andric return __sentinel{__bound_sentinel_};
339349cc55cSDimitry Andric }
340349cc55cSDimitry Andric
341cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
34281ad6265SDimitry Andric requires same_as<_Start, _BoundSentinel>
34381ad6265SDimitry Andric {
34481ad6265SDimitry Andric return __iterator{__bound_sentinel_};
345349cc55cSDimitry Andric }
346349cc55cSDimitry Andric
347*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __value_ == __bound_sentinel_; }
348*0fca6ea1SDimitry Andric
349cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
35081ad6265SDimitry Andric requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
35181ad6265SDimitry Andric (integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
352349cc55cSDimitry Andric {
35381ad6265SDimitry Andric if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
3545f757f3fSDimitry Andric return (__value_ < 0)
3555f757f3fSDimitry Andric ? ((__bound_sentinel_ < 0)
3565f757f3fSDimitry Andric ? std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_)
3575f757f3fSDimitry Andric : std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_))
3585f757f3fSDimitry Andric : std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
3595f757f3fSDimitry Andric } else {
36081ad6265SDimitry Andric return std::__to_unsigned_like(__bound_sentinel_ - __value_);
361349cc55cSDimitry Andric }
3625f757f3fSDimitry Andric }
363349cc55cSDimitry Andric };
364349cc55cSDimitry Andric
36581ad6265SDimitry Andric template <class _Start, class _BoundSentinel>
36681ad6265SDimitry Andric requires(!__integer_like<_Start> || !__integer_like<_BoundSentinel> ||
36781ad6265SDimitry Andric (__signed_integer_like<_Start> == __signed_integer_like<_BoundSentinel>))
36881ad6265SDimitry Andric iota_view(_Start, _BoundSentinel) -> iota_view<_Start, _BoundSentinel>;
369349cc55cSDimitry Andric
37081ad6265SDimitry Andric template <class _Start, class _BoundSentinel>
37181ad6265SDimitry Andric inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
372349cc55cSDimitry Andric
373349cc55cSDimitry Andric namespace views {
374349cc55cSDimitry Andric namespace __iota {
375349cc55cSDimitry Andric struct __fn {
376349cc55cSDimitry Andric template <class _Start>
377cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start) const
37881ad6265SDimitry Andric noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start))))
379cb14a3feSDimitry Andric -> decltype(ranges::iota_view(std::forward<_Start>(__start))) {
380cb14a3feSDimitry Andric return ranges::iota_view(std::forward<_Start>(__start));
381cb14a3feSDimitry Andric }
382349cc55cSDimitry Andric
38381ad6265SDimitry Andric template <class _Start, class _BoundSentinel>
384cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const noexcept(
385cb14a3feSDimitry Andric noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
386cb14a3feSDimitry Andric -> decltype(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))) {
387cb14a3feSDimitry Andric return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel));
388cb14a3feSDimitry Andric }
389349cc55cSDimitry Andric };
390349cc55cSDimitry Andric } // namespace __iota
391349cc55cSDimitry Andric
392349cc55cSDimitry Andric inline namespace __cpo {
393349cc55cSDimitry Andric inline constexpr auto iota = __iota::__fn{};
3941fd87a68SDimitry Andric } // namespace __cpo
395349cc55cSDimitry Andric } // namespace views
396349cc55cSDimitry Andric } // namespace ranges
397349cc55cSDimitry Andric
39806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
399349cc55cSDimitry Andric
400349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD
401349cc55cSDimitry Andric
402b3edf446SDimitry Andric _LIBCPP_POP_MACROS
403b3edf446SDimitry Andric
404349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_IOTA_VIEW_H
405