1*4bdff4beSrobert // -*- C++ -*- 2*4bdff4beSrobert //===----------------------------------------------------------------------===// 3*4bdff4beSrobert // 4*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information. 6*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4bdff4beSrobert // 8*4bdff4beSrobert //===----------------------------------------------------------------------===// 9*4bdff4beSrobert 10*4bdff4beSrobert #ifndef _LIBCPP___RANGES_ELEMENTS_VIEW_H 11*4bdff4beSrobert #define _LIBCPP___RANGES_ELEMENTS_VIEW_H 12*4bdff4beSrobert 13*4bdff4beSrobert #include <__compare/three_way_comparable.h> 14*4bdff4beSrobert #include <__concepts/constructible.h> 15*4bdff4beSrobert #include <__concepts/convertible_to.h> 16*4bdff4beSrobert #include <__concepts/derived_from.h> 17*4bdff4beSrobert #include <__concepts/equality_comparable.h> 18*4bdff4beSrobert #include <__config> 19*4bdff4beSrobert #include <__fwd/get.h> 20*4bdff4beSrobert #include <__iterator/concepts.h> 21*4bdff4beSrobert #include <__iterator/iterator_traits.h> 22*4bdff4beSrobert #include <__ranges/access.h> 23*4bdff4beSrobert #include <__ranges/all.h> 24*4bdff4beSrobert #include <__ranges/concepts.h> 25*4bdff4beSrobert #include <__ranges/enable_borrowed_range.h> 26*4bdff4beSrobert #include <__ranges/range_adaptor.h> 27*4bdff4beSrobert #include <__ranges/size.h> 28*4bdff4beSrobert #include <__ranges/view_interface.h> 29*4bdff4beSrobert #include <__tuple_dir/tuple_element.h> 30*4bdff4beSrobert #include <__tuple_dir/tuple_like.h> 31*4bdff4beSrobert #include <__tuple_dir/tuple_size.h> 32*4bdff4beSrobert #include <__type_traits/is_reference.h> 33*4bdff4beSrobert #include <__type_traits/maybe_const.h> 34*4bdff4beSrobert #include <__type_traits/remove_cv.h> 35*4bdff4beSrobert #include <__type_traits/remove_cvref.h> 36*4bdff4beSrobert #include <__type_traits/remove_reference.h> 37*4bdff4beSrobert #include <__utility/declval.h> 38*4bdff4beSrobert #include <__utility/forward.h> 39*4bdff4beSrobert #include <__utility/move.h> 40*4bdff4beSrobert #include <cstddef> 41*4bdff4beSrobert 42*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 43*4bdff4beSrobert # pragma GCC system_header 44*4bdff4beSrobert #endif 45*4bdff4beSrobert 46*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD 47*4bdff4beSrobert 48*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20 49*4bdff4beSrobert 50*4bdff4beSrobert namespace ranges { 51*4bdff4beSrobert 52*4bdff4beSrobert template <class _Tp, size_t _Np> 53*4bdff4beSrobert concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value; 54*4bdff4beSrobert 55*4bdff4beSrobert template <class _Tp, size_t _Np> 56*4bdff4beSrobert concept __returnable_element = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Np, _Tp>>; 57*4bdff4beSrobert 58*4bdff4beSrobert template <input_range _View, size_t _Np> 59*4bdff4beSrobert requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 60*4bdff4beSrobert __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 61*4bdff4beSrobert __returnable_element<range_reference_t<_View>, _Np> 62*4bdff4beSrobert class elements_view : public view_interface<elements_view<_View, _Np>> { 63*4bdff4beSrobert private: 64*4bdff4beSrobert template <bool> 65*4bdff4beSrobert class __iterator; 66*4bdff4beSrobert 67*4bdff4beSrobert template <bool> 68*4bdff4beSrobert class __sentinel; 69*4bdff4beSrobert 70*4bdff4beSrobert public: 71*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI elements_view() 72*4bdff4beSrobert requires default_initializable<_View> 73*4bdff4beSrobert = default; 74*4bdff4beSrobert elements_view(_View __base)75*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr explicit elements_view(_View __base) : __base_(std::move(__base)) {} 76*4bdff4beSrobert base()77*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& 78*4bdff4beSrobert requires copy_constructible<_View> 79*4bdff4beSrobert { 80*4bdff4beSrobert return __base_; 81*4bdff4beSrobert } 82*4bdff4beSrobert base()83*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } 84*4bdff4beSrobert begin()85*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto begin() 86*4bdff4beSrobert requires(!__simple_view<_View>) 87*4bdff4beSrobert { 88*4bdff4beSrobert return __iterator</*_Const=*/false>(ranges::begin(__base_)); 89*4bdff4beSrobert } 90*4bdff4beSrobert begin()91*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const 92*4bdff4beSrobert requires range<const _View> 93*4bdff4beSrobert { 94*4bdff4beSrobert return __iterator</*_Const=*/true>(ranges::begin(__base_)); 95*4bdff4beSrobert } 96*4bdff4beSrobert end()97*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto end() 98*4bdff4beSrobert requires(!__simple_view<_View> && !common_range<_View>) 99*4bdff4beSrobert { 100*4bdff4beSrobert return __sentinel</*_Const=*/false>{ranges::end(__base_)}; 101*4bdff4beSrobert } 102*4bdff4beSrobert end()103*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto end() 104*4bdff4beSrobert requires(!__simple_view<_View> && common_range<_View>) 105*4bdff4beSrobert { 106*4bdff4beSrobert return __iterator</*_Const=*/false>{ranges::end(__base_)}; 107*4bdff4beSrobert } 108*4bdff4beSrobert end()109*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 110*4bdff4beSrobert requires range<const _View> 111*4bdff4beSrobert { 112*4bdff4beSrobert return __sentinel</*_Const=*/true>{ranges::end(__base_)}; 113*4bdff4beSrobert } 114*4bdff4beSrobert end()115*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 116*4bdff4beSrobert requires common_range<const _View> 117*4bdff4beSrobert { 118*4bdff4beSrobert return __iterator</*_Const=*/true>{ranges::end(__base_)}; 119*4bdff4beSrobert } 120*4bdff4beSrobert size()121*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto size() 122*4bdff4beSrobert requires sized_range<_View> 123*4bdff4beSrobert { 124*4bdff4beSrobert return ranges::size(__base_); 125*4bdff4beSrobert } 126*4bdff4beSrobert size()127*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr auto size() const 128*4bdff4beSrobert requires sized_range<const _View> 129*4bdff4beSrobert { 130*4bdff4beSrobert return ranges::size(__base_); 131*4bdff4beSrobert } 132*4bdff4beSrobert 133*4bdff4beSrobert private: 134*4bdff4beSrobert _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 135*4bdff4beSrobert }; 136*4bdff4beSrobert 137*4bdff4beSrobert template <class, size_t> 138*4bdff4beSrobert struct __elements_view_iterator_category_base {}; 139*4bdff4beSrobert 140*4bdff4beSrobert template <forward_range _Base, size_t _Np> 141*4bdff4beSrobert struct __elements_view_iterator_category_base<_Base, _Np> { 142*4bdff4beSrobert static consteval auto __get_iterator_category() { 143*4bdff4beSrobert using _Result = decltype(std::get<_Np>(*std::declval<iterator_t<_Base>>())); 144*4bdff4beSrobert using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 145*4bdff4beSrobert 146*4bdff4beSrobert if constexpr (!is_lvalue_reference_v<_Result>) { 147*4bdff4beSrobert return input_iterator_tag{}; 148*4bdff4beSrobert } else if constexpr (derived_from<_Cat, random_access_iterator_tag>) { 149*4bdff4beSrobert return random_access_iterator_tag{}; 150*4bdff4beSrobert } else { 151*4bdff4beSrobert return _Cat{}; 152*4bdff4beSrobert } 153*4bdff4beSrobert } 154*4bdff4beSrobert 155*4bdff4beSrobert using iterator_category = decltype(__get_iterator_category()); 156*4bdff4beSrobert }; 157*4bdff4beSrobert 158*4bdff4beSrobert template <input_range _View, size_t _Np> 159*4bdff4beSrobert requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 160*4bdff4beSrobert __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 161*4bdff4beSrobert __returnable_element<range_reference_t<_View>, _Np> 162*4bdff4beSrobert template <bool _Const> 163*4bdff4beSrobert class elements_view<_View, _Np>::__iterator 164*4bdff4beSrobert : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { 165*4bdff4beSrobert template <bool> 166*4bdff4beSrobert friend class __iterator; 167*4bdff4beSrobert 168*4bdff4beSrobert template <bool> 169*4bdff4beSrobert friend class __sentinel; 170*4bdff4beSrobert 171*4bdff4beSrobert using _Base = __maybe_const<_Const, _View>; 172*4bdff4beSrobert 173*4bdff4beSrobert iterator_t<_Base> __current_ = iterator_t<_Base>(); 174*4bdff4beSrobert 175*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) { 176*4bdff4beSrobert if constexpr (is_reference_v<range_reference_t<_Base>>) { 177*4bdff4beSrobert return std::get<_Np>(*__i); 178*4bdff4beSrobert } else { 179*4bdff4beSrobert using _Element = remove_cv_t<tuple_element_t<_Np, range_reference_t<_Base>>>; 180*4bdff4beSrobert return static_cast<_Element>(std::get<_Np>(*__i)); 181*4bdff4beSrobert } 182*4bdff4beSrobert } 183*4bdff4beSrobert 184*4bdff4beSrobert static consteval auto __get_iterator_concept() { 185*4bdff4beSrobert if constexpr (random_access_range<_Base>) { 186*4bdff4beSrobert return random_access_iterator_tag{}; 187*4bdff4beSrobert } else if constexpr (bidirectional_range<_Base>) { 188*4bdff4beSrobert return bidirectional_iterator_tag{}; 189*4bdff4beSrobert } else if constexpr (forward_range<_Base>) { 190*4bdff4beSrobert return forward_iterator_tag{}; 191*4bdff4beSrobert } else { 192*4bdff4beSrobert return input_iterator_tag{}; 193*4bdff4beSrobert } 194*4bdff4beSrobert } 195*4bdff4beSrobert 196*4bdff4beSrobert public: 197*4bdff4beSrobert using iterator_concept = decltype(__get_iterator_concept()); 198*4bdff4beSrobert using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>; 199*4bdff4beSrobert using difference_type = range_difference_t<_Base>; 200*4bdff4beSrobert 201*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI __iterator() 202*4bdff4beSrobert requires default_initializable<iterator_t<_Base>> 203*4bdff4beSrobert = default; 204*4bdff4beSrobert 205*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {} 206*4bdff4beSrobert 207*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i) 208*4bdff4beSrobert requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> 209*4bdff4beSrobert : __current_(std::move(__i.__current_)) {} 210*4bdff4beSrobert 211*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } 212*4bdff4beSrobert 213*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } 214*4bdff4beSrobert 215*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); } 216*4bdff4beSrobert 217*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { 218*4bdff4beSrobert ++__current_; 219*4bdff4beSrobert return *this; 220*4bdff4beSrobert } 221*4bdff4beSrobert 222*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } 223*4bdff4beSrobert 224*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) 225*4bdff4beSrobert requires forward_range<_Base> 226*4bdff4beSrobert { 227*4bdff4beSrobert auto temp = *this; 228*4bdff4beSrobert ++__current_; 229*4bdff4beSrobert return temp; 230*4bdff4beSrobert } 231*4bdff4beSrobert 232*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() 233*4bdff4beSrobert requires bidirectional_range<_Base> 234*4bdff4beSrobert { 235*4bdff4beSrobert --__current_; 236*4bdff4beSrobert return *this; 237*4bdff4beSrobert } 238*4bdff4beSrobert 239*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) 240*4bdff4beSrobert requires bidirectional_range<_Base> 241*4bdff4beSrobert { 242*4bdff4beSrobert auto temp = *this; 243*4bdff4beSrobert --__current_; 244*4bdff4beSrobert return temp; 245*4bdff4beSrobert } 246*4bdff4beSrobert 247*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) 248*4bdff4beSrobert requires random_access_range<_Base> 249*4bdff4beSrobert { 250*4bdff4beSrobert __current_ += __n; 251*4bdff4beSrobert return *this; 252*4bdff4beSrobert } 253*4bdff4beSrobert 254*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) 255*4bdff4beSrobert requires random_access_range<_Base> 256*4bdff4beSrobert { 257*4bdff4beSrobert __current_ -= __n; 258*4bdff4beSrobert return *this; 259*4bdff4beSrobert } 260*4bdff4beSrobert 261*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const 262*4bdff4beSrobert requires random_access_range<_Base> 263*4bdff4beSrobert { 264*4bdff4beSrobert return __get_element(__current_ + __n); 265*4bdff4beSrobert } 266*4bdff4beSrobert 267*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) 268*4bdff4beSrobert requires equality_comparable<iterator_t<_Base>> 269*4bdff4beSrobert { 270*4bdff4beSrobert return __x.__current_ == __y.__current_; 271*4bdff4beSrobert } 272*4bdff4beSrobert 273*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) 274*4bdff4beSrobert requires random_access_range<_Base> 275*4bdff4beSrobert { 276*4bdff4beSrobert return __x.__current_ < __y.__current_; 277*4bdff4beSrobert } 278*4bdff4beSrobert 279*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) 280*4bdff4beSrobert requires random_access_range<_Base> 281*4bdff4beSrobert { 282*4bdff4beSrobert return __y < __x; 283*4bdff4beSrobert } 284*4bdff4beSrobert 285*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) 286*4bdff4beSrobert requires random_access_range<_Base> 287*4bdff4beSrobert { 288*4bdff4beSrobert return !(__y < __x); 289*4bdff4beSrobert } 290*4bdff4beSrobert 291*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) 292*4bdff4beSrobert requires random_access_range<_Base> 293*4bdff4beSrobert { 294*4bdff4beSrobert return !(__x < __y); 295*4bdff4beSrobert } 296*4bdff4beSrobert 297*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) 298*4bdff4beSrobert requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>> 299*4bdff4beSrobert { 300*4bdff4beSrobert return __x.__current_ <=> __y.__current_; 301*4bdff4beSrobert } 302*4bdff4beSrobert 303*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y) 304*4bdff4beSrobert requires random_access_range<_Base> 305*4bdff4beSrobert { 306*4bdff4beSrobert return __iterator{__x} += __y; 307*4bdff4beSrobert } 308*4bdff4beSrobert 309*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y) 310*4bdff4beSrobert requires random_access_range<_Base> 311*4bdff4beSrobert { 312*4bdff4beSrobert return __y + __x; 313*4bdff4beSrobert } 314*4bdff4beSrobert 315*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y) 316*4bdff4beSrobert requires random_access_range<_Base> 317*4bdff4beSrobert { 318*4bdff4beSrobert return __iterator{__x} -= __y; 319*4bdff4beSrobert } 320*4bdff4beSrobert 321*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) 322*4bdff4beSrobert requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 323*4bdff4beSrobert { 324*4bdff4beSrobert return __x.__current_ - __y.__current_; 325*4bdff4beSrobert } 326*4bdff4beSrobert }; 327*4bdff4beSrobert 328*4bdff4beSrobert template <input_range _View, size_t _Np> 329*4bdff4beSrobert requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 330*4bdff4beSrobert __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 331*4bdff4beSrobert __returnable_element<range_reference_t<_View>, _Np> 332*4bdff4beSrobert template <bool _Const> 333*4bdff4beSrobert class elements_view<_View, _Np>::__sentinel { 334*4bdff4beSrobert private: 335*4bdff4beSrobert using _Base = __maybe_const<_Const, _View>; 336*4bdff4beSrobert _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 337*4bdff4beSrobert 338*4bdff4beSrobert template <bool> 339*4bdff4beSrobert friend class __sentinel; 340*4bdff4beSrobert 341*4bdff4beSrobert template <bool _AnyConst> 342*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) { 343*4bdff4beSrobert return (__iter.__current_); 344*4bdff4beSrobert } 345*4bdff4beSrobert 346*4bdff4beSrobert public: 347*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI __sentinel() = default; 348*4bdff4beSrobert 349*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} 350*4bdff4beSrobert 351*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other) 352*4bdff4beSrobert requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 353*4bdff4beSrobert : __end_(std::move(__other.__end_)) {} 354*4bdff4beSrobert 355*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } 356*4bdff4beSrobert 357*4bdff4beSrobert template <bool _OtherConst> 358*4bdff4beSrobert requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 359*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { 360*4bdff4beSrobert return __get_current(__x) == __y.__end_; 361*4bdff4beSrobert } 362*4bdff4beSrobert 363*4bdff4beSrobert template <bool _OtherConst> 364*4bdff4beSrobert requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 365*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 366*4bdff4beSrobert operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { 367*4bdff4beSrobert return __get_current(__x) - __y.__end_; 368*4bdff4beSrobert } 369*4bdff4beSrobert 370*4bdff4beSrobert template <bool _OtherConst> 371*4bdff4beSrobert requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 372*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 373*4bdff4beSrobert operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { 374*4bdff4beSrobert return __x.__end_ - __get_current(__y); 375*4bdff4beSrobert } 376*4bdff4beSrobert }; 377*4bdff4beSrobert 378*4bdff4beSrobert template <class _Tp, size_t _Np> 379*4bdff4beSrobert inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Np>> = enable_borrowed_range<_Tp>; 380*4bdff4beSrobert 381*4bdff4beSrobert template <class _Tp> 382*4bdff4beSrobert using keys_view = elements_view<_Tp, 0>; 383*4bdff4beSrobert template <class _Tp> 384*4bdff4beSrobert using values_view = elements_view<_Tp, 1>; 385*4bdff4beSrobert 386*4bdff4beSrobert namespace views { 387*4bdff4beSrobert namespace __elements { 388*4bdff4beSrobert 389*4bdff4beSrobert template <size_t _Np> 390*4bdff4beSrobert struct __fn : __range_adaptor_closure<__fn<_Np>> { 391*4bdff4beSrobert template <class _Range> 392*4bdff4beSrobert [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const 393*4bdff4beSrobert /**/ noexcept(noexcept(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range)))) 394*4bdff4beSrobert /*------*/ -> decltype(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))) { 395*4bdff4beSrobert /*-------------*/ return elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range)); 396*4bdff4beSrobert } 397*4bdff4beSrobert }; 398*4bdff4beSrobert } // namespace __elements 399*4bdff4beSrobert 400*4bdff4beSrobert inline namespace __cpo { 401*4bdff4beSrobert template <size_t _Np> 402*4bdff4beSrobert inline constexpr auto elements = __elements::__fn<_Np>{}; 403*4bdff4beSrobert inline constexpr auto keys = elements<0>; 404*4bdff4beSrobert inline constexpr auto values = elements<1>; 405*4bdff4beSrobert } // namespace __cpo 406*4bdff4beSrobert } // namespace views 407*4bdff4beSrobert } // namespace ranges 408*4bdff4beSrobert 409*4bdff4beSrobert #endif // _LIBCPP_STD_VER >= 20 410*4bdff4beSrobert 411*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD 412*4bdff4beSrobert 413*4bdff4beSrobert #endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H 414