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 //===----------------------------------------------------------------------===// 9349cc55cSDimitry Andric #ifndef _LIBCPP___RANGES_TAKE_VIEW_H 10349cc55cSDimitry Andric #define _LIBCPP___RANGES_TAKE_VIEW_H 11349cc55cSDimitry Andric 12349cc55cSDimitry Andric #include <__algorithm/min.h> 13*81ad6265SDimitry Andric #include <__algorithm/ranges_min.h> 14349cc55cSDimitry Andric #include <__config> 15*81ad6265SDimitry Andric #include <__functional/bind_back.h> 16*81ad6265SDimitry Andric #include <__fwd/span.h> 17*81ad6265SDimitry Andric #include <__fwd/string_view.h> 18349cc55cSDimitry Andric #include <__iterator/concepts.h> 19349cc55cSDimitry Andric #include <__iterator/counted_iterator.h> 20349cc55cSDimitry Andric #include <__iterator/default_sentinel.h> 21*81ad6265SDimitry Andric #include <__iterator/distance.h> 22349cc55cSDimitry Andric #include <__iterator/iterator_traits.h> 23349cc55cSDimitry Andric #include <__ranges/access.h> 24349cc55cSDimitry Andric #include <__ranges/all.h> 25349cc55cSDimitry Andric #include <__ranges/concepts.h> 26*81ad6265SDimitry Andric #include <__ranges/empty_view.h> 27349cc55cSDimitry Andric #include <__ranges/enable_borrowed_range.h> 28*81ad6265SDimitry Andric #include <__ranges/iota_view.h> 29*81ad6265SDimitry Andric #include <__ranges/range_adaptor.h> 30349cc55cSDimitry Andric #include <__ranges/size.h> 31*81ad6265SDimitry Andric #include <__ranges/subrange.h> 32349cc55cSDimitry Andric #include <__ranges/view_interface.h> 33*81ad6265SDimitry Andric #include <__utility/auto_cast.h> 34*81ad6265SDimitry Andric #include <__utility/forward.h> 35349cc55cSDimitry Andric #include <__utility/move.h> 36349cc55cSDimitry Andric #include <concepts> 37349cc55cSDimitry Andric #include <type_traits> 38349cc55cSDimitry Andric 39349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 40349cc55cSDimitry Andric # pragma GCC system_header 41349cc55cSDimitry Andric #endif 42349cc55cSDimitry Andric 43349cc55cSDimitry Andric _LIBCPP_PUSH_MACROS 44349cc55cSDimitry Andric #include <__undef_macros> 45349cc55cSDimitry Andric 46349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 47349cc55cSDimitry Andric 48*81ad6265SDimitry Andric #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 49349cc55cSDimitry Andric 50349cc55cSDimitry Andric namespace ranges { 51*81ad6265SDimitry Andric 52349cc55cSDimitry Andric template<view _View> 53349cc55cSDimitry Andric class take_view : public view_interface<take_view<_View>> { 54*81ad6265SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 55349cc55cSDimitry Andric range_difference_t<_View> __count_ = 0; 56349cc55cSDimitry Andric 57349cc55cSDimitry Andric template<bool> class __sentinel; 58349cc55cSDimitry Andric 59349cc55cSDimitry Andric public: 60349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 61349cc55cSDimitry Andric take_view() requires default_initializable<_View> = default; 62349cc55cSDimitry Andric 63349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 64349cc55cSDimitry Andric constexpr take_view(_View __base, range_difference_t<_View> __count) 65*81ad6265SDimitry Andric : __base_(std::move(__base)), __count_(__count) {} 66349cc55cSDimitry Andric 67349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 68349cc55cSDimitry Andric constexpr _View base() const& requires copy_constructible<_View> { return __base_; } 69349cc55cSDimitry Andric 70349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 71*81ad6265SDimitry Andric constexpr _View base() && { return std::move(__base_); } 72349cc55cSDimitry Andric 73349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 74349cc55cSDimitry Andric constexpr auto begin() requires (!__simple_view<_View>) { 75349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 76349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 77349cc55cSDimitry Andric return ranges::begin(__base_); 78349cc55cSDimitry Andric } else { 79349cc55cSDimitry Andric using _DifferenceT = range_difference_t<_View>; 80349cc55cSDimitry Andric auto __size = size(); 81349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 82349cc55cSDimitry Andric } 83349cc55cSDimitry Andric } else { 84349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 85349cc55cSDimitry Andric } 86349cc55cSDimitry Andric } 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 89349cc55cSDimitry Andric constexpr auto begin() const requires range<const _View> { 90349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 91349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 92349cc55cSDimitry Andric return ranges::begin(__base_); 93349cc55cSDimitry Andric } else { 94349cc55cSDimitry Andric using _DifferenceT = range_difference_t<const _View>; 95349cc55cSDimitry Andric auto __size = size(); 96349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size)); 97349cc55cSDimitry Andric } 98349cc55cSDimitry Andric } else { 99349cc55cSDimitry Andric return counted_iterator(ranges::begin(__base_), __count_); 100349cc55cSDimitry Andric } 101349cc55cSDimitry Andric } 102349cc55cSDimitry Andric 103349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 104349cc55cSDimitry Andric constexpr auto end() requires (!__simple_view<_View>) { 105349cc55cSDimitry Andric if constexpr (sized_range<_View>) { 106349cc55cSDimitry Andric if constexpr (random_access_range<_View>) { 107349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 108349cc55cSDimitry Andric } else { 109349cc55cSDimitry Andric return default_sentinel; 110349cc55cSDimitry Andric } 111349cc55cSDimitry Andric } else { 112349cc55cSDimitry Andric return __sentinel<false>{ranges::end(__base_)}; 113349cc55cSDimitry Andric } 114349cc55cSDimitry Andric } 115349cc55cSDimitry Andric 116349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 117349cc55cSDimitry Andric constexpr auto end() const requires range<const _View> { 118349cc55cSDimitry Andric if constexpr (sized_range<const _View>) { 119349cc55cSDimitry Andric if constexpr (random_access_range<const _View>) { 120349cc55cSDimitry Andric return ranges::begin(__base_) + size(); 121349cc55cSDimitry Andric } else { 122349cc55cSDimitry Andric return default_sentinel; 123349cc55cSDimitry Andric } 124349cc55cSDimitry Andric } else { 125349cc55cSDimitry Andric return __sentinel<true>{ranges::end(__base_)}; 126349cc55cSDimitry Andric } 127349cc55cSDimitry Andric } 128349cc55cSDimitry Andric 129349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 130349cc55cSDimitry Andric constexpr auto size() requires sized_range<_View> { 131349cc55cSDimitry Andric auto __n = ranges::size(__base_); 132*81ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 133349cc55cSDimitry Andric } 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 136349cc55cSDimitry Andric constexpr auto size() const requires sized_range<const _View> { 137349cc55cSDimitry Andric auto __n = ranges::size(__base_); 138*81ad6265SDimitry Andric return ranges::min(__n, static_cast<decltype(__n)>(__count_)); 139349cc55cSDimitry Andric } 140349cc55cSDimitry Andric }; 141349cc55cSDimitry Andric 142349cc55cSDimitry Andric template<view _View> 143349cc55cSDimitry Andric template<bool _Const> 144349cc55cSDimitry Andric class take_view<_View>::__sentinel { 145349cc55cSDimitry Andric using _Base = __maybe_const<_Const, _View>; 146349cc55cSDimitry Andric template<bool _OtherConst> 147349cc55cSDimitry Andric using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>; 148*81ad6265SDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 149349cc55cSDimitry Andric 150349cc55cSDimitry Andric template<bool> 151349cc55cSDimitry Andric friend class take_view<_View>::__sentinel; 152349cc55cSDimitry Andric 153349cc55cSDimitry Andric public: 154349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 155349cc55cSDimitry Andric __sentinel() = default; 156349cc55cSDimitry Andric 157349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 158*81ad6265SDimitry Andric constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} 159349cc55cSDimitry Andric 160349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 161349cc55cSDimitry Andric constexpr __sentinel(__sentinel<!_Const> __s) 162349cc55cSDimitry Andric requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 163*81ad6265SDimitry Andric : __end_(std::move(__s.__end_)) {} 164349cc55cSDimitry Andric 165349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 166349cc55cSDimitry Andric constexpr sentinel_t<_Base> base() const { return __end_; } 167349cc55cSDimitry Andric 168349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 169349cc55cSDimitry Andric friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { 170349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 171349cc55cSDimitry Andric } 172349cc55cSDimitry Andric 173349cc55cSDimitry Andric template<bool _OtherConst = !_Const> 174349cc55cSDimitry Andric requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 175349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI 176349cc55cSDimitry Andric friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) { 177349cc55cSDimitry Andric return __lhs.count() == 0 || __lhs.base() == __rhs.__end_; 178349cc55cSDimitry Andric } 179349cc55cSDimitry Andric }; 180349cc55cSDimitry Andric 181349cc55cSDimitry Andric template<class _Range> 182349cc55cSDimitry Andric take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>; 183349cc55cSDimitry Andric 184349cc55cSDimitry Andric template<class _Tp> 185349cc55cSDimitry Andric inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>; 186*81ad6265SDimitry Andric 187*81ad6265SDimitry Andric namespace views { 188*81ad6265SDimitry Andric namespace __take { 189*81ad6265SDimitry Andric 190*81ad6265SDimitry Andric template <class _Tp> 191*81ad6265SDimitry Andric inline constexpr bool __is_empty_view = false; 192*81ad6265SDimitry Andric 193*81ad6265SDimitry Andric template <class _Tp> 194*81ad6265SDimitry Andric inline constexpr bool __is_empty_view<empty_view<_Tp>> = true; 195*81ad6265SDimitry Andric 196*81ad6265SDimitry Andric template <class _Tp> 197*81ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization = false; 198*81ad6265SDimitry Andric 199*81ad6265SDimitry Andric template <class _Tp, size_t _Extent> 200*81ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<span<_Tp, _Extent>> = true; 201*81ad6265SDimitry Andric 202*81ad6265SDimitry Andric template <class _CharT, class _Traits> 203*81ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<basic_string_view<_CharT, _Traits>> = true; 204*81ad6265SDimitry Andric 205*81ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 206*81ad6265SDimitry Andric inline constexpr bool __is_passthrough_specialization<subrange<_Iter, _Sent, _Kind>> = true; 207*81ad6265SDimitry Andric 208*81ad6265SDimitry Andric template <class _Tp> 209*81ad6265SDimitry Andric inline constexpr bool __is_iota_specialization = false; 210*81ad6265SDimitry Andric 211*81ad6265SDimitry Andric template <class _Np, class _Bound> 212*81ad6265SDimitry Andric inline constexpr bool __is_iota_specialization<iota_view<_Np, _Bound>> = true; 213*81ad6265SDimitry Andric 214*81ad6265SDimitry Andric template <class _Tp> 215*81ad6265SDimitry Andric struct __passthrough_type; 216*81ad6265SDimitry Andric 217*81ad6265SDimitry Andric template <class _Tp, size_t _Extent> 218*81ad6265SDimitry Andric struct __passthrough_type<span<_Tp, _Extent>> { 219*81ad6265SDimitry Andric using type = span<_Tp>; 220*81ad6265SDimitry Andric }; 221*81ad6265SDimitry Andric 222*81ad6265SDimitry Andric template <class _CharT, class _Traits> 223*81ad6265SDimitry Andric struct __passthrough_type<basic_string_view<_CharT, _Traits>> { 224*81ad6265SDimitry Andric using type = basic_string_view<_CharT, _Traits>; 225*81ad6265SDimitry Andric }; 226*81ad6265SDimitry Andric 227*81ad6265SDimitry Andric template <class _Iter, class _Sent, subrange_kind _Kind> 228*81ad6265SDimitry Andric struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> { 229*81ad6265SDimitry Andric using type = subrange<_Iter>; 230*81ad6265SDimitry Andric }; 231*81ad6265SDimitry Andric 232*81ad6265SDimitry Andric template <class _Tp> 233*81ad6265SDimitry Andric using __passthrough_type_t = typename __passthrough_type<_Tp>::type; 234*81ad6265SDimitry Andric 235*81ad6265SDimitry Andric struct __fn { 236*81ad6265SDimitry Andric // [range.take.overview]: the `empty_view` case. 237*81ad6265SDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np> 238*81ad6265SDimitry Andric requires __is_empty_view<remove_cvref_t<_Range>> 239*81ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 240*81ad6265SDimitry Andric constexpr auto operator()(_Range&& __range, _Np&&) const 241*81ad6265SDimitry Andric noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) 242*81ad6265SDimitry Andric -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) 243*81ad6265SDimitry Andric { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); } 244*81ad6265SDimitry Andric 245*81ad6265SDimitry Andric // [range.take.overview]: the `span | basic_string_view | subrange` case. 246*81ad6265SDimitry Andric template <class _Range, 247*81ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 248*81ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 249*81ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 250*81ad6265SDimitry Andric requires (!__is_empty_view<_RawRange> && 251*81ad6265SDimitry Andric random_access_range<_RawRange> && 252*81ad6265SDimitry Andric sized_range<_RawRange> && 253*81ad6265SDimitry Andric __is_passthrough_specialization<_RawRange>) 254*81ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 255*81ad6265SDimitry Andric constexpr auto operator()(_Range&& __rng, _Np&& __n) const 256*81ad6265SDimitry Andric noexcept(noexcept(__passthrough_type_t<_RawRange>( 257*81ad6265SDimitry Andric ranges::begin(__rng), 258*81ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 259*81ad6265SDimitry Andric ))) 260*81ad6265SDimitry Andric -> decltype( __passthrough_type_t<_RawRange>( 261*81ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 262*81ad6265SDimitry Andric ranges::begin(__rng), 263*81ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 264*81ad6265SDimitry Andric )) 265*81ad6265SDimitry Andric { return __passthrough_type_t<_RawRange>( 266*81ad6265SDimitry Andric ranges::begin(__rng), 267*81ad6265SDimitry Andric ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 268*81ad6265SDimitry Andric ); } 269*81ad6265SDimitry Andric 270*81ad6265SDimitry Andric // [range.take.overview]: the `iota_view` case. 271*81ad6265SDimitry Andric template <class _Range, 272*81ad6265SDimitry Andric convertible_to<range_difference_t<_Range>> _Np, 273*81ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>, 274*81ad6265SDimitry Andric class _Dist = range_difference_t<_Range>> 275*81ad6265SDimitry Andric requires (!__is_empty_view<_RawRange> && 276*81ad6265SDimitry Andric random_access_range<_RawRange> && 277*81ad6265SDimitry Andric sized_range<_RawRange> && 278*81ad6265SDimitry Andric __is_iota_specialization<_RawRange>) 279*81ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 280*81ad6265SDimitry Andric constexpr auto operator()(_Range&& __rng, _Np&& __n) const 281*81ad6265SDimitry Andric noexcept(noexcept(ranges::iota_view( 282*81ad6265SDimitry Andric *ranges::begin(__rng), 283*81ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 284*81ad6265SDimitry Andric ))) 285*81ad6265SDimitry Andric -> decltype( ranges::iota_view( 286*81ad6265SDimitry Andric // Note: deliberately not forwarding `__rng` to guard against double moves. 287*81ad6265SDimitry Andric *ranges::begin(__rng), 288*81ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 289*81ad6265SDimitry Andric )) 290*81ad6265SDimitry Andric { return ranges::iota_view( 291*81ad6265SDimitry Andric *ranges::begin(__rng), 292*81ad6265SDimitry Andric *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) 293*81ad6265SDimitry Andric ); } 294*81ad6265SDimitry Andric 295*81ad6265SDimitry Andric // [range.take.overview]: the "otherwise" case. 296*81ad6265SDimitry Andric template <class _Range, convertible_to<range_difference_t<_Range>> _Np, 297*81ad6265SDimitry Andric class _RawRange = remove_cvref_t<_Range>> 298*81ad6265SDimitry Andric // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other 299*81ad6265SDimitry Andric // overloads. 300*81ad6265SDimitry Andric requires (!(__is_empty_view<_RawRange> || 301*81ad6265SDimitry Andric (__is_iota_specialization<_RawRange> && 302*81ad6265SDimitry Andric sized_range<_RawRange> && 303*81ad6265SDimitry Andric random_access_range<_RawRange>) || 304*81ad6265SDimitry Andric (__is_passthrough_specialization<_RawRange> && 305*81ad6265SDimitry Andric sized_range<_RawRange> && 306*81ad6265SDimitry Andric random_access_range<_RawRange>) 307*81ad6265SDimitry Andric )) 308*81ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 309*81ad6265SDimitry Andric constexpr auto operator()(_Range&& __range, _Np&& __n) const 310*81ad6265SDimitry Andric noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))) 311*81ad6265SDimitry Andric -> decltype( take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) 312*81ad6265SDimitry Andric { return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); } 313*81ad6265SDimitry Andric 314*81ad6265SDimitry Andric template <class _Np> 315*81ad6265SDimitry Andric requires constructible_from<decay_t<_Np>, _Np> 316*81ad6265SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI 317*81ad6265SDimitry Andric constexpr auto operator()(_Np&& __n) const 318*81ad6265SDimitry Andric noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) 319*81ad6265SDimitry Andric { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); } 320*81ad6265SDimitry Andric }; 321*81ad6265SDimitry Andric 322*81ad6265SDimitry Andric } // namespace __take 323*81ad6265SDimitry Andric 324*81ad6265SDimitry Andric inline namespace __cpo { 325*81ad6265SDimitry Andric inline constexpr auto take = __take::__fn{}; 326*81ad6265SDimitry Andric } // namespace __cpo 327*81ad6265SDimitry Andric } // namespace views 328*81ad6265SDimitry Andric 329349cc55cSDimitry Andric } // namespace ranges 330349cc55cSDimitry Andric 331*81ad6265SDimitry Andric #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 332349cc55cSDimitry Andric 333349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD 334349cc55cSDimitry Andric 335349cc55cSDimitry Andric _LIBCPP_POP_MACROS 336349cc55cSDimitry Andric 337349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_TAKE_VIEW_H 338