Mercurial > hg > CbC > CbC_llvm
comparison libcxx/include/concepts @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
65 | 65 |
66 // [concept.constructible], concept constructible_from | 66 // [concept.constructible], concept constructible_from |
67 template<class T, class... Args> | 67 template<class T, class... Args> |
68 concept constructible_from = see below; | 68 concept constructible_from = see below; |
69 | 69 |
70 // [concept.defaultconstructible], concept default_constructible | 70 // [concept.default.init], concept default_initializable |
71 template<class T> | 71 template<class T> |
72 concept default_constructible = see below; | 72 concept default_initializable = see below; |
73 | 73 |
74 // [concept.moveconstructible], concept move_constructible | 74 // [concept.moveconstructible], concept move_constructible |
75 template<class T> | 75 template<class T> |
76 concept move_constructible = see below; | 76 concept move_constructible = see below; |
77 | 77 |
78 // [concept.copyconstructible], concept copy_constructible | 78 // [concept.copyconstructible], concept copy_constructible |
79 template<class T> | 79 template<class T> |
80 concept copy_constructible = see below; | 80 concept copy_constructible = see below; |
81 | |
82 // [concepts.compare], comparison concepts | |
83 // [concept.boolean], concept boolean | |
84 template<class B> | |
85 concept boolean = see below; | |
86 | 81 |
87 // [concept.equalitycomparable], concept equality_comparable | 82 // [concept.equalitycomparable], concept equality_comparable |
88 template<class T> | 83 template<class T> |
89 concept equality_comparable = see below; | 84 concept equality_comparable = see below; |
90 template<class T, class U> | 85 template<class T, class U> |
133 } | 128 } |
134 | 129 |
135 */ | 130 */ |
136 | 131 |
137 #include <__config> | 132 #include <__config> |
133 #include <__functional_base> | |
138 #include <type_traits> | 134 #include <type_traits> |
135 #include <utility> | |
139 #include <version> | 136 #include <version> |
140 | 137 |
141 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | 138 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
142 #pragma GCC system_header | 139 #pragma GCC system_header |
143 #endif | 140 #endif |
145 _LIBCPP_PUSH_MACROS | 142 _LIBCPP_PUSH_MACROS |
146 #include <__undef_macros> | 143 #include <__undef_macros> |
147 | 144 |
148 _LIBCPP_BEGIN_NAMESPACE_STD | 145 _LIBCPP_BEGIN_NAMESPACE_STD |
149 | 146 |
150 #if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L | 147 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) |
151 | 148 |
152 // [concept.same] | 149 // [concept.same] |
153 | 150 |
154 template<class _Tp, class _Up> | 151 template<class _Tp, class _Up> |
155 concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; | 152 concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; |
156 | 153 |
157 template<class _Tp, class _Up> | 154 template<class _Tp, class _Up> |
158 concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; | 155 concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; |
159 | 156 |
160 #endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L | 157 // [concept.derived] |
158 template<class _Dp, class _Bp> | |
159 concept derived_from = | |
160 is_base_of_v<_Bp, _Dp> && | |
161 is_convertible_v<const volatile _Dp*, const volatile _Bp*>; | |
162 | |
163 // [concept.convertible] | |
164 template<class _From, class _To> | |
165 concept convertible_to = | |
166 is_convertible_v<_From, _To> && | |
167 requires(add_rvalue_reference_t<_From> (&__f)()) { | |
168 static_cast<_To>(__f()); | |
169 }; | |
170 | |
171 // [concept.commonref] | |
172 template<class _Tp, class _Up> | |
173 concept common_reference_with = | |
174 same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> && | |
175 convertible_to<_Tp, common_reference_t<_Tp, _Up>> && | |
176 convertible_to<_Up, common_reference_t<_Tp, _Up>>; | |
177 | |
178 // [concept.common] | |
179 template<class _Tp, class _Up> | |
180 concept common_with = | |
181 same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> && | |
182 requires { | |
183 static_cast<common_type_t<_Tp, _Up>>(declval<_Tp>()); | |
184 static_cast<common_type_t<_Tp, _Up>>(declval<_Up>()); | |
185 } && | |
186 common_reference_with< | |
187 add_lvalue_reference_t<const _Tp>, | |
188 add_lvalue_reference_t<const _Up>> && | |
189 common_reference_with< | |
190 add_lvalue_reference_t<common_type_t<_Tp, _Up>>, | |
191 common_reference_t< | |
192 add_lvalue_reference_t<const _Tp>, | |
193 add_lvalue_reference_t<const _Up>>>; | |
194 | |
195 // [concepts.arithmetic], arithmetic concepts | |
196 template<class _Tp> | |
197 concept integral = is_integral_v<_Tp>; | |
198 | |
199 template<class _Tp> | |
200 concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; | |
201 | |
202 template<class _Tp> | |
203 concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; | |
204 | |
205 template<class _Tp> | |
206 concept floating_point = is_floating_point_v<_Tp>; | |
207 | |
208 // [concept.assignable] | |
209 template<class _Lhs, class _Rhs> | |
210 concept assignable_from = | |
211 is_lvalue_reference_v<_Lhs> && | |
212 common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && | |
213 requires (_Lhs __lhs, _Rhs&& __rhs) { | |
214 { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; | |
215 }; | |
216 | |
217 // [concept.destructible] | |
218 | |
219 template<class _Tp> | |
220 concept destructible = is_nothrow_destructible_v<_Tp>; | |
221 | |
222 // [concept.constructible] | |
223 template<class _Tp, class... _Args> | |
224 concept constructible_from = | |
225 destructible<_Tp> && is_constructible_v<_Tp, _Args...>; | |
226 | |
227 // [concept.default.init] | |
228 | |
229 template<class _Tp> | |
230 concept __default_initializable = requires { ::new _Tp; }; | |
231 | |
232 template<class _Tp> | |
233 concept default_initializable = constructible_from<_Tp> && | |
234 requires { _Tp{}; } && __default_initializable<_Tp>; | |
235 | |
236 // [concept.moveconstructible] | |
237 template<class _Tp> | |
238 concept move_constructible = | |
239 constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; | |
240 | |
241 // [concept.copyconstructible] | |
242 template<class _Tp> | |
243 concept copy_constructible = | |
244 move_constructible<_Tp> && | |
245 constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && | |
246 constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && | |
247 constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; | |
248 | |
249 // Whether a type is a class type or enumeration type according to the Core wording. | |
250 template<class _Tp> | |
251 concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; | |
252 | |
253 // [concept.swappable] | |
254 namespace ranges::__swap { | |
255 // Deleted to inhibit ADL | |
256 template<class _Tp> | |
257 void swap(_Tp&, _Tp&) = delete; | |
258 | |
259 | |
260 // [1] | |
261 template<class _Tp, class _Up> | |
262 concept __unqualified_swappable_with = | |
263 (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) && | |
264 requires(_Tp&& __t, _Up&& __u) { | |
265 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
266 }; | |
267 | |
268 struct __fn; | |
269 | |
270 template<class _Tp, class _Up, size_t _Size> | |
271 concept __swappable_arrays = | |
272 !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && | |
273 extent_v<_Tp> == extent_v<_Up> && | |
274 requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { | |
275 __swap(__t[0], __u[0]); | |
276 }; | |
277 | |
278 template<class _Tp> | |
279 concept __exchangeable = | |
280 !__unqualified_swappable_with<_Tp&, _Tp&> && | |
281 move_constructible<_Tp> && | |
282 assignable_from<_Tp&, _Tp>; | |
283 | |
284 struct __fn { | |
285 // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... | |
286 // *The name `swap` is used here unqualified. | |
287 template<class _Tp, class _Up> | |
288 requires __unqualified_swappable_with<_Tp, _Up> | |
289 constexpr void operator()(_Tp&& __t, _Up&& __u) const | |
290 noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) | |
291 { | |
292 swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
293 } | |
294 | |
295 // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... | |
296 template<class _Tp, class _Up, size_t _Size> | |
297 requires __swappable_arrays<_Tp, _Up, _Size> | |
298 constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const | |
299 noexcept(noexcept((*this)(*__t, *__u))) | |
300 { | |
301 // TODO(cjdb): replace with `ranges::swap_ranges`. | |
302 for (size_t __i = 0; __i < _Size; ++__i) { | |
303 (*this)(__t[__i], __u[__i]); | |
304 } | |
305 } | |
306 | |
307 // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... | |
308 template<__exchangeable _Tp> | |
309 constexpr void operator()(_Tp& __x, _Tp& __y) const | |
310 noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) | |
311 { | |
312 __y = _VSTD::exchange(__x, _VSTD::move(__y)); | |
313 } | |
314 }; | |
315 } // namespace ranges::__swap | |
316 | |
317 namespace ranges::inline __cpo { | |
318 inline constexpr auto swap = __swap::__fn{}; | |
319 } // namespace ranges::__cpo | |
320 | |
321 template<class _Tp> | |
322 concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; | |
323 | |
324 template<class _Tp, class _Up> | |
325 concept swappable_with = | |
326 common_reference_with<_Tp, _Up> && | |
327 requires(_Tp&& __t, _Up&& __u) { | |
328 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); | |
329 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); | |
330 ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
331 ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); | |
332 }; | |
333 | |
334 // [concept.booleantestable] | |
335 template<class _Tp> | |
336 concept __boolean_testable_impl = convertible_to<_Tp, bool>; | |
337 | |
338 template<class _Tp> | |
339 concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { | |
340 { !std::forward<_Tp>(__t) } -> __boolean_testable_impl; | |
341 }; | |
342 | |
343 // [concept.equalitycomparable] | |
344 template<class _Tp, class _Up> | |
345 concept __weakly_equality_comparable_with = | |
346 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
347 { __t == __u } -> __boolean_testable; | |
348 { __t != __u } -> __boolean_testable; | |
349 { __u == __t } -> __boolean_testable; | |
350 { __u != __t } -> __boolean_testable; | |
351 }; | |
352 | |
353 template<class _Tp> | |
354 concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; | |
355 | |
356 template<class _Tp, class _Up> | |
357 concept equality_comparable_with = | |
358 equality_comparable<_Tp> && equality_comparable<_Up> && | |
359 common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && | |
360 equality_comparable< | |
361 common_reference_t< | |
362 __make_const_lvalue_ref<_Tp>, | |
363 __make_const_lvalue_ref<_Up>>> && | |
364 __weakly_equality_comparable_with<_Tp, _Up>; | |
365 | |
366 // [concept.totallyordered] | |
367 | |
368 template<class _Tp, class _Up> | |
369 concept __partially_ordered_with = | |
370 requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
371 { __t < __u } -> __boolean_testable; | |
372 { __t > __u } -> __boolean_testable; | |
373 { __t <= __u } -> __boolean_testable; | |
374 { __t >= __u } -> __boolean_testable; | |
375 { __u < __t } -> __boolean_testable; | |
376 { __u > __t } -> __boolean_testable; | |
377 { __u <= __t } -> __boolean_testable; | |
378 { __u >= __t } -> __boolean_testable; | |
379 }; | |
380 | |
381 template<class _Tp> | |
382 concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; | |
383 | |
384 template<class _Tp, class _Up> | |
385 concept totally_ordered_with = | |
386 totally_ordered<_Tp> && totally_ordered<_Up> && | |
387 equality_comparable_with<_Tp, _Up> && | |
388 totally_ordered< | |
389 common_reference_t< | |
390 __make_const_lvalue_ref<_Tp>, | |
391 __make_const_lvalue_ref<_Up>>> && | |
392 __partially_ordered_with<_Tp, _Up>; | |
393 | |
394 // [concepts.object] | |
395 template<class _Tp> | |
396 concept movable = | |
397 is_object_v<_Tp> && | |
398 move_constructible<_Tp> && | |
399 assignable_from<_Tp&, _Tp> && | |
400 swappable<_Tp>; | |
401 | |
402 template<class _Tp> | |
403 concept copyable = | |
404 copy_constructible<_Tp> && | |
405 movable<_Tp> && | |
406 assignable_from<_Tp&, _Tp&> && | |
407 assignable_from<_Tp&, const _Tp&> && | |
408 assignable_from<_Tp&, const _Tp>; | |
409 | |
410 template<class _Tp> | |
411 concept semiregular = copyable<_Tp> && default_initializable<_Tp>; | |
412 | |
413 template<class _Tp> | |
414 concept regular = semiregular<_Tp> && equality_comparable<_Tp>; | |
415 | |
416 // [concept.invocable] | |
417 template<class _Fn, class... _Args> | |
418 concept invocable = requires(_Fn&& __fn, _Args&&... __args) { | |
419 _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving | |
420 }; | |
421 | |
422 // [concept.regular.invocable] | |
423 template<class _Fn, class... _Args> | |
424 concept regular_invocable = invocable<_Fn, _Args...>; | |
425 | |
426 // [concept.predicate] | |
427 template<class _Fn, class... _Args> | |
428 concept predicate = | |
429 regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>; | |
430 | |
431 // [concept.relation] | |
432 template<class _Rp, class _Tp, class _Up> | |
433 concept relation = | |
434 predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && | |
435 predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; | |
436 | |
437 // [concept.equiv] | |
438 template<class _Rp, class _Tp, class _Up> | |
439 concept equivalence_relation = relation<_Rp, _Tp, _Up>; | |
440 | |
441 // [concept.strictweakorder] | |
442 template<class _Rp, class _Tp, class _Up> | |
443 concept strict_weak_order = relation<_Rp, _Tp, _Up>; | |
444 | |
445 template<class _Tp, class _Up> | |
446 concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; | |
447 | |
448 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) | |
161 | 449 |
162 _LIBCPP_END_NAMESPACE_STD | 450 _LIBCPP_END_NAMESPACE_STD |
163 | 451 |
164 _LIBCPP_POP_MACROS | 452 _LIBCPP_POP_MACROS |
165 | 453 |