Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/elements_view.h
35236 views
// -*- C++ -*-1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___RANGES_ELEMENTS_VIEW_H10#define _LIBCPP___RANGES_ELEMENTS_VIEW_H1112#include <__compare/three_way_comparable.h>13#include <__concepts/constructible.h>14#include <__concepts/convertible_to.h>15#include <__concepts/derived_from.h>16#include <__concepts/equality_comparable.h>17#include <__config>18#include <__fwd/complex.h>19#include <__iterator/concepts.h>20#include <__iterator/iterator_traits.h>21#include <__ranges/access.h>22#include <__ranges/all.h>23#include <__ranges/concepts.h>24#include <__ranges/enable_borrowed_range.h>25#include <__ranges/range_adaptor.h>26#include <__ranges/size.h>27#include <__ranges/view_interface.h>28#include <__tuple/tuple_element.h>29#include <__tuple/tuple_like.h>30#include <__tuple/tuple_size.h>31#include <__type_traits/is_reference.h>32#include <__type_traits/maybe_const.h>33#include <__type_traits/remove_cv.h>34#include <__type_traits/remove_cvref.h>35#include <__type_traits/remove_reference.h>36#include <__utility/declval.h>37#include <__utility/forward.h>38#include <__utility/move.h>39#include <cstddef>4041#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)42# pragma GCC system_header43#endif4445_LIBCPP_PUSH_MACROS46#include <__undef_macros>4748_LIBCPP_BEGIN_NAMESPACE_STD4950#if _LIBCPP_STD_VER >= 205152namespace ranges {5354template <class _Tp, size_t _Np>55concept __has_tuple_element = __tuple_like<_Tp> && _Np < tuple_size<_Tp>::value;5657template <class _Tp, size_t _Np>58concept __returnable_element = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Np, _Tp>>;5960template <input_range _View, size_t _Np>61requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&62__has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&63__returnable_element<range_reference_t<_View>, _Np>64class elements_view : public view_interface<elements_view<_View, _Np>> {65private:66template <bool>67class __iterator;6869template <bool>70class __sentinel;7172public:73_LIBCPP_HIDE_FROM_ABI elements_view()74requires default_initializable<_View>75= default;7677_LIBCPP_HIDE_FROM_ABI constexpr explicit elements_view(_View __base) : __base_(std::move(__base)) {}7879_LIBCPP_HIDE_FROM_ABI constexpr _View base() const&80requires copy_constructible<_View>81{82return __base_;83}8485_LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }8687_LIBCPP_HIDE_FROM_ABI constexpr auto begin()88requires(!__simple_view<_View>)89{90return __iterator</*_Const=*/false>(ranges::begin(__base_));91}9293_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const94requires range<const _View>95{96return __iterator</*_Const=*/true>(ranges::begin(__base_));97}9899_LIBCPP_HIDE_FROM_ABI constexpr auto end()100requires(!__simple_view<_View> && !common_range<_View>)101{102return __sentinel</*_Const=*/false>{ranges::end(__base_)};103}104105_LIBCPP_HIDE_FROM_ABI constexpr auto end()106requires(!__simple_view<_View> && common_range<_View>)107{108return __iterator</*_Const=*/false>{ranges::end(__base_)};109}110111_LIBCPP_HIDE_FROM_ABI constexpr auto end() const112requires range<const _View>113{114return __sentinel</*_Const=*/true>{ranges::end(__base_)};115}116117_LIBCPP_HIDE_FROM_ABI constexpr auto end() const118requires common_range<const _View>119{120return __iterator</*_Const=*/true>{ranges::end(__base_)};121}122123_LIBCPP_HIDE_FROM_ABI constexpr auto size()124requires sized_range<_View>125{126return ranges::size(__base_);127}128129_LIBCPP_HIDE_FROM_ABI constexpr auto size() const130requires sized_range<const _View>131{132return ranges::size(__base_);133}134135private:136_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();137};138139template <class, size_t>140struct __elements_view_iterator_category_base {};141142template <forward_range _Base, size_t _Np>143struct __elements_view_iterator_category_base<_Base, _Np> {144static consteval auto __get_iterator_category() {145using _Result = decltype(std::get<_Np>(*std::declval<iterator_t<_Base>>()));146using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;147148if constexpr (!is_lvalue_reference_v<_Result>) {149return input_iterator_tag{};150} else if constexpr (derived_from<_Cat, random_access_iterator_tag>) {151return random_access_iterator_tag{};152} else {153return _Cat{};154}155}156157using iterator_category = decltype(__get_iterator_category());158};159160template <input_range _View, size_t _Np>161requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&162__has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&163__returnable_element<range_reference_t<_View>, _Np>164template <bool _Const>165class elements_view<_View, _Np>::__iterator166: public __elements_view_iterator_category_base<__maybe_const<_Const, _View>, _Np> {167template <bool>168friend class __iterator;169170template <bool>171friend class __sentinel;172173using _Base = __maybe_const<_Const, _View>;174175iterator_t<_Base> __current_ = iterator_t<_Base>();176177_LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_element(const iterator_t<_Base>& __i) {178if constexpr (is_reference_v<range_reference_t<_Base>>) {179return std::get<_Np>(*__i);180} else {181using _Element = remove_cv_t<tuple_element_t<_Np, range_reference_t<_Base>>>;182return static_cast<_Element>(std::get<_Np>(*__i));183}184}185186static consteval auto __get_iterator_concept() {187if constexpr (random_access_range<_Base>) {188return random_access_iterator_tag{};189} else if constexpr (bidirectional_range<_Base>) {190return bidirectional_iterator_tag{};191} else if constexpr (forward_range<_Base>) {192return forward_iterator_tag{};193} else {194return input_iterator_tag{};195}196}197198public:199using iterator_concept = decltype(__get_iterator_concept());200using value_type = remove_cvref_t<tuple_element_t<_Np, range_value_t<_Base>>>;201using difference_type = range_difference_t<_Base>;202203_LIBCPP_HIDE_FROM_ABI __iterator()204requires default_initializable<iterator_t<_Base>>205= default;206207_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(iterator_t<_Base> __current) : __current_(std::move(__current)) {}208209_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)210requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>211: __current_(std::move(__i.__current_)) {}212213_LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }214215_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }216217_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return __get_element(__current_); }218219_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {220++__current_;221return *this;222}223224_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }225226_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)227requires forward_range<_Base>228{229auto __temp = *this;230++__current_;231return __temp;232}233234_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()235requires bidirectional_range<_Base>236{237--__current_;238return *this;239}240241_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)242requires bidirectional_range<_Base>243{244auto __temp = *this;245--__current_;246return __temp;247}248249_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)250requires random_access_range<_Base>251{252__current_ += __n;253return *this;254}255256_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)257requires random_access_range<_Base>258{259__current_ -= __n;260return *this;261}262263_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const264requires random_access_range<_Base>265{266return __get_element(__current_ + __n);267}268269_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)270requires equality_comparable<iterator_t<_Base>>271{272return __x.__current_ == __y.__current_;273}274275_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)276requires random_access_range<_Base>277{278return __x.__current_ < __y.__current_;279}280281_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)282requires random_access_range<_Base>283{284return __y < __x;285}286287_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)288requires random_access_range<_Base>289{290return !(__y < __x);291}292293_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)294requires random_access_range<_Base>295{296return !(__x < __y);297}298299_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)300requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>301{302return __x.__current_ <=> __y.__current_;303}304305_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __x, difference_type __y)306requires random_access_range<_Base>307{308return __iterator{__x} += __y;309}310311_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __x, const __iterator& __y)312requires random_access_range<_Base>313{314return __y + __x;315}316317_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __x, difference_type __y)318requires random_access_range<_Base>319{320return __iterator{__x} -= __y;321}322323_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)324requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>325{326return __x.__current_ - __y.__current_;327}328};329330template <input_range _View, size_t _Np>331requires view<_View> && __has_tuple_element<range_value_t<_View>, _Np> &&332__has_tuple_element<remove_reference_t<range_reference_t<_View>>, _Np> &&333__returnable_element<range_reference_t<_View>, _Np>334template <bool _Const>335class elements_view<_View, _Np>::__sentinel {336private:337using _Base = __maybe_const<_Const, _View>;338_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();339340template <bool>341friend class __sentinel;342343template <bool _AnyConst>344_LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __get_current(const __iterator<_AnyConst>& __iter) {345return (__iter.__current_);346}347348public:349_LIBCPP_HIDE_FROM_ABI __sentinel() = default;350351_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}352353_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __other)354requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>355: __end_(std::move(__other.__end_)) {}356357_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }358359template <bool _OtherConst>360requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>361_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {362return __get_current(__x) == __y.__end_;363}364365template <bool _OtherConst>366requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>367_LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>368operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {369return __get_current(__x) - __y.__end_;370}371372template <bool _OtherConst>373requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>374_LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>375operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) {376return __x.__end_ - __get_current(__y);377}378};379380template <class _Tp, size_t _Np>381inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Np>> = enable_borrowed_range<_Tp>;382383template <class _Tp>384using keys_view = elements_view<_Tp, 0>;385template <class _Tp>386using values_view = elements_view<_Tp, 1>;387388namespace views {389namespace __elements {390391template <size_t _Np>392struct __fn : __range_adaptor_closure<__fn<_Np>> {393template <class _Range>394[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const395/**/ noexcept(noexcept(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))))396/*------*/ -> decltype(elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range))) {397/*-------------*/ return elements_view<all_t<_Range&&>, _Np>(std::forward<_Range>(__range));398}399};400} // namespace __elements401402inline namespace __cpo {403template <size_t _Np>404inline constexpr auto elements = __elements::__fn<_Np>{};405inline constexpr auto keys = elements<0>;406inline constexpr auto values = elements<1>;407} // namespace __cpo408} // namespace views409} // namespace ranges410411#endif // _LIBCPP_STD_VER >= 20412413_LIBCPP_END_NAMESPACE_STD414415_LIBCPP_POP_MACROS416417#endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H418419420