1e78f53d1SNikolas Klauser // -*- C++ -*- 2e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 3e78f53d1SNikolas Klauser // 4e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 6e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e78f53d1SNikolas Klauser // 8e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 9e78f53d1SNikolas Klauser 10*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___RANGES_VIEW_INTERFACE_H 11*ce777190SNikolas Klauser #define _LIBCPP___CXX03___RANGES_VIEW_INTERFACE_H 12e78f53d1SNikolas Klauser 1373fbae83SNikolas Klauser #include <__cxx03/__assert> 1473fbae83SNikolas Klauser #include <__cxx03/__concepts/derived_from.h> 1573fbae83SNikolas Klauser #include <__cxx03/__concepts/same_as.h> 1673fbae83SNikolas Klauser #include <__cxx03/__config> 1773fbae83SNikolas Klauser #include <__cxx03/__iterator/concepts.h> 1873fbae83SNikolas Klauser #include <__cxx03/__iterator/iterator_traits.h> 1973fbae83SNikolas Klauser #include <__cxx03/__iterator/prev.h> 2073fbae83SNikolas Klauser #include <__cxx03/__memory/pointer_traits.h> 2173fbae83SNikolas Klauser #include <__cxx03/__ranges/access.h> 2273fbae83SNikolas Klauser #include <__cxx03/__ranges/concepts.h> 2373fbae83SNikolas Klauser #include <__cxx03/__ranges/empty.h> 2473fbae83SNikolas Klauser #include <__cxx03/__ranges/size.h> 2573fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_class.h> 2673fbae83SNikolas Klauser #include <__cxx03/__type_traits/make_unsigned.h> 2773fbae83SNikolas Klauser #include <__cxx03/__type_traits/remove_cv.h> 28e78f53d1SNikolas Klauser 29e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 30e78f53d1SNikolas Klauser # pragma GCC system_header 31e78f53d1SNikolas Klauser #endif 32e78f53d1SNikolas Klauser 33e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 34e78f53d1SNikolas Klauser 35e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 20 36e78f53d1SNikolas Klauser 37e78f53d1SNikolas Klauser namespace ranges { 38e78f53d1SNikolas Klauser 39e78f53d1SNikolas Klauser template <class _Derived> 40e78f53d1SNikolas Klauser requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 41e78f53d1SNikolas Klauser class view_interface { 42e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept { 43e78f53d1SNikolas Klauser static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 44e78f53d1SNikolas Klauser return static_cast<_Derived&>(*this); 45e78f53d1SNikolas Klauser } 46e78f53d1SNikolas Klauser 47e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept { 48e78f53d1SNikolas Klauser static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); 49e78f53d1SNikolas Klauser return static_cast<_Derived const&>(*this); 50e78f53d1SNikolas Klauser } 51e78f53d1SNikolas Klauser 52e78f53d1SNikolas Klauser public: 53e78f53d1SNikolas Klauser template <class _D2 = _Derived> 54e78f53d1SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() 55e78f53d1SNikolas Klauser requires sized_range<_D2> || forward_range<_D2> 56e78f53d1SNikolas Klauser { 57e78f53d1SNikolas Klauser if constexpr (sized_range<_D2>) { 58e78f53d1SNikolas Klauser return ranges::size(__derived()) == 0; 59e78f53d1SNikolas Klauser } else { 60e78f53d1SNikolas Klauser return ranges::begin(__derived()) == ranges::end(__derived()); 61e78f53d1SNikolas Klauser } 62e78f53d1SNikolas Klauser } 63e78f53d1SNikolas Klauser 64e78f53d1SNikolas Klauser template <class _D2 = _Derived> 65e78f53d1SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const 66e78f53d1SNikolas Klauser requires sized_range<const _D2> || forward_range<const _D2> 67e78f53d1SNikolas Klauser { 68e78f53d1SNikolas Klauser if constexpr (sized_range<const _D2>) { 69e78f53d1SNikolas Klauser return ranges::size(__derived()) == 0; 70e78f53d1SNikolas Klauser } else { 71e78f53d1SNikolas Klauser return ranges::begin(__derived()) == ranges::end(__derived()); 72e78f53d1SNikolas Klauser } 73e78f53d1SNikolas Klauser } 74e78f53d1SNikolas Klauser 75e78f53d1SNikolas Klauser template <class _D2 = _Derived> 76e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() 77e78f53d1SNikolas Klauser requires requires(_D2& __t) { ranges::empty(__t); } 78e78f53d1SNikolas Klauser { 79e78f53d1SNikolas Klauser return !ranges::empty(__derived()); 80e78f53d1SNikolas Klauser } 81e78f53d1SNikolas Klauser 82e78f53d1SNikolas Klauser template <class _D2 = _Derived> 83e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const 84e78f53d1SNikolas Klauser requires requires(const _D2& __t) { ranges::empty(__t); } 85e78f53d1SNikolas Klauser { 86e78f53d1SNikolas Klauser return !ranges::empty(__derived()); 87e78f53d1SNikolas Klauser } 88e78f53d1SNikolas Klauser 89e78f53d1SNikolas Klauser template <class _D2 = _Derived> 90e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto data() 91e78f53d1SNikolas Klauser requires contiguous_iterator<iterator_t<_D2>> 92e78f53d1SNikolas Klauser { 93e78f53d1SNikolas Klauser return std::to_address(ranges::begin(__derived())); 94e78f53d1SNikolas Klauser } 95e78f53d1SNikolas Klauser 96e78f53d1SNikolas Klauser template <class _D2 = _Derived> 97e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto data() const 98e78f53d1SNikolas Klauser requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>> 99e78f53d1SNikolas Klauser { 100e78f53d1SNikolas Klauser return std::to_address(ranges::begin(__derived())); 101e78f53d1SNikolas Klauser } 102e78f53d1SNikolas Klauser 103e78f53d1SNikolas Klauser template <class _D2 = _Derived> 104e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto size() 105e78f53d1SNikolas Klauser requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>> 106e78f53d1SNikolas Klauser { 107e78f53d1SNikolas Klauser return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); 108e78f53d1SNikolas Klauser } 109e78f53d1SNikolas Klauser 110e78f53d1SNikolas Klauser template <class _D2 = _Derived> 111e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr auto size() const 112e78f53d1SNikolas Klauser requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>> 113e78f53d1SNikolas Klauser { 114e78f53d1SNikolas Klauser return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived())); 115e78f53d1SNikolas Klauser } 116e78f53d1SNikolas Klauser 117e78f53d1SNikolas Klauser template <class _D2 = _Derived> 118e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() 119e78f53d1SNikolas Klauser requires forward_range<_D2> 120e78f53d1SNikolas Klauser { 121e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 122e78f53d1SNikolas Klauser !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 123e78f53d1SNikolas Klauser return *ranges::begin(__derived()); 124e78f53d1SNikolas Klauser } 125e78f53d1SNikolas Klauser 126e78f53d1SNikolas Klauser template <class _D2 = _Derived> 127e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const 128e78f53d1SNikolas Klauser requires forward_range<const _D2> 129e78f53d1SNikolas Klauser { 130e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 131e78f53d1SNikolas Klauser !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); 132e78f53d1SNikolas Klauser return *ranges::begin(__derived()); 133e78f53d1SNikolas Klauser } 134e78f53d1SNikolas Klauser 135e78f53d1SNikolas Klauser template <class _D2 = _Derived> 136e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() 137e78f53d1SNikolas Klauser requires bidirectional_range<_D2> && common_range<_D2> 138e78f53d1SNikolas Klauser { 139e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 140e78f53d1SNikolas Klauser !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 141e78f53d1SNikolas Klauser return *ranges::prev(ranges::end(__derived())); 142e78f53d1SNikolas Klauser } 143e78f53d1SNikolas Klauser 144e78f53d1SNikolas Klauser template <class _D2 = _Derived> 145e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const 146e78f53d1SNikolas Klauser requires bidirectional_range<const _D2> && common_range<const _D2> 147e78f53d1SNikolas Klauser { 148e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 149e78f53d1SNikolas Klauser !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); 150e78f53d1SNikolas Klauser return *ranges::prev(ranges::end(__derived())); 151e78f53d1SNikolas Klauser } 152e78f53d1SNikolas Klauser 153e78f53d1SNikolas Klauser template <random_access_range _RARange = _Derived> 154e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) { 155e78f53d1SNikolas Klauser return ranges::begin(__derived())[__index]; 156e78f53d1SNikolas Klauser } 157e78f53d1SNikolas Klauser 158e78f53d1SNikolas Klauser template <random_access_range _RARange = const _Derived> 159e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const { 160e78f53d1SNikolas Klauser return ranges::begin(__derived())[__index]; 161e78f53d1SNikolas Klauser } 162e78f53d1SNikolas Klauser }; 163e78f53d1SNikolas Klauser 164e78f53d1SNikolas Klauser } // namespace ranges 165e78f53d1SNikolas Klauser 166e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 167e78f53d1SNikolas Klauser 168e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 169e78f53d1SNikolas Klauser 170*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___RANGES_VIEW_INTERFACE_H 171