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