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> 19*0fca6ea1SDimitry Andric #include <__fwd/complex.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> 2906c3fb27SDimitry Andric #include <__tuple/tuple_element.h> 3006c3fb27SDimitry Andric #include <__tuple/tuple_like.h> 3106c3fb27SDimitry 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 46b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 47b3edf446SDimitry Andric #include <__undef_macros> 48b3edf446SDimitry Andric 49bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 50bdd1243dSDimitry Andric 51bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 20 52bdd1243dSDimitry Andric 53bdd1243dSDimitry Andric namespace ranges { 54bdd1243dSDimitry Andric 55bdd1243dSDimitry Andric template <class _Tp, size_t _Np> 56bdd1243dSDimitry Andric concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value; 57bdd1243dSDimitry Andric 58bdd1243dSDimitry Andric template <class _Tp, size_t _Np> 59bdd1243dSDimitry Andric concept __returnable_element = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Np, _Tp>>; 60bdd1243dSDimitry Andric 61bdd1243dSDimitry Andric template <input_range _View, size_t _Np> 62bdd1243dSDimitry Andric requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 63bdd1243dSDimitry Andric __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 64bdd1243dSDimitry Andric __returnable_element<range_reference_t<_View>, _Np> 65bdd1243dSDimitry Andric class elements_view : public view_interface<elements_view<_View, _Np>> { 661ac55f4cSDimitry Andric private: 671ac55f4cSDimitry Andric template <bool> 681ac55f4cSDimitry Andric class __iterator; 691ac55f4cSDimitry Andric 701ac55f4cSDimitry Andric template <bool> 711ac55f4cSDimitry Andric class __sentinel; 721ac55f4cSDimitry Andric 73bdd1243dSDimitry Andric public: 74bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI elements_view() 75bdd1243dSDimitry Andric requires default_initializable<_View> 76bdd1243dSDimitry Andric = default; 77bdd1243dSDimitry Andric elements_view(_View __base)78bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit elements_view(_View __base) : __base_(std::move(__base)) {} 79bdd1243dSDimitry Andric base()80bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& 81bdd1243dSDimitry Andric requires copy_constructible<_View> 82bdd1243dSDimitry Andric { 83bdd1243dSDimitry Andric return __base_; 84bdd1243dSDimitry Andric } 85bdd1243dSDimitry Andric base()86bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } 87bdd1243dSDimitry Andric begin()88bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() 89bdd1243dSDimitry Andric requires(!__simple_view<_View>) 90bdd1243dSDimitry Andric { 91bdd1243dSDimitry Andric return __iterator</*_Const=*/false>(ranges::begin(__base_)); 92bdd1243dSDimitry Andric } 93bdd1243dSDimitry Andric begin()94bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const 95bdd1243dSDimitry Andric requires range<const _View> 96bdd1243dSDimitry Andric { 97bdd1243dSDimitry Andric return __iterator</*_Const=*/true>(ranges::begin(__base_)); 98bdd1243dSDimitry Andric } 99bdd1243dSDimitry Andric end()100bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() 101bdd1243dSDimitry Andric requires(!__simple_view<_View> && !common_range<_View>) 102bdd1243dSDimitry Andric { 103bdd1243dSDimitry Andric return __sentinel</*_Const=*/false>{ranges::end(__base_)}; 104bdd1243dSDimitry Andric } 105bdd1243dSDimitry Andric end()106bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() 107bdd1243dSDimitry Andric requires(!__simple_view<_View> && common_range<_View>) 108bdd1243dSDimitry Andric { 109bdd1243dSDimitry Andric return __iterator</*_Const=*/false>{ranges::end(__base_)}; 110bdd1243dSDimitry Andric } 111bdd1243dSDimitry Andric end()112bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 113bdd1243dSDimitry Andric requires range<const _View> 114bdd1243dSDimitry Andric { 115bdd1243dSDimitry Andric return __sentinel</*_Const=*/true>{ranges::end(__base_)}; 116bdd1243dSDimitry Andric } 117bdd1243dSDimitry Andric end()118bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto end() const 119bdd1243dSDimitry Andric requires common_range<const _View> 120bdd1243dSDimitry Andric { 121bdd1243dSDimitry Andric return __iterator</*_Const=*/true>{ranges::end(__base_)}; 122bdd1243dSDimitry Andric } 123bdd1243dSDimitry Andric size()124bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() 125bdd1243dSDimitry Andric requires sized_range<_View> 126bdd1243dSDimitry Andric { 127bdd1243dSDimitry Andric return ranges::size(__base_); 128bdd1243dSDimitry Andric } 129bdd1243dSDimitry Andric size()130bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() const 131bdd1243dSDimitry Andric requires sized_range<const _View> 132bdd1243dSDimitry Andric { 133bdd1243dSDimitry Andric return ranges::size(__base_); 134bdd1243dSDimitry Andric } 135bdd1243dSDimitry Andric 136bdd1243dSDimitry Andric private: 137bdd1243dSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); 138bdd1243dSDimitry Andric }; 139bdd1243dSDimitry Andric 140bdd1243dSDimitry Andric template <class, size_t> 141bdd1243dSDimitry Andric struct __elements_view_iterator_category_base {}; 142bdd1243dSDimitry Andric 143bdd1243dSDimitry Andric template <forward_range _Base, size_t _Np> 144bdd1243dSDimitry Andric struct __elements_view_iterator_category_base<_Base, _Np> { 145bdd1243dSDimitry Andric static consteval auto __get_iterator_category() { 146bdd1243dSDimitry Andric using _Result = decltype(std::get<_Np>(*std::declval<iterator_t<_Base>>())); 147bdd1243dSDimitry Andric using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 148bdd1243dSDimitry Andric 149bdd1243dSDimitry Andric if constexpr (!is_lvalue_reference_v<_Result>) { 150bdd1243dSDimitry Andric return input_iterator_tag{}; 151bdd1243dSDimitry Andric } else if constexpr (derived_from<_Cat, random_access_iterator_tag>) { 152bdd1243dSDimitry Andric return random_access_iterator_tag{}; 153bdd1243dSDimitry Andric } else { 154bdd1243dSDimitry Andric return _Cat{}; 155bdd1243dSDimitry Andric } 156bdd1243dSDimitry Andric } 157bdd1243dSDimitry Andric 158bdd1243dSDimitry Andric using iterator_category = decltype(__get_iterator_category()); 159bdd1243dSDimitry Andric }; 160bdd1243dSDimitry Andric 1611ac55f4cSDimitry Andric template <input_range _View, size_t _Np> 1621ac55f4cSDimitry Andric requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 1631ac55f4cSDimitry Andric __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 1641ac55f4cSDimitry Andric __returnable_element<range_reference_t<_View>, _Np> 1651ac55f4cSDimitry Andric template <bool _Const> 1661ac55f4cSDimitry Andric class elements_view<_View, _Np>::__iterator 1671ac55f4cSDimitry Andric : public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> { 1681ac55f4cSDimitry Andric template <bool> 1691ac55f4cSDimitry Andric friend class __iterator; 170bdd1243dSDimitry Andric 1711ac55f4cSDimitry Andric template <bool> 1721ac55f4cSDimitry Andric friend class __sentinel; 173bdd1243dSDimitry Andric 174bdd1243dSDimitry Andric using _Base = __maybe_const<_Const, _View>; 175bdd1243dSDimitry Andric 176bdd1243dSDimitry Andric iterator_t<_Base> __current_ = iterator_t<_Base>(); 177bdd1243dSDimitry Andric 178bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) { 179bdd1243dSDimitry Andric if constexpr (is_reference_v<range_reference_t<_Base>>) { 180bdd1243dSDimitry Andric return std::get<_Np>(*__i); 181bdd1243dSDimitry Andric } else { 182bdd1243dSDimitry Andric using _Element = remove_cv_t<tuple_element_t<_Np, range_reference_t<_Base>>>; 183bdd1243dSDimitry Andric return static_cast<_Element>(std::get<_Np>(*__i)); 184bdd1243dSDimitry Andric } 185bdd1243dSDimitry Andric } 186bdd1243dSDimitry Andric 187bdd1243dSDimitry Andric static consteval auto __get_iterator_concept() { 188bdd1243dSDimitry Andric if constexpr (random_access_range<_Base>) { 189bdd1243dSDimitry Andric return random_access_iterator_tag{}; 190bdd1243dSDimitry Andric } else if constexpr (bidirectional_range<_Base>) { 191bdd1243dSDimitry Andric return bidirectional_iterator_tag{}; 192bdd1243dSDimitry Andric } else if constexpr (forward_range<_Base>) { 193bdd1243dSDimitry Andric return forward_iterator_tag{}; 194bdd1243dSDimitry Andric } else { 195bdd1243dSDimitry Andric return input_iterator_tag{}; 196bdd1243dSDimitry Andric } 197bdd1243dSDimitry Andric } 198bdd1243dSDimitry Andric 199bdd1243dSDimitry Andric public: 200bdd1243dSDimitry Andric using iterator_concept = decltype(__get_iterator_concept()); 201bdd1243dSDimitry Andric using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>; 202bdd1243dSDimitry Andric using difference_type = range_difference_t<_Base>; 203bdd1243dSDimitry Andric 2041ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __iterator() 205bdd1243dSDimitry Andric requires default_initializable<iterator_t<_Base>> 206bdd1243dSDimitry Andric = default; 207bdd1243dSDimitry Andric 2081ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {} 209bdd1243dSDimitry Andric 2101ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i) 211bdd1243dSDimitry Andric requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> 212bdd1243dSDimitry Andric : __current_(std::move(__i.__current_)) {} 213bdd1243dSDimitry Andric 214bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; } 215bdd1243dSDimitry Andric 216bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } 217bdd1243dSDimitry Andric 218bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); } 219bdd1243dSDimitry Andric 2201ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { 221bdd1243dSDimitry Andric ++__current_; 222bdd1243dSDimitry Andric return *this; 223bdd1243dSDimitry Andric } 224bdd1243dSDimitry Andric 225bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } 226bdd1243dSDimitry Andric 2271ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) 228bdd1243dSDimitry Andric requires forward_range<_Base> 229bdd1243dSDimitry Andric { 23006c3fb27SDimitry Andric auto __temp = *this; 231bdd1243dSDimitry Andric ++__current_; 23206c3fb27SDimitry Andric return __temp; 233bdd1243dSDimitry Andric } 234bdd1243dSDimitry Andric 2351ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() 236bdd1243dSDimitry Andric requires bidirectional_range<_Base> 237bdd1243dSDimitry Andric { 238bdd1243dSDimitry Andric --__current_; 239bdd1243dSDimitry Andric return *this; 240bdd1243dSDimitry Andric } 241bdd1243dSDimitry Andric 2421ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) 243bdd1243dSDimitry Andric requires bidirectional_range<_Base> 244bdd1243dSDimitry Andric { 24506c3fb27SDimitry Andric auto __temp = *this; 246bdd1243dSDimitry Andric --__current_; 24706c3fb27SDimitry Andric return __temp; 248bdd1243dSDimitry Andric } 249bdd1243dSDimitry Andric 2501ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) 251bdd1243dSDimitry Andric requires random_access_range<_Base> 252bdd1243dSDimitry Andric { 253bdd1243dSDimitry Andric __current_ += __n; 254bdd1243dSDimitry Andric return *this; 255bdd1243dSDimitry Andric } 256bdd1243dSDimitry Andric 2571ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) 258bdd1243dSDimitry Andric requires random_access_range<_Base> 259bdd1243dSDimitry Andric { 260bdd1243dSDimitry Andric __current_ -= __n; 261bdd1243dSDimitry Andric return *this; 262bdd1243dSDimitry Andric } 263bdd1243dSDimitry Andric 264bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const 265bdd1243dSDimitry Andric requires random_access_range<_Base> 266bdd1243dSDimitry Andric { 267bdd1243dSDimitry Andric return __get_element(__current_ + __n); 268bdd1243dSDimitry Andric } 269bdd1243dSDimitry Andric 2701ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) 271bdd1243dSDimitry Andric requires equality_comparable<iterator_t<_Base>> 272bdd1243dSDimitry Andric { 273bdd1243dSDimitry Andric return __x.__current_ == __y.__current_; 274bdd1243dSDimitry Andric } 275bdd1243dSDimitry Andric 2761ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) 277bdd1243dSDimitry Andric requires random_access_range<_Base> 278bdd1243dSDimitry Andric { 279bdd1243dSDimitry Andric return __x.__current_ < __y.__current_; 280bdd1243dSDimitry Andric } 281bdd1243dSDimitry Andric 2821ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) 283bdd1243dSDimitry Andric requires random_access_range<_Base> 284bdd1243dSDimitry Andric { 285bdd1243dSDimitry Andric return __y < __x; 286bdd1243dSDimitry Andric } 287bdd1243dSDimitry Andric 2881ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) 289bdd1243dSDimitry Andric requires random_access_range<_Base> 290bdd1243dSDimitry Andric { 291bdd1243dSDimitry Andric return !(__y < __x); 292bdd1243dSDimitry Andric } 293bdd1243dSDimitry Andric 2941ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) 295bdd1243dSDimitry Andric requires random_access_range<_Base> 296bdd1243dSDimitry Andric { 297bdd1243dSDimitry Andric return !(__x < __y); 298bdd1243dSDimitry Andric } 299bdd1243dSDimitry Andric 3001ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) 301bdd1243dSDimitry Andric requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>> 302bdd1243dSDimitry Andric { 303bdd1243dSDimitry Andric return __x.__current_ <=> __y.__current_; 304bdd1243dSDimitry Andric } 305bdd1243dSDimitry Andric 3061ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y) 307bdd1243dSDimitry Andric requires random_access_range<_Base> 308bdd1243dSDimitry Andric { 3091ac55f4cSDimitry Andric return __iterator{__x} += __y; 310bdd1243dSDimitry Andric } 311bdd1243dSDimitry Andric 3121ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y) 313bdd1243dSDimitry Andric requires random_access_range<_Base> 314bdd1243dSDimitry Andric { 315bdd1243dSDimitry Andric return __y + __x; 316bdd1243dSDimitry Andric } 317bdd1243dSDimitry Andric 3181ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y) 319bdd1243dSDimitry Andric requires random_access_range<_Base> 320bdd1243dSDimitry Andric { 3211ac55f4cSDimitry Andric return __iterator{__x} -= __y; 322bdd1243dSDimitry Andric } 323bdd1243dSDimitry Andric 3241ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) 325bdd1243dSDimitry Andric requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 326bdd1243dSDimitry Andric { 327bdd1243dSDimitry Andric return __x.__current_ - __y.__current_; 328bdd1243dSDimitry Andric } 329bdd1243dSDimitry Andric }; 330bdd1243dSDimitry Andric 3311ac55f4cSDimitry Andric template <input_range _View, size_t _Np> 3321ac55f4cSDimitry Andric requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> && 3331ac55f4cSDimitry Andric __has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> && 3341ac55f4cSDimitry Andric __returnable_element<range_reference_t<_View>, _Np> 3351ac55f4cSDimitry Andric template <bool _Const> 3361ac55f4cSDimitry Andric class elements_view<_View, _Np>::__sentinel { 337bdd1243dSDimitry Andric private: 338bdd1243dSDimitry Andric using _Base = __maybe_const<_Const, _View>; 339bdd1243dSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>(); 340bdd1243dSDimitry Andric 3411ac55f4cSDimitry Andric template <bool> 3421ac55f4cSDimitry Andric friend class __sentinel; 343bdd1243dSDimitry Andric 344bdd1243dSDimitry Andric template <bool _AnyConst> 3451ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) { 346bdd1243dSDimitry Andric return (__iter.__current_); 347bdd1243dSDimitry Andric } 348bdd1243dSDimitry Andric 349bdd1243dSDimitry Andric public: 3501ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI __sentinel() = default; 351bdd1243dSDimitry Andric 3521ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {} 353bdd1243dSDimitry Andric 3541ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other) 355bdd1243dSDimitry Andric requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> 356bdd1243dSDimitry Andric : __end_(std::move(__other.__end_)) {} 357bdd1243dSDimitry Andric 358bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; } 359bdd1243dSDimitry Andric 360bdd1243dSDimitry Andric template <bool _OtherConst> 361bdd1243dSDimitry Andric requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 3621ac55f4cSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { 363bdd1243dSDimitry Andric return __get_current(__x) == __y.__end_; 364bdd1243dSDimitry Andric } 365bdd1243dSDimitry Andric 366bdd1243dSDimitry Andric template <bool _OtherConst> 367bdd1243dSDimitry Andric requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 368bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 3691ac55f4cSDimitry Andric operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { 370bdd1243dSDimitry Andric return __get_current(__x) - __y.__end_; 371bdd1243dSDimitry Andric } 372bdd1243dSDimitry Andric 373bdd1243dSDimitry Andric template <bool _OtherConst> 374bdd1243dSDimitry Andric requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> 375bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> 3761ac55f4cSDimitry Andric operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { 377bdd1243dSDimitry Andric return __x.__end_ - __get_current(__y); 378bdd1243dSDimitry Andric } 379bdd1243dSDimitry Andric }; 380bdd1243dSDimitry Andric 381bdd1243dSDimitry Andric template <class _Tp, size_t _Np> 382bdd1243dSDimitry Andric inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Np>> = enable_borrowed_range<_Tp>; 383bdd1243dSDimitry Andric 384bdd1243dSDimitry Andric template <class _Tp> 385bdd1243dSDimitry Andric using keys_view = elements_view<_Tp, 0>; 386bdd1243dSDimitry Andric template <class _Tp> 387bdd1243dSDimitry Andric using values_view = elements_view<_Tp, 1>; 388bdd1243dSDimitry Andric 389bdd1243dSDimitry Andric namespace views { 390bdd1243dSDimitry Andric namespace __elements { 391bdd1243dSDimitry Andric 392bdd1243dSDimitry Andric template <size_t _Np> 393bdd1243dSDimitry Andric struct __fn : __range_adaptor_closure<__fn<_Np>> { 394bdd1243dSDimitry Andric template <class _Range> 395bdd1243dSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const 396bdd1243dSDimitry Andric /**/ noexcept(noexcept(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range)))) 397bdd1243dSDimitry Andric /*------*/ -> decltype(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))) { 398bdd1243dSDimitry Andric /*-------------*/ return elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range)); 399bdd1243dSDimitry Andric } 400bdd1243dSDimitry Andric }; 401bdd1243dSDimitry Andric } // namespace __elements 402bdd1243dSDimitry Andric 403bdd1243dSDimitry Andric inline namespace __cpo { 404bdd1243dSDimitry Andric template <size_t _Np> 405bdd1243dSDimitry Andric inline constexpr auto elements = __elements::__fn<_Np>{}; 406bdd1243dSDimitry Andric inline constexpr auto keys = elements<0>; 407bdd1243dSDimitry Andric inline constexpr auto values = elements<1>; 408bdd1243dSDimitry Andric } // namespace __cpo 409bdd1243dSDimitry Andric } // namespace views 410bdd1243dSDimitry Andric } // namespace ranges 411bdd1243dSDimitry Andric 412bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 20 413bdd1243dSDimitry Andric 414bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 415bdd1243dSDimitry Andric 416b3edf446SDimitry Andric _LIBCPP_POP_MACROS 417b3edf446SDimitry Andric 418bdd1243dSDimitry Andric #endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H 419