-
Notifications
You must be signed in to change notification settings - Fork 47
/
concepts
executable file
·301 lines (245 loc) · 11.4 KB
/
concepts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
// concepts standard header (core)
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef _CONCEPTS_
#define _CONCEPTS_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#ifndef __cpp_lib_concepts
_EMIT_STL_WARNING(STL4038, "The contents of <concepts> are available only with C++20 concepts support.");
#else // ^^^ !defined(__cpp_lib_concepts) / defined(__cpp_lib_concepts) vvv
#include <type_traits>
#include <vcruntime_new.h>
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
_STD_BEGIN
// clang-format off
template <class _Ty1, class _Ty2>
concept _Same_impl = // Must be a distinct concept to provide symmetric subsumption for same_as
#ifdef __clang__
__is_same(_Ty1, _Ty2);
#else // ^^^ use intrinsic / no intrinsic vvv
is_same_v<_Ty1, _Ty2>;
#endif // ^^^ no intrinsic ^^^
_EXPORT_STD template <class _Ty1, class _Ty2>
concept same_as = _Same_impl<_Ty1, _Ty2> && _Same_impl<_Ty2, _Ty1>;
_EXPORT_STD template <class _Derived, class _Base>
concept derived_from = __is_base_of(_Base, _Derived)
&& __is_convertible_to(const volatile _Derived*, const volatile _Base*);
template <class _From, class _To>
concept _Implicitly_convertible_to = is_convertible_v<_From, _To>;
_EXPORT_STD template <class _Ty1, class _Ty2>
concept common_reference_with =
requires {
typename common_reference_t<_Ty1, _Ty2>;
typename common_reference_t<_Ty2, _Ty1>;
}
&& same_as<common_reference_t<_Ty1, _Ty2>, common_reference_t<_Ty2, _Ty1>>
&& convertible_to<_Ty1, common_reference_t<_Ty1, _Ty2>>
&& convertible_to<_Ty2, common_reference_t<_Ty1, _Ty2>>;
_EXPORT_STD template <class _Ty1, class _Ty2>
concept common_with =
requires {
typename common_type_t<_Ty1, _Ty2>;
typename common_type_t<_Ty2, _Ty1>;
}
&& same_as<common_type_t<_Ty1, _Ty2>, common_type_t<_Ty2, _Ty1>>
&& requires {
static_cast<common_type_t<_Ty1, _Ty2>>(_STD declval<_Ty1>());
static_cast<common_type_t<_Ty1, _Ty2>>(_STD declval<_Ty2>());
}
&& common_reference_with<add_lvalue_reference_t<const _Ty1>, add_lvalue_reference_t<const _Ty2>>
&& common_reference_with<add_lvalue_reference_t<common_type_t<_Ty1, _Ty2>>,
common_reference_t<add_lvalue_reference_t<const _Ty1>, add_lvalue_reference_t<const _Ty2>>>;
_EXPORT_STD template <class _Ty>
concept integral = is_integral_v<_Ty>;
_EXPORT_STD template <class _Ty>
concept signed_integral = integral<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0);
_EXPORT_STD template <class _Ty>
concept unsigned_integral = integral<_Ty> && !signed_integral<_Ty>;
_EXPORT_STD template <class _Ty>
concept floating_point = is_floating_point_v<_Ty>;
_EXPORT_STD template <class _LTy, class _RTy>
concept assignable_from = is_lvalue_reference_v<_LTy>
&& common_reference_with<const remove_reference_t<_LTy>&, const remove_reference_t<_RTy>&>
&& requires(_LTy _Left, _RTy&& _Right) {
{ _Left = static_cast<_RTy&&>(_Right) } -> same_as<_LTy>;
};
// swappable and swappable_with are defined below, since they depend on move_constructible.
_EXPORT_STD template <class _Ty>
concept destructible = __is_nothrow_destructible(_Ty);
_EXPORT_STD template <class _Ty, class... _ArgTys>
concept constructible_from = destructible<_Ty>
&& __is_constructible(_Ty, _ArgTys...);
_EXPORT_STD template <class _Ty>
concept default_initializable = constructible_from<_Ty>
&& requires {
_Ty{};
::new (static_cast<void*>(nullptr)) _Ty; // is-default-initializable<_Ty>
};
_EXPORT_STD template <class _Ty>
concept move_constructible = constructible_from<_Ty, _Ty> && convertible_to<_Ty, _Ty>;
template <class _Ty>
concept _Has_class_or_enum_type = __is_class(remove_reference_t<_Ty>) || __is_enum(remove_reference_t<_Ty>)
|| __is_union(remove_reference_t<_Ty>);
namespace ranges {
namespace _Swap {
template <class _Ty>
void swap(_Ty&, _Ty&) = delete;
template <class _Ty1, class _Ty2>
concept _Use_ADL_swap = (_Has_class_or_enum_type<_Ty1> || _Has_class_or_enum_type<_Ty2>)
&& requires(_Ty1&& __t, _Ty2&& __u) {
swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u)); // intentional ADL
};
struct _Cpo {
template <class _Ty1, class _Ty2>
requires _Use_ADL_swap<_Ty1, _Ty2>
constexpr void operator()(_Ty1&& __t, _Ty2&& __u) const
noexcept(noexcept(swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u)))) { // intentional ADL
swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u)); // intentional ADL
}
template <class _Ty>
requires (!_Use_ADL_swap<_Ty&, _Ty&> && move_constructible<_Ty> && assignable_from<_Ty&, _Ty>)
constexpr void operator()(_Ty& __x, _Ty& __y) const
noexcept(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) {
_Ty __tmp(static_cast<_Ty&&>(__x));
__x = static_cast<_Ty&&>(__y);
__y = static_cast<_Ty&&>(__tmp);
}
template <class _Ty1, class _Ty2, size_t _Size>
constexpr void operator()(_Ty1 (&__t)[_Size], _Ty2 (&__u)[_Size]) const
noexcept(noexcept((*this)(__t[0], __u[0])))
requires requires { (*this)(__t[0], __u[0]); } {
for (size_t __i = 0; __i < _Size; ++__i) {
(*this)(__t[__i], __u[__i]);
}
}
};
} // namespace _Swap
inline namespace _Cpos {
_EXPORT_STD inline constexpr _Swap::_Cpo swap;
}
} // namespace ranges
_EXPORT_STD template <class _Ty>
concept swappable = requires(_Ty& __x, _Ty& __y) {
_RANGES swap(__x, __y);
};
_EXPORT_STD template <class _Ty1, class _Ty2>
concept swappable_with = common_reference_with<_Ty1, _Ty2>
&& requires(_Ty1&& __t, _Ty2&& __u) {
_RANGES swap(static_cast<_Ty1&&>(__t), static_cast<_Ty1&&>(__t));
_RANGES swap(static_cast<_Ty2&&>(__u), static_cast<_Ty2&&>(__u));
_RANGES swap(static_cast<_Ty1&&>(__t), static_cast<_Ty2&&>(__u));
_RANGES swap(static_cast<_Ty2&&>(__u), static_cast<_Ty1&&>(__t));
};
_EXPORT_STD template <class _Ty>
concept copy_constructible = move_constructible<_Ty>
&& constructible_from<_Ty, _Ty&> && convertible_to<_Ty&, _Ty>
&& constructible_from<_Ty, const _Ty&> && convertible_to<const _Ty&, _Ty>
&& constructible_from<_Ty, const _Ty> && convertible_to<const _Ty, _Ty>;
template <class _Ty>
concept _Boolean_testable_impl = convertible_to<_Ty, bool>;
template <class _Ty>
concept _Boolean_testable = _Boolean_testable_impl<_Ty>
&& requires(_Ty&& __t) {
{ !static_cast<_Ty&&>(__t) } -> _Boolean_testable_impl;
};
template <class _Ty1, class _Ty2>
concept _Half_equality_comparable =
requires(const remove_reference_t<_Ty1>& __x, const remove_reference_t<_Ty2>& __y) {
{ __x == __y } -> _Boolean_testable;
{ __x != __y } -> _Boolean_testable;
};
template <class _Ty1, class _Ty2>
concept _Weakly_equality_comparable_with =
_Half_equality_comparable<_Ty1, _Ty2> && _Half_equality_comparable<_Ty2, _Ty1>;
_EXPORT_STD template <class _Ty>
concept equality_comparable = _Half_equality_comparable<_Ty, _Ty>;
#if _HAS_CXX23
template <class _Ty1, class _Ty2, class _Ref = common_reference_t<const _Ty1&, const _Ty2&>>
concept _Comparison_common_type_with_impl =
same_as<_Ref, common_reference_t<const _Ty2&, const _Ty1&>>
&& requires {
requires convertible_to<const _Ty1&, const _Ref&> || convertible_to<_Ty1, const _Ref&>;
requires convertible_to<const _Ty2&, const _Ref&> || convertible_to<_Ty2, const _Ref&>;
};
template <class _Ty1, class _Ty2>
concept _Comparison_common_type_with = _Comparison_common_type_with_impl<remove_cvref_t<_Ty1>, remove_cvref_t<_Ty2>>;
#endif // _HAS_CXX23
_EXPORT_STD template <class _Ty1, class _Ty2>
concept equality_comparable_with = equality_comparable<_Ty1> && equality_comparable<_Ty2>
#if _HAS_CXX23
&& _Comparison_common_type_with<_Ty1, _Ty2>
#else // ^^^ C++23 / C++20 vvv
&& common_reference_with<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>
#endif // C++20
&& equality_comparable<common_reference_t<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>>
&& _Weakly_equality_comparable_with<_Ty1, _Ty2>;
template <class _Ty1, class _Ty2>
concept _Half_ordered = requires(const remove_reference_t<_Ty1>& __t, const remove_reference_t<_Ty2>& __u) {
{ __t < __u } -> _Boolean_testable;
{ __t > __u } -> _Boolean_testable;
{ __t <= __u } -> _Boolean_testable;
{ __t >= __u } -> _Boolean_testable;
};
template <class _Ty1, class _Ty2>
concept _Partially_ordered_with = _Half_ordered<_Ty1, _Ty2> && _Half_ordered<_Ty2, _Ty1>;
_EXPORT_STD template <class _Ty>
concept totally_ordered = equality_comparable<_Ty> && _Half_ordered<_Ty, _Ty>;
_EXPORT_STD template <class _Ty1, class _Ty2>
concept totally_ordered_with = totally_ordered<_Ty1> && totally_ordered<_Ty2>
&& equality_comparable_with<_Ty1, _Ty2>
&& totally_ordered<common_reference_t<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>>
&& _Partially_ordered_with<_Ty1, _Ty2>;
_EXPORT_STD template <class _Ty>
concept movable = is_object_v<_Ty>
&& move_constructible<_Ty>
&& assignable_from<_Ty&, _Ty>
&& swappable<_Ty>;
_EXPORT_STD template <class _Ty>
concept copyable = copy_constructible<_Ty>
&& movable<_Ty>
&& assignable_from<_Ty&, _Ty&>
&& assignable_from<_Ty&, const _Ty&>
&& assignable_from<_Ty&, const _Ty>;
_EXPORT_STD template <class _Ty>
concept semiregular = copyable<_Ty> && default_initializable<_Ty>;
_EXPORT_STD template <class _Ty>
concept regular = semiregular<_Ty> && equality_comparable<_Ty>;
_EXPORT_STD template <class _FTy, class... _ArgTys>
concept invocable = requires(_FTy&& _Fn, _ArgTys&&... _Args) {
_STD invoke(static_cast<_FTy&&>(_Fn), static_cast<_ArgTys&&>(_Args)...);
};
_EXPORT_STD template <class _FTy, class... _ArgTys>
concept regular_invocable = invocable<_FTy, _ArgTys...>;
_EXPORT_STD template <class _FTy, class... _ArgTys>
concept predicate = regular_invocable<_FTy, _ArgTys...>
&& _Boolean_testable<invoke_result_t<_FTy, _ArgTys...>>;
_EXPORT_STD template <class _FTy, class _Ty1, class _Ty2>
concept relation =
predicate<_FTy, _Ty1, _Ty1>
&& predicate<_FTy, _Ty2, _Ty2>
&& predicate<_FTy, _Ty1, _Ty2>
&& predicate<_FTy, _Ty2, _Ty1>;
_EXPORT_STD template <class _FTy, class _Ty1, class _Ty2>
concept equivalence_relation = relation<_FTy, _Ty1, _Ty2>;
_EXPORT_STD template <class _FTy, class _Ty1, class _Ty2>
concept strict_weak_order = relation<_FTy, _Ty1, _Ty2>;
// clang-format on
template <class _Ty>
struct _Choice_t {
_Ty _Strategy = _Ty{};
bool _No_throw = false;
};
_STD_END
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // defined(__cpp_lib_concepts)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _CONCEPTS_