1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9bdd1243dSDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H 11fe6060f1SDimitry Andric #define _LIBCPP___RANGES_VIEW_INTERFACE_H 12fe6060f1SDimitry Andric 1381ad6265SDimitry Andric #include <__assert> 1481ad6265SDimitry Andric #include <__concepts/derived_from.h> 1581ad6265SDimitry Andric #include <__concepts/same_as.h> 16fe6060f1SDimitry Andric #include <__config> 17fe6060f1SDimitry Andric #include <__iterator/concepts.h> 18fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 19fe6060f1SDimitry Andric #include <__iterator/prev.h> 20fe6060f1SDimitry Andric #include <__memory/pointer_traits.h> 21fe6060f1SDimitry Andric #include <__ranges/access.h> 22fe6060f1SDimitry Andric #include <__ranges/concepts.h> 23fe6060f1SDimitry Andric #include <__ranges/empty.h> 24bdd1243dSDimitry Andric #include <__type_traits/is_class.h> 25bdd1243dSDimitry Andric #include <__type_traits/make_unsigned.h> 26bdd1243dSDimitry Andric #include <__type_traits/remove_cv.h> 27fe6060f1SDimitry Andric 28fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 29fe6060f1SDimitry Andric # pragma GCC system_header 30fe6060f1SDimitry Andric #endif 31fe6060f1SDimitry Andric 32fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 33fe6060f1SDimitry Andric 3406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 35fe6060f1SDimitry Andric 36fe6060f1SDimitry Andric namespace ranges { 37fe6060f1SDimitry Andric 38fe6060f1SDimitry Andric template <class _Derived> 39fe6060f1SDimitry Andric requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 4004eeddc0SDimitry Andric class view_interface { __derived()41*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept { 42349cc55cSDimitry Andric static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 43fe6060f1SDimitry Andric return static_cast<_Derived&>(*this); 44fe6060f1SDimitry Andric } 45fe6060f1SDimitry Andric __derived()46*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept { 47349cc55cSDimitry Andric static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 48fe6060f1SDimitry Andric return static_cast<_Derived const&>(*this); 49fe6060f1SDimitry Andric } 50fe6060f1SDimitry Andric 51fe6060f1SDimitry Andric public: 52fe6060f1SDimitry Andric template <class _D2 = _Derived> empty()53fe6060f1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() 54fe6060f1SDimitry Andric requires forward_range<_D2> 55fe6060f1SDimitry Andric { 56fe6060f1SDimitry Andric return ranges::begin(__derived()) == ranges::end(__derived()); 57fe6060f1SDimitry Andric } 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric template <class _D2 = _Derived> empty()60fe6060f1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const 61fe6060f1SDimitry Andric requires forward_range<const _D2> 62fe6060f1SDimitry Andric { 63fe6060f1SDimitry Andric return ranges::begin(__derived()) == ranges::end(__derived()); 64fe6060f1SDimitry Andric } 65fe6060f1SDimitry Andric 66fe6060f1SDimitry Andric template <class _D2 = _Derived> 67*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() requires(_D2 & __t)6881ad6265SDimitry Andric requires requires(_D2& __t) { ranges::empty(__t); } 69fe6060f1SDimitry Andric { 70fe6060f1SDimitry Andric return !ranges::empty(__derived()); 71fe6060f1SDimitry Andric } 72fe6060f1SDimitry Andric 73fe6060f1SDimitry Andric template <class _D2 = _Derived> 74*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const requires(const _D2 & __t)7581ad6265SDimitry Andric requires requires(const _D2& __t) { ranges::empty(__t); } 76fe6060f1SDimitry Andric { 77fe6060f1SDimitry Andric return !ranges::empty(__derived()); 78fe6060f1SDimitry Andric } 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric template <class _D2 = _Derived> data()81*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto data() 82fe6060f1SDimitry Andric requires contiguous_iterator<iterator_t<_D2>> 83fe6060f1SDimitry Andric { 8481ad6265SDimitry Andric return std::to_address(ranges::begin(__derived())); 85fe6060f1SDimitry Andric } 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric template <class _D2 = _Derived> data()88*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto data() const 89fe6060f1SDimitry Andric requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>> 90fe6060f1SDimitry Andric { 9181ad6265SDimitry Andric return std::to_address(ranges::begin(__derived())); 92fe6060f1SDimitry Andric } 93fe6060f1SDimitry Andric 94fe6060f1SDimitry Andric template <class _D2 = _Derived> size()95*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() 9681ad6265SDimitry Andric requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>> 97fe6060f1SDimitry Andric { 98bdd1243dSDimitry Andric return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); 99fe6060f1SDimitry Andric } 100fe6060f1SDimitry Andric 101fe6060f1SDimitry Andric template <class _D2 = _Derived> size()102*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto size() const 10381ad6265SDimitry Andric requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>> 104fe6060f1SDimitry Andric { 105bdd1243dSDimitry Andric return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); 106fe6060f1SDimitry Andric } 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric template <class _D2 = _Derived> decltype(auto)109*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() 110fe6060f1SDimitry Andric requires forward_range<_D2> 111fe6060f1SDimitry Andric { 112*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 113*cb14a3feSDimitry Andric !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 114fe6060f1SDimitry Andric return *ranges::begin(__derived()); 115fe6060f1SDimitry Andric } 116fe6060f1SDimitry Andric 117fe6060f1SDimitry Andric template <class _D2 = _Derived> decltype(auto)118*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const 119fe6060f1SDimitry Andric requires forward_range<const _D2> 120fe6060f1SDimitry Andric { 121*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 122*cb14a3feSDimitry Andric !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 123fe6060f1SDimitry Andric return *ranges::begin(__derived()); 124fe6060f1SDimitry Andric } 125fe6060f1SDimitry Andric 126fe6060f1SDimitry Andric template <class _D2 = _Derived> decltype(auto)127*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() 128fe6060f1SDimitry Andric requires bidirectional_range<_D2> && common_range<_D2> 129fe6060f1SDimitry Andric { 130*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 131*cb14a3feSDimitry Andric !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 132fe6060f1SDimitry Andric return *ranges::prev(ranges::end(__derived())); 133fe6060f1SDimitry Andric } 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric template <class _D2 = _Derived> decltype(auto)136*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const 137fe6060f1SDimitry Andric requires bidirectional_range<const _D2> && common_range<const _D2> 138fe6060f1SDimitry Andric { 139*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 140*cb14a3feSDimitry Andric !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 141fe6060f1SDimitry Andric return *ranges::prev(ranges::end(__derived())); 142fe6060f1SDimitry Andric } 143fe6060f1SDimitry Andric 144fe6060f1SDimitry Andric template <random_access_range _RARange = _Derived> decltype(auto)145*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) { 146fe6060f1SDimitry Andric return ranges::begin(__derived())[__index]; 147fe6060f1SDimitry Andric } 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric template <random_access_range _RARange = const _Derived> decltype(auto)150*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const { 151fe6060f1SDimitry Andric return ranges::begin(__derived())[__index]; 152fe6060f1SDimitry Andric } 153fe6060f1SDimitry Andric }; 154fe6060f1SDimitry Andric 1551fd87a68SDimitry Andric } // namespace ranges 156fe6060f1SDimitry Andric 15706c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 158fe6060f1SDimitry Andric 159fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 160fe6060f1SDimitry Andric 161fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_VIEW_INTERFACE_H 162