1*349cc55cSDimitry Andric // -*- C++ -*- 2*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 3*349cc55cSDimitry Andric // 4*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*349cc55cSDimitry Andric // 8*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 9*349cc55cSDimitry Andric #ifndef _LIBCPP___RANGES_IOTA_VIEW_H 10*349cc55cSDimitry Andric #define _LIBCPP___RANGES_IOTA_VIEW_H 11*349cc55cSDimitry Andric 12*349cc55cSDimitry Andric #include <__compare/three_way_comparable.h> 13*349cc55cSDimitry Andric #include <__concepts/arithmetic.h> 14*349cc55cSDimitry Andric #include <__concepts/constructible.h> 15*349cc55cSDimitry Andric #include <__concepts/convertible_to.h> 16*349cc55cSDimitry Andric #include <__concepts/copyable.h> 17*349cc55cSDimitry Andric #include <__concepts/equality_comparable.h> 18*349cc55cSDimitry Andric #include <__concepts/invocable.h> 19*349cc55cSDimitry Andric #include <__concepts/same_as.h> 20*349cc55cSDimitry Andric #include <__concepts/semiregular.h> 21*349cc55cSDimitry Andric #include <__concepts/totally_ordered.h> 22*349cc55cSDimitry Andric #include <__config> 23*349cc55cSDimitry Andric #include <__debug> 24*349cc55cSDimitry Andric #include <__functional/ranges_operations.h> 25*349cc55cSDimitry Andric #include <__iterator/concepts.h> 26*349cc55cSDimitry Andric #include <__iterator/incrementable_traits.h> 27*349cc55cSDimitry Andric #include <__iterator/iterator_traits.h> 28*349cc55cSDimitry Andric #include <__iterator/unreachable_sentinel.h> 29*349cc55cSDimitry Andric #include <__ranges/copyable_box.h> 30*349cc55cSDimitry Andric #include <__ranges/enable_borrowed_range.h> 31*349cc55cSDimitry Andric #include <__ranges/view_interface.h> 32*349cc55cSDimitry Andric #include <__utility/forward.h> 33*349cc55cSDimitry Andric #include <__utility/move.h> 34*349cc55cSDimitry Andric #include <type_traits> 35*349cc55cSDimitry Andric 36*349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 37*349cc55cSDimitry Andric #pragma GCC system_header 38*349cc55cSDimitry Andric #endif 39*349cc55cSDimitry Andric 40*349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 41*349cc55cSDimitry Andric 42*349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_RANGES) 43*349cc55cSDimitry Andric 44*349cc55cSDimitry Andric namespace ranges { 45*349cc55cSDimitry Andric template<class _Int> 46*349cc55cSDimitry Andric struct __get_wider_signed { 47*349cc55cSDimitry Andric static auto __call() { 48*349cc55cSDimitry Andric if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{}; 49*349cc55cSDimitry Andric else if constexpr (sizeof(_Int) < sizeof(int)) return type_identity<int>{}; 50*349cc55cSDimitry Andric else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{}; 51*349cc55cSDimitry Andric else return type_identity<long long>{}; 52*349cc55cSDimitry Andric 53*349cc55cSDimitry Andric static_assert(sizeof(_Int) <= sizeof(long long), 54*349cc55cSDimitry Andric "Found integer-like type that is bigger than largest integer like type."); 55*349cc55cSDimitry Andric } 56*349cc55cSDimitry Andric 57*349cc55cSDimitry Andric using type = typename decltype(__call())::type; 58*349cc55cSDimitry Andric }; 59*349cc55cSDimitry Andric 60*349cc55cSDimitry Andric template<class _Start> 61*349cc55cSDimitry Andric using _IotaDiffT = typename _If< 62*349cc55cSDimitry Andric (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)), 63*349cc55cSDimitry Andric type_identity<iter_difference_t<_Start>>, 64*349cc55cSDimitry Andric __get_wider_signed<_Start> 65*349cc55cSDimitry Andric >::type; 66*349cc55cSDimitry Andric 67*349cc55cSDimitry Andric template<class _Iter> 68*349cc55cSDimitry Andric concept __decrementable = incrementable<_Iter> && requires(_Iter __i) { 69*349cc55cSDimitry Andric { --__i } -> same_as<_Iter&>; 70*349cc55cSDimitry Andric { __i-- } -> same_as<_Iter>; 71*349cc55cSDimitry Andric }; 72*349cc55cSDimitry Andric 73*349cc55cSDimitry Andric template<class _Iter> 74*349cc55cSDimitry Andric concept __advanceable = 75*349cc55cSDimitry Andric __decrementable<_Iter> && totally_ordered<_Iter> && 76*349cc55cSDimitry Andric requires(_Iter __i, const _Iter __j, const _IotaDiffT<_Iter> __n) { 77*349cc55cSDimitry Andric { __i += __n } -> same_as<_Iter&>; 78*349cc55cSDimitry Andric { __i -= __n } -> same_as<_Iter&>; 79*349cc55cSDimitry Andric _Iter(__j + __n); 80*349cc55cSDimitry Andric _Iter(__n + __j); 81*349cc55cSDimitry Andric _Iter(__j - __n); 82*349cc55cSDimitry Andric { __j - __j } -> convertible_to<_IotaDiffT<_Iter>>; 83*349cc55cSDimitry Andric }; 84*349cc55cSDimitry Andric 85*349cc55cSDimitry Andric template<class> 86*349cc55cSDimitry Andric struct __iota_iterator_category {}; 87*349cc55cSDimitry Andric 88*349cc55cSDimitry Andric template<incrementable _Tp> 89*349cc55cSDimitry Andric struct __iota_iterator_category<_Tp> { 90*349cc55cSDimitry Andric using iterator_category = input_iterator_tag; 91*349cc55cSDimitry Andric }; 92*349cc55cSDimitry Andric 93*349cc55cSDimitry Andric template<weakly_incrementable _Start, semiregular _Bound = unreachable_sentinel_t> 94*349cc55cSDimitry Andric requires __weakly_equality_comparable_with<_Start, _Bound> && copyable<_Start> 95*349cc55cSDimitry Andric class iota_view : public view_interface<iota_view<_Start, _Bound>> { 96*349cc55cSDimitry Andric struct __iterator : public __iota_iterator_category<_Start> { 97*349cc55cSDimitry Andric friend class iota_view; 98*349cc55cSDimitry Andric 99*349cc55cSDimitry Andric using iterator_concept = 100*349cc55cSDimitry Andric _If<__advanceable<_Start>, random_access_iterator_tag, 101*349cc55cSDimitry Andric _If<__decrementable<_Start>, bidirectional_iterator_tag, 102*349cc55cSDimitry Andric _If<incrementable<_Start>, forward_iterator_tag, 103*349cc55cSDimitry Andric /*Else*/ input_iterator_tag>>>; 104*349cc55cSDimitry Andric 105*349cc55cSDimitry Andric using value_type = _Start; 106*349cc55cSDimitry Andric using difference_type = _IotaDiffT<_Start>; 107*349cc55cSDimitry Andric 108*349cc55cSDimitry Andric _Start __value_ = _Start(); 109*349cc55cSDimitry Andric 110*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 111*349cc55cSDimitry Andric __iterator() requires default_initializable<_Start> = default; 112*349cc55cSDimitry Andric 113*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 114*349cc55cSDimitry Andric constexpr explicit __iterator(_Start __value) : __value_(_VSTD::move(__value)) {} 115*349cc55cSDimitry Andric 116*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 117*349cc55cSDimitry Andric constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) { 118*349cc55cSDimitry Andric return __value_; 119*349cc55cSDimitry Andric } 120*349cc55cSDimitry Andric 121*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 122*349cc55cSDimitry Andric constexpr __iterator& operator++() { 123*349cc55cSDimitry Andric ++__value_; 124*349cc55cSDimitry Andric return *this; 125*349cc55cSDimitry Andric } 126*349cc55cSDimitry Andric 127*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 128*349cc55cSDimitry Andric constexpr void operator++(int) { ++*this; } 129*349cc55cSDimitry Andric 130*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 131*349cc55cSDimitry Andric constexpr __iterator operator++(int) requires incrementable<_Start> { 132*349cc55cSDimitry Andric auto __tmp = *this; 133*349cc55cSDimitry Andric ++*this; 134*349cc55cSDimitry Andric return __tmp; 135*349cc55cSDimitry Andric } 136*349cc55cSDimitry Andric 137*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 138*349cc55cSDimitry Andric constexpr __iterator& operator--() requires __decrementable<_Start> { 139*349cc55cSDimitry Andric --__value_; 140*349cc55cSDimitry Andric return *this; 141*349cc55cSDimitry Andric } 142*349cc55cSDimitry Andric 143*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 144*349cc55cSDimitry Andric constexpr __iterator operator--(int) requires __decrementable<_Start> { 145*349cc55cSDimitry Andric auto __tmp = *this; 146*349cc55cSDimitry Andric --*this; 147*349cc55cSDimitry Andric return __tmp; 148*349cc55cSDimitry Andric } 149*349cc55cSDimitry Andric 150*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 151*349cc55cSDimitry Andric constexpr __iterator& operator+=(difference_type __n) 152*349cc55cSDimitry Andric requires __advanceable<_Start> 153*349cc55cSDimitry Andric { 154*349cc55cSDimitry Andric if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { 155*349cc55cSDimitry Andric if (__n >= difference_type(0)) { 156*349cc55cSDimitry Andric __value_ += static_cast<_Start>(__n); 157*349cc55cSDimitry Andric } else { 158*349cc55cSDimitry Andric __value_ -= static_cast<_Start>(-__n); 159*349cc55cSDimitry Andric } 160*349cc55cSDimitry Andric } else { 161*349cc55cSDimitry Andric __value_ += __n; 162*349cc55cSDimitry Andric } 163*349cc55cSDimitry Andric return *this; 164*349cc55cSDimitry Andric } 165*349cc55cSDimitry Andric 166*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 167*349cc55cSDimitry Andric constexpr __iterator& operator-=(difference_type __n) 168*349cc55cSDimitry Andric requires __advanceable<_Start> 169*349cc55cSDimitry Andric { 170*349cc55cSDimitry Andric if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) { 171*349cc55cSDimitry Andric if (__n >= difference_type(0)) { 172*349cc55cSDimitry Andric __value_ -= static_cast<_Start>(__n); 173*349cc55cSDimitry Andric } else { 174*349cc55cSDimitry Andric __value_ += static_cast<_Start>(-__n); 175*349cc55cSDimitry Andric } 176*349cc55cSDimitry Andric } else { 177*349cc55cSDimitry Andric __value_ -= __n; 178*349cc55cSDimitry Andric } 179*349cc55cSDimitry Andric return *this; 180*349cc55cSDimitry Andric } 181*349cc55cSDimitry Andric 182*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 183*349cc55cSDimitry Andric constexpr _Start operator[](difference_type __n) const 184*349cc55cSDimitry Andric requires __advanceable<_Start> 185*349cc55cSDimitry Andric { 186*349cc55cSDimitry Andric return _Start(__value_ + __n); 187*349cc55cSDimitry Andric } 188*349cc55cSDimitry Andric 189*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 190*349cc55cSDimitry Andric friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) 191*349cc55cSDimitry Andric requires equality_comparable<_Start> 192*349cc55cSDimitry Andric { 193*349cc55cSDimitry Andric return __x.__value_ == __y.__value_; 194*349cc55cSDimitry Andric } 195*349cc55cSDimitry Andric 196*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 197*349cc55cSDimitry Andric friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) 198*349cc55cSDimitry Andric requires totally_ordered<_Start> 199*349cc55cSDimitry Andric { 200*349cc55cSDimitry Andric return __x.__value_ < __y.__value_; 201*349cc55cSDimitry Andric } 202*349cc55cSDimitry Andric 203*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 204*349cc55cSDimitry Andric friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) 205*349cc55cSDimitry Andric requires totally_ordered<_Start> 206*349cc55cSDimitry Andric { 207*349cc55cSDimitry Andric return __y < __x; 208*349cc55cSDimitry Andric } 209*349cc55cSDimitry Andric 210*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 211*349cc55cSDimitry Andric friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) 212*349cc55cSDimitry Andric requires totally_ordered<_Start> 213*349cc55cSDimitry Andric { 214*349cc55cSDimitry Andric return !(__y < __x); 215*349cc55cSDimitry Andric } 216*349cc55cSDimitry Andric 217*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 218*349cc55cSDimitry Andric friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) 219*349cc55cSDimitry Andric requires totally_ordered<_Start> 220*349cc55cSDimitry Andric { 221*349cc55cSDimitry Andric return !(__x < __y); 222*349cc55cSDimitry Andric } 223*349cc55cSDimitry Andric 224*349cc55cSDimitry Andric friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) 225*349cc55cSDimitry Andric requires totally_ordered<_Start> && three_way_comparable<_Start> 226*349cc55cSDimitry Andric { 227*349cc55cSDimitry Andric return __x.__value_ <=> __y.__value_; 228*349cc55cSDimitry Andric } 229*349cc55cSDimitry Andric 230*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 231*349cc55cSDimitry Andric friend constexpr __iterator operator+(__iterator __i, difference_type __n) 232*349cc55cSDimitry Andric requires __advanceable<_Start> 233*349cc55cSDimitry Andric { 234*349cc55cSDimitry Andric __i += __n; 235*349cc55cSDimitry Andric return __i; 236*349cc55cSDimitry Andric } 237*349cc55cSDimitry Andric 238*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 239*349cc55cSDimitry Andric friend constexpr __iterator operator+(difference_type __n, __iterator __i) 240*349cc55cSDimitry Andric requires __advanceable<_Start> 241*349cc55cSDimitry Andric { 242*349cc55cSDimitry Andric return __i + __n; 243*349cc55cSDimitry Andric } 244*349cc55cSDimitry Andric 245*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 246*349cc55cSDimitry Andric friend constexpr __iterator operator-(__iterator __i, difference_type __n) 247*349cc55cSDimitry Andric requires __advanceable<_Start> 248*349cc55cSDimitry Andric { 249*349cc55cSDimitry Andric __i -= __n; 250*349cc55cSDimitry Andric return __i; 251*349cc55cSDimitry Andric } 252*349cc55cSDimitry Andric 253*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 254*349cc55cSDimitry Andric friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) 255*349cc55cSDimitry Andric requires __advanceable<_Start> 256*349cc55cSDimitry Andric { 257*349cc55cSDimitry Andric if constexpr (__integer_like<_Start>) { 258*349cc55cSDimitry Andric if constexpr (__signed_integer_like<_Start>) { 259*349cc55cSDimitry Andric return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_)); 260*349cc55cSDimitry Andric } 261*349cc55cSDimitry Andric if (__y.__value_ > __x.__value_) { 262*349cc55cSDimitry Andric return difference_type(-difference_type(__y.__value_ - __x.__value_)); 263*349cc55cSDimitry Andric } 264*349cc55cSDimitry Andric return difference_type(__x.__value_ - __y.__value_); 265*349cc55cSDimitry Andric } 266*349cc55cSDimitry Andric return __x.__value_ - __y.__value_; 267*349cc55cSDimitry Andric } 268*349cc55cSDimitry Andric }; 269*349cc55cSDimitry Andric 270*349cc55cSDimitry Andric struct __sentinel { 271*349cc55cSDimitry Andric friend class iota_view; 272*349cc55cSDimitry Andric 273*349cc55cSDimitry Andric private: 274*349cc55cSDimitry Andric _Bound __bound_ = _Bound(); 275*349cc55cSDimitry Andric 276*349cc55cSDimitry Andric public: 277*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 278*349cc55cSDimitry Andric __sentinel() = default; 279*349cc55cSDimitry Andric constexpr explicit __sentinel(_Bound __bound) : __bound_(_VSTD::move(__bound)) {} 280*349cc55cSDimitry Andric 281*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 282*349cc55cSDimitry Andric friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { 283*349cc55cSDimitry Andric return __x.__value_ == __y.__bound_; 284*349cc55cSDimitry Andric } 285*349cc55cSDimitry Andric 286*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 287*349cc55cSDimitry Andric friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y) 288*349cc55cSDimitry Andric requires sized_sentinel_for<_Bound, _Start> 289*349cc55cSDimitry Andric { 290*349cc55cSDimitry Andric return __x.__value_ - __y.__bound_; 291*349cc55cSDimitry Andric } 292*349cc55cSDimitry Andric 293*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 294*349cc55cSDimitry Andric friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y) 295*349cc55cSDimitry Andric requires sized_sentinel_for<_Bound, _Start> 296*349cc55cSDimitry Andric { 297*349cc55cSDimitry Andric return -(__y - __x); 298*349cc55cSDimitry Andric } 299*349cc55cSDimitry Andric }; 300*349cc55cSDimitry Andric 301*349cc55cSDimitry Andric _Start __value_ = _Start(); 302*349cc55cSDimitry Andric _Bound __bound_ = _Bound(); 303*349cc55cSDimitry Andric 304*349cc55cSDimitry Andric public: 305*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 306*349cc55cSDimitry Andric iota_view() requires default_initializable<_Start> = default; 307*349cc55cSDimitry Andric 308*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 309*349cc55cSDimitry Andric constexpr explicit iota_view(_Start __value) : __value_(_VSTD::move(__value)) { } 310*349cc55cSDimitry Andric 311*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 312*349cc55cSDimitry Andric constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_Bound> __bound) 313*349cc55cSDimitry Andric : __value_(_VSTD::move(__value)), __bound_(_VSTD::move(__bound)) { 314*349cc55cSDimitry Andric // Validate the precondition if possible. 315*349cc55cSDimitry Andric if constexpr (totally_ordered_with<_Start, _Bound>) { 316*349cc55cSDimitry Andric _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_), 317*349cc55cSDimitry Andric "Precondition violated: value is greater than bound."); 318*349cc55cSDimitry Andric } 319*349cc55cSDimitry Andric } 320*349cc55cSDimitry Andric 321*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 322*349cc55cSDimitry Andric constexpr iota_view(__iterator __first, __iterator __last) 323*349cc55cSDimitry Andric requires same_as<_Start, _Bound> 324*349cc55cSDimitry Andric : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last.__value_)) {} 325*349cc55cSDimitry Andric 326*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 327*349cc55cSDimitry Andric constexpr iota_view(__iterator __first, _Bound __last) 328*349cc55cSDimitry Andric requires same_as<_Bound, unreachable_sentinel_t> 329*349cc55cSDimitry Andric : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last)) {} 330*349cc55cSDimitry Andric 331*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 332*349cc55cSDimitry Andric constexpr iota_view(__iterator __first, __sentinel __last) 333*349cc55cSDimitry Andric requires (!same_as<_Start, _Bound> && !same_as<_Start, unreachable_sentinel_t>) 334*349cc55cSDimitry Andric : iota_view(_VSTD::move(__first.__value_), _VSTD::move(__last.__bound_)) {} 335*349cc55cSDimitry Andric 336*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 337*349cc55cSDimitry Andric constexpr __iterator begin() const { return __iterator{__value_}; } 338*349cc55cSDimitry Andric 339*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 340*349cc55cSDimitry Andric constexpr auto end() const { 341*349cc55cSDimitry Andric if constexpr (same_as<_Bound, unreachable_sentinel_t>) 342*349cc55cSDimitry Andric return unreachable_sentinel; 343*349cc55cSDimitry Andric else 344*349cc55cSDimitry Andric return __sentinel{__bound_}; 345*349cc55cSDimitry Andric } 346*349cc55cSDimitry Andric 347*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 348*349cc55cSDimitry Andric constexpr __iterator end() const requires same_as<_Start, _Bound> { 349*349cc55cSDimitry Andric return __iterator{__bound_}; 350*349cc55cSDimitry Andric } 351*349cc55cSDimitry Andric 352*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 353*349cc55cSDimitry Andric constexpr auto size() const 354*349cc55cSDimitry Andric requires (same_as<_Start, _Bound> && __advanceable<_Start>) || 355*349cc55cSDimitry Andric (integral<_Start> && integral<_Bound>) || 356*349cc55cSDimitry Andric sized_sentinel_for<_Bound, _Start> 357*349cc55cSDimitry Andric { 358*349cc55cSDimitry Andric if constexpr (__integer_like<_Start> && __integer_like<_Bound>) { 359*349cc55cSDimitry Andric if (__value_ < 0) { 360*349cc55cSDimitry Andric if (__bound_ < 0) { 361*349cc55cSDimitry Andric return _VSTD::__to_unsigned_like(-__value_) - _VSTD::__to_unsigned_like(-__bound_); 362*349cc55cSDimitry Andric } 363*349cc55cSDimitry Andric return _VSTD::__to_unsigned_like(__bound_) + _VSTD::__to_unsigned_like(-__value_); 364*349cc55cSDimitry Andric } 365*349cc55cSDimitry Andric return _VSTD::__to_unsigned_like(__bound_) - _VSTD::__to_unsigned_like(__value_); 366*349cc55cSDimitry Andric } 367*349cc55cSDimitry Andric return _VSTD::__to_unsigned_like(__bound_ - __value_); 368*349cc55cSDimitry Andric } 369*349cc55cSDimitry Andric }; 370*349cc55cSDimitry Andric 371*349cc55cSDimitry Andric template<class _Start, class _Bound> 372*349cc55cSDimitry Andric requires (!__integer_like<_Start> || !__integer_like<_Bound> || 373*349cc55cSDimitry Andric (__signed_integer_like<_Start> == __signed_integer_like<_Bound>)) 374*349cc55cSDimitry Andric iota_view(_Start, _Bound) -> iota_view<_Start, _Bound>; 375*349cc55cSDimitry Andric 376*349cc55cSDimitry Andric template<class _Start, class _Bound> 377*349cc55cSDimitry Andric inline constexpr bool enable_borrowed_range<iota_view<_Start, _Bound>> = true; 378*349cc55cSDimitry Andric 379*349cc55cSDimitry Andric namespace views { 380*349cc55cSDimitry Andric namespace __iota { 381*349cc55cSDimitry Andric struct __fn { 382*349cc55cSDimitry Andric template<class _Start> 383*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 384*349cc55cSDimitry Andric constexpr auto operator()(_Start&& __start) const 385*349cc55cSDimitry Andric noexcept(noexcept(ranges::iota_view(_VSTD::forward<_Start>(__start)))) 386*349cc55cSDimitry Andric -> decltype( ranges::iota_view(_VSTD::forward<_Start>(__start))) 387*349cc55cSDimitry Andric { return ranges::iota_view(_VSTD::forward<_Start>(__start)); } 388*349cc55cSDimitry Andric 389*349cc55cSDimitry Andric template<class _Start, class _Bound> 390*349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 391*349cc55cSDimitry Andric constexpr auto operator()(_Start&& __start, _Bound&& __bound) const 392*349cc55cSDimitry Andric noexcept(noexcept(ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound)))) 393*349cc55cSDimitry Andric -> decltype( ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound))) 394*349cc55cSDimitry Andric { return ranges::iota_view(_VSTD::forward<_Start>(__start), _VSTD::forward<_Bound>(__bound)); } 395*349cc55cSDimitry Andric }; 396*349cc55cSDimitry Andric } // namespace __iota 397*349cc55cSDimitry Andric 398*349cc55cSDimitry Andric inline namespace __cpo { 399*349cc55cSDimitry Andric inline constexpr auto iota = __iota::__fn{}; 400*349cc55cSDimitry Andric } 401*349cc55cSDimitry Andric } // namespace views 402*349cc55cSDimitry Andric } // namespace ranges 403*349cc55cSDimitry Andric 404*349cc55cSDimitry Andric #endif // !defined(_LIBCPP_HAS_NO_RANGES) 405*349cc55cSDimitry Andric 406*349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD 407*349cc55cSDimitry Andric 408*349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_IOTA_VIEW_H 409