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 //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H 10fe6060f1SDimitry Andric #define _LIBCPP___RANGES_VIEW_INTERFACE_H 11fe6060f1SDimitry Andric 12*81ad6265SDimitry Andric #include <__assert> 13*81ad6265SDimitry Andric #include <__concepts/derived_from.h> 14*81ad6265SDimitry Andric #include <__concepts/same_as.h> 15fe6060f1SDimitry Andric #include <__config> 16fe6060f1SDimitry Andric #include <__iterator/concepts.h> 17fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 18fe6060f1SDimitry Andric #include <__iterator/prev.h> 19fe6060f1SDimitry Andric #include <__memory/pointer_traits.h> 20fe6060f1SDimitry Andric #include <__ranges/access.h> 21fe6060f1SDimitry Andric #include <__ranges/concepts.h> 22fe6060f1SDimitry Andric #include <__ranges/empty.h> 23fe6060f1SDimitry Andric #include <type_traits> 24fe6060f1SDimitry Andric 25fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26fe6060f1SDimitry Andric # pragma GCC system_header 27fe6060f1SDimitry Andric #endif 28fe6060f1SDimitry Andric 29fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 30fe6060f1SDimitry Andric 31*81ad6265SDimitry Andric #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric namespace ranges { 34fe6060f1SDimitry Andric 35fe6060f1SDimitry Andric template<class _Derived> 36fe6060f1SDimitry Andric requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 3704eeddc0SDimitry Andric class view_interface { 38fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 39fe6060f1SDimitry Andric constexpr _Derived& __derived() noexcept { 40349cc55cSDimitry Andric static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 41fe6060f1SDimitry Andric return static_cast<_Derived&>(*this); 42fe6060f1SDimitry Andric } 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 45fe6060f1SDimitry Andric constexpr _Derived const& __derived() const noexcept { 46349cc55cSDimitry Andric static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 47fe6060f1SDimitry Andric return static_cast<_Derived const&>(*this); 48fe6060f1SDimitry Andric } 49fe6060f1SDimitry Andric 50fe6060f1SDimitry Andric public: 51fe6060f1SDimitry Andric template<class _D2 = _Derived> 52fe6060f1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() 53fe6060f1SDimitry Andric requires forward_range<_D2> 54fe6060f1SDimitry Andric { 55fe6060f1SDimitry Andric return ranges::begin(__derived()) == ranges::end(__derived()); 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric template<class _D2 = _Derived> 59fe6060f1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const 60fe6060f1SDimitry Andric requires forward_range<const _D2> 61fe6060f1SDimitry Andric { 62fe6060f1SDimitry Andric return ranges::begin(__derived()) == ranges::end(__derived()); 63fe6060f1SDimitry Andric } 64fe6060f1SDimitry Andric 65fe6060f1SDimitry Andric template<class _D2 = _Derived> 66fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 67fe6060f1SDimitry Andric constexpr explicit operator bool() 68*81ad6265SDimitry 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> 74fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 75fe6060f1SDimitry Andric constexpr explicit operator bool() const 76*81ad6265SDimitry Andric requires requires (const _D2& __t) { ranges::empty(__t); } 77fe6060f1SDimitry Andric { 78fe6060f1SDimitry Andric return !ranges::empty(__derived()); 79fe6060f1SDimitry Andric } 80fe6060f1SDimitry Andric 81fe6060f1SDimitry Andric template<class _D2 = _Derived> 82fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 83fe6060f1SDimitry Andric constexpr auto data() 84fe6060f1SDimitry Andric requires contiguous_iterator<iterator_t<_D2>> 85fe6060f1SDimitry Andric { 86*81ad6265SDimitry Andric return std::to_address(ranges::begin(__derived())); 87fe6060f1SDimitry Andric } 88fe6060f1SDimitry Andric 89fe6060f1SDimitry Andric template<class _D2 = _Derived> 90fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 91fe6060f1SDimitry Andric constexpr auto data() const 92fe6060f1SDimitry Andric requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>> 93fe6060f1SDimitry Andric { 94*81ad6265SDimitry Andric return std::to_address(ranges::begin(__derived())); 95fe6060f1SDimitry Andric } 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric template<class _D2 = _Derived> 98fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 99fe6060f1SDimitry Andric constexpr auto size() 100*81ad6265SDimitry Andric requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>> 101fe6060f1SDimitry Andric { 102fe6060f1SDimitry Andric return ranges::end(__derived()) - ranges::begin(__derived()); 103fe6060f1SDimitry Andric } 104fe6060f1SDimitry Andric 105fe6060f1SDimitry Andric template<class _D2 = _Derived> 106fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 107fe6060f1SDimitry Andric constexpr auto size() const 108*81ad6265SDimitry Andric requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>> 109fe6060f1SDimitry Andric { 110fe6060f1SDimitry Andric return ranges::end(__derived()) - ranges::begin(__derived()); 111fe6060f1SDimitry Andric } 112fe6060f1SDimitry Andric 113fe6060f1SDimitry Andric template<class _D2 = _Derived> 114fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 115fe6060f1SDimitry Andric constexpr decltype(auto) front() 116fe6060f1SDimitry Andric requires forward_range<_D2> 117fe6060f1SDimitry Andric { 118fe6060f1SDimitry Andric _LIBCPP_ASSERT(!empty(), 119fe6060f1SDimitry Andric "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 120fe6060f1SDimitry Andric return *ranges::begin(__derived()); 121fe6060f1SDimitry Andric } 122fe6060f1SDimitry Andric 123fe6060f1SDimitry Andric template<class _D2 = _Derived> 124fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 125fe6060f1SDimitry Andric constexpr decltype(auto) front() const 126fe6060f1SDimitry Andric requires forward_range<const _D2> 127fe6060f1SDimitry Andric { 128fe6060f1SDimitry Andric _LIBCPP_ASSERT(!empty(), 129fe6060f1SDimitry Andric "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 130fe6060f1SDimitry Andric return *ranges::begin(__derived()); 131fe6060f1SDimitry Andric } 132fe6060f1SDimitry Andric 133fe6060f1SDimitry Andric template<class _D2 = _Derived> 134fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 135fe6060f1SDimitry Andric constexpr decltype(auto) back() 136fe6060f1SDimitry Andric requires bidirectional_range<_D2> && common_range<_D2> 137fe6060f1SDimitry Andric { 138fe6060f1SDimitry Andric _LIBCPP_ASSERT(!empty(), 139fe6060f1SDimitry Andric "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 140fe6060f1SDimitry Andric return *ranges::prev(ranges::end(__derived())); 141fe6060f1SDimitry Andric } 142fe6060f1SDimitry Andric 143fe6060f1SDimitry Andric template<class _D2 = _Derived> 144fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 145fe6060f1SDimitry Andric constexpr decltype(auto) back() const 146fe6060f1SDimitry Andric requires bidirectional_range<const _D2> && common_range<const _D2> 147fe6060f1SDimitry Andric { 148fe6060f1SDimitry Andric _LIBCPP_ASSERT(!empty(), 149fe6060f1SDimitry Andric "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 150fe6060f1SDimitry Andric return *ranges::prev(ranges::end(__derived())); 151fe6060f1SDimitry Andric } 152fe6060f1SDimitry Andric 153fe6060f1SDimitry Andric template<random_access_range _RARange = _Derived> 154fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 155fe6060f1SDimitry Andric constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) 156fe6060f1SDimitry Andric { 157fe6060f1SDimitry Andric return ranges::begin(__derived())[__index]; 158fe6060f1SDimitry Andric } 159fe6060f1SDimitry Andric 160fe6060f1SDimitry Andric template<random_access_range _RARange = const _Derived> 161fe6060f1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 162fe6060f1SDimitry Andric constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const 163fe6060f1SDimitry Andric { 164fe6060f1SDimitry Andric return ranges::begin(__derived())[__index]; 165fe6060f1SDimitry Andric } 166fe6060f1SDimitry Andric }; 167fe6060f1SDimitry Andric 1681fd87a68SDimitry Andric } // namespace ranges 169fe6060f1SDimitry Andric 170*81ad6265SDimitry Andric #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 171fe6060f1SDimitry Andric 172fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 173fe6060f1SDimitry Andric 174fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_VIEW_INTERFACE_H 175