File indexing completed on 2026-05-03 08:14:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
0011 #define _LIBCPP___RANGES_VIEW_INTERFACE_H
0012
0013 #include <__assert>
0014 #include <__concepts/derived_from.h>
0015 #include <__concepts/same_as.h>
0016 #include <__config>
0017 #include <__iterator/concepts.h>
0018 #include <__iterator/iterator_traits.h>
0019 #include <__iterator/prev.h>
0020 #include <__memory/pointer_traits.h>
0021 #include <__ranges/access.h>
0022 #include <__ranges/concepts.h>
0023 #include <__ranges/empty.h>
0024 #include <__ranges/size.h>
0025 #include <__type_traits/is_class.h>
0026 #include <__type_traits/make_unsigned.h>
0027 #include <__type_traits/remove_cv.h>
0028
0029 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0030 # pragma GCC system_header
0031 #endif
0032
0033 _LIBCPP_BEGIN_NAMESPACE_STD
0034
0035 #if _LIBCPP_STD_VER >= 20
0036
0037 namespace ranges {
0038
0039 template <class _Derived>
0040 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
0041 class view_interface {
0042 _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept {
0043 static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
0044 return static_cast<_Derived&>(*this);
0045 }
0046
0047 _LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept {
0048 static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
0049 return static_cast<_Derived const&>(*this);
0050 }
0051
0052 public:
0053 template <class _D2 = _Derived>
0054 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
0055 requires sized_range<_D2> || forward_range<_D2>
0056 {
0057 if constexpr (sized_range<_D2>) {
0058 return ranges::size(__derived()) == 0;
0059 } else {
0060 return ranges::begin(__derived()) == ranges::end(__derived());
0061 }
0062 }
0063
0064 template <class _D2 = _Derived>
0065 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
0066 requires sized_range<const _D2> || forward_range<const _D2>
0067 {
0068 if constexpr (sized_range<const _D2>) {
0069 return ranges::size(__derived()) == 0;
0070 } else {
0071 return ranges::begin(__derived()) == ranges::end(__derived());
0072 }
0073 }
0074
0075 template <class _D2 = _Derived>
0076 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool()
0077 requires requires(_D2& __t) { ranges::empty(__t); }
0078 {
0079 return !ranges::empty(__derived());
0080 }
0081
0082 template <class _D2 = _Derived>
0083 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const
0084 requires requires(const _D2& __t) { ranges::empty(__t); }
0085 {
0086 return !ranges::empty(__derived());
0087 }
0088
0089 template <class _D2 = _Derived>
0090 _LIBCPP_HIDE_FROM_ABI constexpr auto data()
0091 requires contiguous_iterator<iterator_t<_D2>>
0092 {
0093 return std::to_address(ranges::begin(__derived()));
0094 }
0095
0096 template <class _D2 = _Derived>
0097 _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
0098 requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
0099 {
0100 return std::to_address(ranges::begin(__derived()));
0101 }
0102
0103 template <class _D2 = _Derived>
0104 _LIBCPP_HIDE_FROM_ABI constexpr auto size()
0105 requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
0106 {
0107 return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
0108 }
0109
0110 template <class _D2 = _Derived>
0111 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
0112 requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
0113 {
0114 return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
0115 }
0116
0117 template <class _D2 = _Derived>
0118 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
0119 requires forward_range<_D2>
0120 {
0121 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0122 !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
0123 return *ranges::begin(__derived());
0124 }
0125
0126 template <class _D2 = _Derived>
0127 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
0128 requires forward_range<const _D2>
0129 {
0130 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0131 !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
0132 return *ranges::begin(__derived());
0133 }
0134
0135 template <class _D2 = _Derived>
0136 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
0137 requires bidirectional_range<_D2> && common_range<_D2>
0138 {
0139 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0140 !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
0141 return *ranges::prev(ranges::end(__derived()));
0142 }
0143
0144 template <class _D2 = _Derived>
0145 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
0146 requires bidirectional_range<const _D2> && common_range<const _D2>
0147 {
0148 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
0149 !empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
0150 return *ranges::prev(ranges::end(__derived()));
0151 }
0152
0153 template <random_access_range _RARange = _Derived>
0154 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {
0155 return ranges::begin(__derived())[__index];
0156 }
0157
0158 template <random_access_range _RARange = const _Derived>
0159 _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
0160 return ranges::begin(__derived())[__index];
0161 }
0162 };
0163
0164 }
0165
0166 #endif
0167
0168 _LIBCPP_END_NAMESPACE_STD
0169
0170 #endif