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