xref: /freebsd-src/contrib/llvm-project/libcxx/include/__ranges/view_interface.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
24*0fca6ea1SDimitry Andric #include <__ranges/size.h>
25bdd1243dSDimitry Andric #include <__type_traits/is_class.h>
26bdd1243dSDimitry Andric #include <__type_traits/make_unsigned.h>
27bdd1243dSDimitry Andric #include <__type_traits/remove_cv.h>
28fe6060f1SDimitry Andric 
29fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30fe6060f1SDimitry Andric #  pragma GCC system_header
31fe6060f1SDimitry Andric #endif
32fe6060f1SDimitry Andric 
33fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
34fe6060f1SDimitry Andric 
3506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
36fe6060f1SDimitry Andric 
37fe6060f1SDimitry Andric namespace ranges {
38fe6060f1SDimitry Andric 
39fe6060f1SDimitry Andric template <class _Derived>
40fe6060f1SDimitry Andric   requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
4104eeddc0SDimitry Andric class view_interface {
42cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept {
43349cc55cSDimitry Andric     static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
44fe6060f1SDimitry Andric     return static_cast<_Derived&>(*this);
45fe6060f1SDimitry Andric   }
46fe6060f1SDimitry Andric 
47cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept {
48349cc55cSDimitry Andric     static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
49fe6060f1SDimitry Andric     return static_cast<_Derived const&>(*this);
50fe6060f1SDimitry Andric   }
51fe6060f1SDimitry Andric 
52fe6060f1SDimitry Andric public:
53fe6060f1SDimitry Andric   template <class _D2 = _Derived>
54fe6060f1SDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
55*0fca6ea1SDimitry Andric     requires sized_range<_D2> || forward_range<_D2>
56fe6060f1SDimitry Andric   {
57*0fca6ea1SDimitry Andric     if constexpr (sized_range<_D2>) {
58*0fca6ea1SDimitry Andric       return ranges::size(__derived()) == 0;
59*0fca6ea1SDimitry Andric     } else {
60fe6060f1SDimitry Andric       return ranges::begin(__derived()) == ranges::end(__derived());
61fe6060f1SDimitry Andric     }
62*0fca6ea1SDimitry Andric   }
63fe6060f1SDimitry Andric 
64fe6060f1SDimitry Andric   template <class _D2 = _Derived>
65fe6060f1SDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
66*0fca6ea1SDimitry Andric     requires sized_range<const _D2> || forward_range<const _D2>
67fe6060f1SDimitry Andric   {
68*0fca6ea1SDimitry Andric     if constexpr (sized_range<const _D2>) {
69*0fca6ea1SDimitry Andric       return ranges::size(__derived()) == 0;
70*0fca6ea1SDimitry Andric     } else {
71fe6060f1SDimitry Andric       return ranges::begin(__derived()) == ranges::end(__derived());
72fe6060f1SDimitry Andric     }
73*0fca6ea1SDimitry Andric   }
74fe6060f1SDimitry Andric 
75fe6060f1SDimitry Andric   template <class _D2 = _Derived>
76cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool()
7781ad6265SDimitry Andric     requires requires(_D2& __t) { ranges::empty(__t); }
78fe6060f1SDimitry Andric   {
79fe6060f1SDimitry Andric     return !ranges::empty(__derived());
80fe6060f1SDimitry Andric   }
81fe6060f1SDimitry Andric 
82fe6060f1SDimitry Andric   template <class _D2 = _Derived>
83cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const
8481ad6265SDimitry Andric     requires requires(const _D2& __t) { ranges::empty(__t); }
85fe6060f1SDimitry Andric   {
86fe6060f1SDimitry Andric     return !ranges::empty(__derived());
87fe6060f1SDimitry Andric   }
88fe6060f1SDimitry Andric 
89fe6060f1SDimitry Andric   template <class _D2 = _Derived>
90cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto data()
91fe6060f1SDimitry Andric     requires contiguous_iterator<iterator_t<_D2>>
92fe6060f1SDimitry Andric   {
9381ad6265SDimitry Andric     return std::to_address(ranges::begin(__derived()));
94fe6060f1SDimitry Andric   }
95fe6060f1SDimitry Andric 
96fe6060f1SDimitry Andric   template <class _D2 = _Derived>
97cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto data() const
98fe6060f1SDimitry Andric     requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
99fe6060f1SDimitry Andric   {
10081ad6265SDimitry Andric     return std::to_address(ranges::begin(__derived()));
101fe6060f1SDimitry Andric   }
102fe6060f1SDimitry Andric 
103fe6060f1SDimitry Andric   template <class _D2 = _Derived>
104cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto size()
10581ad6265SDimitry Andric     requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
106fe6060f1SDimitry Andric   {
107bdd1243dSDimitry Andric     return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
108fe6060f1SDimitry Andric   }
109fe6060f1SDimitry Andric 
110fe6060f1SDimitry Andric   template <class _D2 = _Derived>
111cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
11281ad6265SDimitry Andric     requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
113fe6060f1SDimitry Andric   {
114bdd1243dSDimitry Andric     return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
115fe6060f1SDimitry Andric   }
116fe6060f1SDimitry Andric 
117fe6060f1SDimitry Andric   template <class _D2 = _Derived>
118cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
119fe6060f1SDimitry Andric     requires forward_range<_D2>
120fe6060f1SDimitry Andric   {
121cb14a3feSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
122cb14a3feSDimitry 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>
127cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
128fe6060f1SDimitry Andric     requires forward_range<const _D2>
129fe6060f1SDimitry Andric   {
130cb14a3feSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
131cb14a3feSDimitry Andric         !empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
132fe6060f1SDimitry Andric     return *ranges::begin(__derived());
133fe6060f1SDimitry Andric   }
134fe6060f1SDimitry Andric 
135fe6060f1SDimitry Andric   template <class _D2 = _Derived>
136cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
137fe6060f1SDimitry Andric     requires bidirectional_range<_D2> && common_range<_D2>
138fe6060f1SDimitry Andric   {
139cb14a3feSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
140cb14a3feSDimitry 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 <class _D2 = _Derived>
145cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
146fe6060f1SDimitry Andric     requires bidirectional_range<const _D2> && common_range<const _D2>
147fe6060f1SDimitry Andric   {
148cb14a3feSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
149cb14a3feSDimitry Andric         !empty(), "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>
154cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {
155fe6060f1SDimitry Andric     return ranges::begin(__derived())[__index];
156fe6060f1SDimitry Andric   }
157fe6060f1SDimitry Andric 
158fe6060f1SDimitry Andric   template <random_access_range _RARange = const _Derived>
159cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
160fe6060f1SDimitry Andric     return ranges::begin(__derived())[__index];
161fe6060f1SDimitry Andric   }
162fe6060f1SDimitry Andric };
163fe6060f1SDimitry Andric 
1641fd87a68SDimitry Andric } // namespace ranges
165fe6060f1SDimitry Andric 
16606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
167fe6060f1SDimitry Andric 
168fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
169fe6060f1SDimitry Andric 
170fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_VIEW_INTERFACE_H
171