Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/reverse_view.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_REVERSE_VIEW_H
11
#define _LIBCPP___RANGES_REVERSE_VIEW_H
12
13
#include <__concepts/constructible.h>
14
#include <__config>
15
#include <__iterator/concepts.h>
16
#include <__iterator/next.h>
17
#include <__iterator/reverse_iterator.h>
18
#include <__ranges/access.h>
19
#include <__ranges/all.h>
20
#include <__ranges/concepts.h>
21
#include <__ranges/enable_borrowed_range.h>
22
#include <__ranges/non_propagating_cache.h>
23
#include <__ranges/range_adaptor.h>
24
#include <__ranges/size.h>
25
#include <__ranges/subrange.h>
26
#include <__ranges/view_interface.h>
27
#include <__type_traits/conditional.h>
28
#include <__type_traits/remove_cvref.h>
29
#include <__utility/forward.h>
30
#include <__utility/move.h>
31
32
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
33
# pragma GCC system_header
34
#endif
35
36
_LIBCPP_PUSH_MACROS
37
#include <__undef_macros>
38
39
_LIBCPP_BEGIN_NAMESPACE_STD
40
41
#if _LIBCPP_STD_VER >= 20
42
43
namespace ranges {
44
template <view _View>
45
requires bidirectional_range<_View>
46
class reverse_view : public view_interface<reverse_view<_View>> {
47
// We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
48
// amortized O(1) begin() method.
49
static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>;
50
using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>;
51
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
52
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
53
54
public:
55
_LIBCPP_HIDE_FROM_ABI reverse_view()
56
requires default_initializable<_View>
57
= default;
58
59
_LIBCPP_HIDE_FROM_ABI constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {}
60
61
_LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
62
requires copy_constructible<_View>
63
{
64
return __base_;
65
}
66
67
_LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
68
69
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin() {
70
if constexpr (_UseCache)
71
if (__cached_begin_.__has_value())
72
return *__cached_begin_;
73
74
auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
75
if constexpr (_UseCache)
76
__cached_begin_.__emplace(__tmp);
77
return __tmp;
78
}
79
80
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin()
81
requires common_range<_View>
82
{
83
return std::make_reverse_iterator(ranges::end(__base_));
84
}
85
86
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
87
requires common_range<const _View>
88
{
89
return std::make_reverse_iterator(ranges::end(__base_));
90
}
91
92
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> end() {
93
return std::make_reverse_iterator(ranges::begin(__base_));
94
}
95
96
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
97
requires common_range<const _View>
98
{
99
return std::make_reverse_iterator(ranges::begin(__base_));
100
}
101
102
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
103
requires sized_range<_View>
104
{
105
return ranges::size(__base_);
106
}
107
108
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
109
requires sized_range<const _View>
110
{
111
return ranges::size(__base_);
112
}
113
};
114
115
template <class _Range>
116
reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
117
118
template <class _Tp>
119
inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> = enable_borrowed_range<_Tp>;
120
121
namespace views {
122
namespace __reverse {
123
template <class _Tp>
124
inline constexpr bool __is_reverse_view = false;
125
126
template <class _Tp>
127
inline constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
128
129
template <class _Tp>
130
inline constexpr bool __is_sized_reverse_subrange = false;
131
132
template <class _Iter>
133
inline constexpr bool
134
__is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> =
135
true;
136
137
template <class _Tp>
138
inline constexpr bool __is_unsized_reverse_subrange = false;
139
140
template <class _Iter, subrange_kind _Kind>
141
inline constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> =
142
_Kind == subrange_kind::unsized;
143
144
template <class _Tp>
145
struct __unwrapped_reverse_subrange {
146
using type =
147
void; // avoid SFINAE-ing out the overload below -- let the concept requirements do it for better diagnostics
148
};
149
150
template <class _Iter, subrange_kind _Kind>
151
struct __unwrapped_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> {
152
using type = subrange<_Iter, _Iter, _Kind>;
153
};
154
155
struct __fn : __range_adaptor_closure<__fn> {
156
template <class _Range>
157
requires __is_reverse_view<remove_cvref_t<_Range>>
158
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
159
noexcept(noexcept(std::forward<_Range>(__range).base())) -> decltype(std::forward<_Range>(__range).base()) {
160
return std::forward<_Range>(__range).base();
161
}
162
163
template <class _Range,
164
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
165
requires __is_sized_reverse_subrange<remove_cvref_t<_Range>>
166
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
167
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())))
168
-> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())) {
169
return _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size());
170
}
171
172
template <class _Range,
173
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
174
requires __is_unsized_reverse_subrange<remove_cvref_t<_Range>>
175
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
176
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base())))
177
-> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base())) {
178
return _UnwrappedSubrange(__range.end().base(), __range.begin().base());
179
}
180
181
template <class _Range>
182
requires(!__is_reverse_view<remove_cvref_t<_Range>> && !__is_sized_reverse_subrange<remove_cvref_t<_Range>> &&
183
!__is_unsized_reverse_subrange<remove_cvref_t<_Range>>)
184
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(noexcept(reverse_view{
185
std::forward<_Range>(__range)})) -> decltype(reverse_view{std::forward<_Range>(__range)}) {
186
return reverse_view{std::forward<_Range>(__range)};
187
}
188
};
189
} // namespace __reverse
190
191
inline namespace __cpo {
192
inline constexpr auto reverse = __reverse::__fn{};
193
} // namespace __cpo
194
} // namespace views
195
} // namespace ranges
196
197
#endif // _LIBCPP_STD_VER >= 20
198
199
_LIBCPP_END_NAMESPACE_STD
200
201
_LIBCPP_POP_MACROS
202
203
#endif // _LIBCPP___RANGES_REVERSE_VIEW_H
204
205