|
17 | 17 | #include <__ranges/const_access.h>
|
18 | 18 | #include <__ranges/empty_view.h>
|
19 | 19 | #include <__ranges/range_adaptor.h>
|
| 20 | +#include <__ranges/ref_view.h> |
20 | 21 | #include <__ranges/size.h>
|
21 | 22 | #include <__ranges/view_interface.h>
|
22 | 23 | #include <__type_traits/is_specialization.h>
|
@@ -102,96 +103,138 @@ inline constexpr bool enable_borrowed_range<as_const_view<_Tp>> = enable_borrowe
|
102 | 103 | namespace views {
|
103 | 104 | namespace __as_const {
|
104 | 105 |
|
105 |
| -template <class _Tp> |
106 |
| -concept __has_type = requires { typename _Tp::type; }; |
| 106 | +template <class _Case> |
| 107 | +concept __case = requires { _Case::__impl; }; |
107 | 108 |
|
108 |
| -template <class _Tp> |
| 109 | +template <class _Range> |
| 110 | +struct __already_constant_case {}; |
| 111 | +template <class _Range> |
| 112 | + requires constant_range<all_t<_Range>> |
| 113 | +struct __already_constant_case<_Range> { |
| 114 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range& __range) |
| 115 | + noexcept(noexcept(views::all(std::forward<_Range>(__range)))) |
| 116 | + -> decltype(views::all(std::forward<_Range>(__range))) { |
| 117 | + return views::all(std::forward<_Range>(__range)); |
| 118 | + } |
| 119 | +}; |
| 120 | + |
| 121 | +template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
109 | 122 | struct __empty_view_case {};
|
110 |
| -template <class _Tp> |
111 |
| -struct __empty_view_case<empty_view<_Tp>> { |
112 |
| - using type = const _Tp; |
| 123 | +template <class _Range, class _XType> |
| 124 | + requires (!__case<__already_constant_case<_Range>>) |
| 125 | +struct __empty_view_case<_Range, empty_view<_XType>> { |
| 126 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range&) |
| 127 | + noexcept(noexcept(auto(views::empty<const _XType>))) |
| 128 | + -> decltype(auto(views::empty<const _XType>)) { |
| 129 | + return auto(views::empty<const _XType>); |
| 130 | + } |
113 | 131 | };
|
114 | 132 |
|
115 |
| -template <class _Tp> |
| 133 | +template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
116 | 134 | struct __span_case {};
|
117 |
| -template <class _Tp, size_t _Extent> |
118 |
| -struct __span_case<span<_Tp, _Extent>> { |
119 |
| - using type = span<const _Tp, _Extent>; |
| 135 | +template <class _Range, class _XType, size_t _Extent> |
| 136 | + requires (!__case<__already_constant_case<_Range>>) |
| 137 | +struct __span_case<_Range, span<_XType, _Extent>> { |
| 138 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range& __range) |
| 139 | + noexcept(noexcept(span<const _XType, _Extent>(std::forward<_Range>(__range)))) |
| 140 | + -> decltype(span<const _XType, _Extent>(std::forward<_Range>(__range))) { |
| 141 | + return span<const _XType, _Extent>(std::forward<_Range>(__range)); |
| 142 | + } |
120 | 143 | };
|
121 | 144 |
|
122 |
| -template <class _Tp> |
| 145 | +template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
123 | 146 | struct __ref_view_case {};
|
124 |
| -template <class _Tp> |
125 |
| - requires constant_range<const _Tp> |
126 |
| -struct __ref_view_case<ref_view<_Tp>> { |
127 |
| - using type = const _Tp&; |
| 147 | +template <class _Range, class _XType> |
| 148 | + requires (!__case<__already_constant_case<_Range>>) && constant_range<const _XType> |
| 149 | +struct __ref_view_case<_Range, ref_view<_XType>> { |
| 150 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range& __range) |
| 151 | + noexcept(noexcept(ref_view(static_cast<const _XType&>(std::forward<_Range>(__range).base())))) |
| 152 | + -> decltype(ref_view(static_cast<const _XType&>(std::forward<_Range>(__range).base()))) { |
| 153 | + return ref_view(static_cast<const _XType&>(std::forward<_Range>(__range).base())); |
| 154 | + } |
128 | 155 | };
|
129 | 156 |
|
130 |
| -template <class _Tp> |
| 157 | +template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
131 | 158 | struct __constant_range_case {};
|
132 |
| -template <class _Tp> |
133 |
| - requires constant_range<const _Tp> && (!view<_Tp>) |
134 |
| -struct __constant_range_case<_Tp> { |
135 |
| - using type = const _Tp&; |
| 159 | +template <class _Range, class _UType> |
| 160 | + requires(!__case<__already_constant_case<_Range>>) |
| 161 | + && (!__case<__empty_view_case<_Range>>) |
| 162 | + && (!__case<__span_case<_Range>>) |
| 163 | + && (!__case<__ref_view_case<_Range>>) |
| 164 | + && is_lvalue_reference_v<_Range> |
| 165 | + && constant_range<const _UType> |
| 166 | + && (!view<_UType>) |
| 167 | +struct __constant_range_case<_Range, _UType> { |
| 168 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range& __range) |
| 169 | + noexcept(noexcept(ref_view(static_cast<const _UType&>(std::forward<_Range>(__range))))) |
| 170 | + -> decltype(ref_view(static_cast<const _UType&>(std::forward<_Range>(__range)))) { |
| 171 | + return ref_view(static_cast<const _UType&>(std::forward<_Range>(__range))); |
| 172 | + } |
| 173 | +}; |
| 174 | + |
| 175 | +template <class _Range> |
| 176 | +struct __otherwise_case {}; |
| 177 | +template <class _Range> |
| 178 | + requires (!__case<__already_constant_case<_Range>>) |
| 179 | + && (!__case<__empty_view_case<_Range>>) |
| 180 | + && (!__case<__span_case<_Range>>) |
| 181 | + && (!__case<__ref_view_case<_Range>>) |
| 182 | + && (!__case<__constant_range_case<_Range>>) |
| 183 | +struct __otherwise_case<_Range> { |
| 184 | + _LIBCPP_HIDE_FROM_ABI static constexpr auto __impl(_Range& __range) |
| 185 | + noexcept(noexcept(as_const_view(std::forward<_Range>(__range)))) |
| 186 | + -> decltype(as_const_view(std::forward<_Range>(__range))) { |
| 187 | + return as_const_view(std::forward<_Range>(__range)); |
| 188 | + } |
136 | 189 | };
|
137 | 190 |
|
138 | 191 | struct __fn : __range_adaptor_closure<__fn> {
|
139 | 192 | // [range.as.const.overview]: the basic `constant_range` case
|
140 | 193 | template <class _Range>
|
141 |
| - requires constant_range<all_t<_Range>> |
142 | 194 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
|
143 |
| - operator()(_Range&& __range) noexcept(noexcept(views::all(std::forward<_Range>(__range)))) |
144 |
| - -> decltype(/*--------------------------*/ views::all(std::forward<_Range>(__range))) { |
145 |
| - return /*---------------------------------*/ views::all(std::forward<_Range>(__range)); |
| 195 | + operator()(_Range&& __range) noexcept(noexcept(__already_constant_case<_Range>::__impl(__range))) |
| 196 | + -> decltype(__already_constant_case<_Range>::__impl(__range)) { |
| 197 | + return __already_constant_case<_Range>::__impl(__range); |
146 | 198 | }
|
147 | 199 |
|
148 | 200 | // [range.as.const.overview]: the `empty_view` case
|
149 |
| - template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
150 |
| - requires(!constant_range<all_t<_Range>>) && __has_type<__empty_view_case<_UType>> |
| 201 | + template <class _Range> |
151 | 202 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
|
152 |
| - operator()(_Range&&) noexcept(noexcept(auto(views::empty<typename __empty_view_case<_UType>::type>))) |
153 |
| - -> decltype(/*------------------*/ auto(views::empty<typename __empty_view_case<_UType>::type>)) { |
154 |
| - return /*-------------------------*/ auto(views::empty<typename __empty_view_case<_UType>::type>); |
| 203 | + operator()(_Range&& __range) noexcept(noexcept(__empty_view_case<_Range>::__impl(__range))) |
| 204 | + -> decltype(__empty_view_case<_Range>::__impl(__range)) { |
| 205 | + return __empty_view_case<_Range>::__impl(__range); |
155 | 206 | }
|
156 | 207 |
|
157 | 208 | // [range.as.const.overview]: the `span` case
|
158 |
| - template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
159 |
| - requires(!constant_range<all_t<_Range>>) && __has_type<__span_case<_UType>> |
| 209 | + template <class _Range> |
160 | 210 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
|
161 |
| - operator()(_Range&& __range) noexcept(noexcept(typename __span_case<_UType>::type(std::forward<_UType>(__range)))) |
162 |
| - -> decltype(/*--------------------------*/ typename __span_case<_UType>::type(std::forward<_UType>(__range))) { |
163 |
| - return /*---------------------------------*/ typename __span_case<_UType>::type(std::forward<_UType>(__range)); |
| 211 | + operator()(_Range&& __range) noexcept(noexcept(__span_case<_Range>::__impl(__range))) |
| 212 | + -> decltype(__span_case<_Range>::__impl(__range)) { |
| 213 | + return __span_case<_Range>::__impl(__range); |
164 | 214 | }
|
165 | 215 |
|
166 | 216 | // [range.as.const.overview]: the `ref_view` case
|
167 |
| - template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
168 |
| - requires(!constant_range<all_t<_Range>>) && __has_type<__ref_view_case<_UType>> |
| 217 | + template <class _Range> |
169 | 218 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(
|
170 |
| - noexcept(ref_view(static_cast<typename __ref_view_case<_UType>::type>(__range.base())))) |
171 |
| - -> decltype(/*--------------------------*/ ref_view( |
172 |
| - static_cast<typename __ref_view_case<_UType>::type>(__range.base()))) { |
173 |
| - return /*---------------------------------*/ ref_view( |
174 |
| - static_cast<typename __ref_view_case<_UType>::type>(__range.base())); |
| 219 | + noexcept(__ref_view_case<_Range>::__impl(__range))) |
| 220 | + -> decltype(__ref_view_case<_Range>::__impl(__range)) { |
| 221 | + return __ref_view_case<_Range>::__impl(__range); |
175 | 222 | }
|
176 | 223 |
|
177 | 224 | // [range.as.const.overview]: the second `constant_range` case
|
178 |
| - template <class _Range, class _UType = std::remove_cvref_t<_Range>> |
179 |
| - requires(!constant_range<all_t<_Range>>) && is_lvalue_reference_v<_Range> && |
180 |
| - __has_type<__constant_range_case<_UType>> |
| 225 | + template <class _Range> |
181 | 226 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) noexcept(
|
182 |
| - noexcept(ref_view(static_cast<typename __constant_range_case<_UType>::type>(__range)))) |
183 |
| - -> decltype(/*--------------------------*/ ref_view( |
184 |
| - static_cast<typename __constant_range_case<_UType>::type>(__range))) { |
185 |
| - return /*---------------------------------*/ ref_view( |
186 |
| - static_cast<typename __constant_range_case<_UType>::type>(__range)); |
| 227 | + noexcept(__constant_range_case<_Range>::__impl(__range))) |
| 228 | + -> decltype(__constant_range_case<_Range>::__impl(__range)) { |
| 229 | + return __constant_range_case<_Range>::__impl(__range); |
187 | 230 | }
|
188 | 231 |
|
189 | 232 | // [range.as.const.overview]: otherwise
|
190 | 233 | template <class _Range>
|
191 |
| - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto |
192 |
| - operator()(_Range&& __range) noexcept(noexcept(as_const_view(std::forward<_Range>(__range)))) |
193 |
| - -> decltype(/*--------------------------*/ as_const_view(std::forward<_Range>(__range))) { |
194 |
| - return /*---------------------------------*/ as_const_view(std::forward<_Range>(__range)); |
| 234 | + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range) |
| 235 | + noexcept(noexcept(__otherwise_case<_Range>::__impl(__range))) |
| 236 | + -> decltype(__otherwise_case<_Range>::__impl(__range)) { |
| 237 | + return __otherwise_case<_Range>::__impl(__range); |
195 | 238 | }
|
196 | 239 | };
|
197 | 240 |
|
|
0 commit comments