1 /// \file
2 //  CPP, the Concepts PreProcessor library
3 //
4 //  Copyright Eric Niebler 2018-present
5 //  Copyright (c) 2018-present, Facebook, Inc.
6 //  Copyright (c) 2020-present, Google LLC.
7 //
8 //  Use, modification and distribution is subject to the
9 //  Boost Software License, Version 1.0. (See accompanying
10 //  file LICENSE_1_0.txt or copy at
11 //  http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // This source code is licensed under the MIT license found in the
14 // LICENSE file in the root directory of this source tree.
15 //
16 // Project home: https://github.com/ericniebler/range-v3
17 //
18 
19 #ifndef CPP_CONCEPTS_HPP
20 #define CPP_CONCEPTS_HPP
21 
22 // clang-format off
23 
24 #include <initializer_list>
25 #include <utility>
26 #include <type_traits>
27 #include <concepts/swap.hpp>
28 #include <concepts/type_traits.hpp>
29 
30 // Disable buggy clang compatibility warning about "requires" and "concept" being
31 // C++20 keywords.
32 // https://bugs.llvm.org/show_bug.cgi?id=43708
33 #if defined(__clang__) && __cplusplus <= 201703L
34 #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                                \
35     CPP_DIAGNOSTIC_PUSH                                                                 \
36     CPP_DIAGNOSTIC_IGNORE_CPP2A_COMPAT
37 
38 #define CPP_PP_IGNORE_CXX2A_COMPAT_END                                                  \
39     CPP_DIAGNOSTIC_POP
40 
41 #else
42 #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN
43 #define CPP_PP_IGNORE_CXX2A_COMPAT_END
44 #endif
45 
46 #if defined(_MSC_VER) && !defined(__clang__)
47 #define CPP_WORKAROUND_MSVC_779763 // FATAL_UNREACHABLE calling constexpr function via template parameter
48 #define CPP_WORKAROUND_MSVC_784772 // Failure to invoke *explicit* bool conversion in a constant expression
49 #endif
50 
51 #if !defined(CPP_CXX_CONCEPTS)
52 #ifdef CPP_DOXYGEN_INVOKED
53 #define CPP_CXX_CONCEPTS 201800L
54 #elif defined(__cpp_concepts) && __cpp_concepts > 0
55 // gcc-6 concepts are too buggy to use
56 #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 7
57 #define CPP_CXX_CONCEPTS __cpp_concepts
58 #else
59 #define CPP_CXX_CONCEPTS 0L
60 #endif
61 #else
62 #define CPP_CXX_CONCEPTS 0L
63 #endif
64 #endif
65 
66 #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
67 #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
68 
69 #define CPP_PP_EVAL_(X, ARGS) X ARGS
70 #define CPP_PP_EVAL(X, ...) CPP_PP_EVAL_(X, (__VA_ARGS__))
71 
72 #define CPP_PP_EVAL2_(X, ARGS) X ARGS
73 #define CPP_PP_EVAL2(X, ...) CPP_PP_EVAL2_(X, (__VA_ARGS__))
74 
75 #define CPP_PP_EXPAND(...) __VA_ARGS__
76 #define CPP_PP_EAT(...)
77 
78 #define CPP_PP_FIRST(LIST) CPP_PP_FIRST_ LIST
79 #define CPP_PP_FIRST_(...) __VA_ARGS__ CPP_PP_EAT
80 
81 #define CPP_PP_SECOND(LIST) CPP_PP_SECOND_ LIST
82 #define CPP_PP_SECOND_(...) CPP_PP_EXPAND
83 
84 #define CPP_PP_CHECK(...) CPP_PP_EXPAND(CPP_PP_CHECK_N(__VA_ARGS__, 0,))
85 #define CPP_PP_CHECK_N(x, n, ...) n
86 #define CPP_PP_PROBE(x) x, 1,
87 #define CPP_PP_PROBE_N(x, n) x, n,
88 
89 #define CPP_PP_IS_PAREN(x) CPP_PP_CHECK(CPP_PP_IS_PAREN_PROBE x)
90 #define CPP_PP_IS_PAREN_PROBE(...) CPP_PP_PROBE(~)
91 
92 // CPP_CXX_VA_OPT
93 #ifndef CPP_CXX_VA_OPT
94 #if __cplusplus > 201703L
95 #define CPP_CXX_VA_OPT_(...) CPP_PP_CHECK(__VA_OPT__(,) 1)
96 #define CPP_CXX_VA_OPT CPP_CXX_VA_OPT_(~)
97 #else
98 #define CPP_CXX_VA_OPT 0
99 #endif
100 #endif // CPP_CXX_VA_OPT
101 
102 // The final CPP_PP_EXPAND here is to avoid
103 // https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
104 #define CPP_PP_COUNT(...)                                                       \
105     CPP_PP_EXPAND(CPP_PP_COUNT_(__VA_ARGS__,                                    \
106         50, 49, 48, 47, 46, 45, 44, 43, 42, 41,                                 \
107         40, 39, 38, 37, 36, 35, 34, 33, 32, 31,                                 \
108         30, 29, 28, 27, 26, 25, 24, 23, 22, 21,                                 \
109         20, 19, 18, 17, 16, 15, 14, 13, 12, 11,                                 \
110         10, 9, 8, 7, 6, 5, 4, 3, 2, 1,))
111 
112 #define CPP_PP_COUNT_(                                                          \
113     _01, _02, _03, _04, _05, _06, _07, _08, _09, _10,                           \
114     _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,                           \
115     _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,                           \
116     _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,                           \
117     _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, N, ...)                   \
118     N
119 
120 #define CPP_PP_IIF(BIT) CPP_PP_CAT_(CPP_PP_IIF_, BIT)
121 #define CPP_PP_IIF_0(TRUE, ...) __VA_ARGS__
122 #define CPP_PP_IIF_1(TRUE, ...) TRUE
123 
124 #define CPP_PP_LPAREN (
125 #define CPP_PP_RPAREN )
126 
127 #define CPP_PP_NOT(BIT) CPP_PP_CAT_(CPP_PP_NOT_, BIT)
128 #define CPP_PP_NOT_0 1
129 #define CPP_PP_NOT_1 0
130 
131 #define CPP_PP_EMPTY()
132 #define CPP_PP_COMMA() ,
133 #define CPP_PP_LBRACE() {
134 #define CPP_PP_RBRACE() }
135 #define CPP_PP_COMMA_IIF(X)                                                     \
136     CPP_PP_IIF(X)(CPP_PP_EMPTY, CPP_PP_COMMA)()
137 
138 #define CPP_PP_FOR_EACH(M, ...)                                                 \
139     CPP_PP_FOR_EACH_N(CPP_PP_COUNT(__VA_ARGS__), M, __VA_ARGS__)
140 #define CPP_PP_FOR_EACH_N(N, M, ...)                                            \
141     CPP_PP_CAT(CPP_PP_FOR_EACH_, N)(M, __VA_ARGS__)
142 #define CPP_PP_FOR_EACH_1(M, _1)                                                \
143     M(_1)
144 #define CPP_PP_FOR_EACH_2(M, _1, _2)                                            \
145     M(_1), M(_2)
146 #define CPP_PP_FOR_EACH_3(M, _1, _2, _3)                                        \
147     M(_1), M(_2), M(_3)
148 #define CPP_PP_FOR_EACH_4(M, _1, _2, _3, _4)                                    \
149     M(_1), M(_2), M(_3), M(_4)
150 #define CPP_PP_FOR_EACH_5(M, _1, _2, _3, _4, _5)                                \
151     M(_1), M(_2), M(_3), M(_4), M(_5)
152 #define CPP_PP_FOR_EACH_6(M, _1, _2, _3, _4, _5, _6)                            \
153     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6)
154 #define CPP_PP_FOR_EACH_7(M, _1, _2, _3, _4, _5, _6, _7)                        \
155     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6), M(_7)
156 #define CPP_PP_FOR_EACH_8(M, _1, _2, _3, _4, _5, _6, _7, _8)                    \
157     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6), M(_7), M(_8)
158 
159 #define CPP_PP_PROBE_EMPTY_PROBE_CPP_PP_PROBE_EMPTY                             \
160     CPP_PP_PROBE(~)
161 
162 #define CPP_PP_PROBE_EMPTY()
163 #define CPP_PP_IS_NOT_EMPTY(...)                                                \
164     CPP_PP_EVAL(                                                                \
165         CPP_PP_CHECK,                                                           \
166         CPP_PP_CAT(                                                             \
167             CPP_PP_PROBE_EMPTY_PROBE_,                                          \
168             CPP_PP_PROBE_EMPTY __VA_ARGS__ ()))
169 
170 #if defined(_MSC_VER) && !defined(__clang__) && (__cplusplus <= 201703L)
171 #define CPP_BOOL(...) ::meta::bool_<__VA_ARGS__>::value
172 #define CPP_TRUE_FN                                                             \
173     !::concepts::detail::instance_<                                             \
174         decltype(CPP_true_fn(::concepts::detail::xNil{}))>
175 
176 #define CPP_NOT(...) (!CPP_BOOL(__VA_ARGS__))
177 #else
178 #define CPP_BOOL(...) __VA_ARGS__
179 #define CPP_TRUE_FN CPP_true_fn(::concepts::detail::xNil{})
180 #define CPP_NOT(...) (!(__VA_ARGS__))
181 #endif
182 
183 #define CPP_assert(...)                                                         \
184     static_assert(static_cast<bool>(__VA_ARGS__),                               \
185         "Concept assertion failed : " #__VA_ARGS__)
186 
187 #define CPP_assert_msg static_assert
188 
189 #if CPP_CXX_CONCEPTS || defined(CPP_DOXYGEN_INVOKED)
190 #define CPP_concept META_CONCEPT
191 #define CPP_and &&
192 
193 #else
194 #define CPP_concept CPP_INLINE_VAR constexpr bool
195 #define CPP_and CPP_and_sfinae
196 
197 #endif
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 // CPP_template
201 // Usage:
202 //   CPP_template(typename A, typename B)
203 //     (requires Concept1<A> CPP_and Concept2<B>)
204 //   void foo(A a, B b)
205 //   {}
206 #if CPP_CXX_CONCEPTS
207 #define CPP_template(...) template<__VA_ARGS__ CPP_TEMPLATE_AUX_
208 #define CPP_template_def CPP_template
209 #define CPP_member
210 #define CPP_ctor(TYPE) TYPE CPP_CTOR_IMPL_1_
211 
212 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED
213 /// INTERNAL ONLY
214 #define CPP_CTOR_IMPL_1_(...) (__VA_ARGS__) CPP_CTOR_IMPL_2_
215 #define CPP_CTOR_IMPL_2_(...) __VA_ARGS__ `
216 #else
217 /// INTERNAL ONLY
218 #define CPP_CTOR_IMPL_1_(...) (__VA_ARGS__) CPP_PP_EXPAND
219 #endif
220 
221 /// INTERNAL ONLY
222 #define CPP_TEMPLATE_AUX_(...)                                                  \
223     > CPP_PP_CAT(                                                               \
224         CPP_TEMPLATE_AUX_,                                                      \
225         CPP_TEMPLATE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__)
226 
227 /// INTERNAL ONLY
228 #define CPP_TEMPLATE_AUX_WHICH_(FIRST, ...)                                     \
229     CPP_PP_EVAL(                                                                \
230         CPP_PP_CHECK,                                                           \
231         CPP_PP_CAT(CPP_TEMPLATE_PROBE_CONCEPT_, FIRST))
232 
233 /// INTERNAL ONLY
234 #define CPP_TEMPLATE_PROBE_CONCEPT_concept                                      \
235     CPP_PP_PROBE(~)
236 
237 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED
238 // A template with a requires clause. Turn the requires clause into
239 // a Doxygen precondition block.
240 /// INTERNAL ONLY
241 #define CPP_TEMPLATE_AUX_0(...) __VA_ARGS__`
242 #define requires requires `
243 
244 #else
245 // A template with a requires clause
246 /// INTERNAL ONLY
247 #define CPP_TEMPLATE_AUX_0(...) __VA_ARGS__
248 #endif
249 
250 // A concept definition
251 /// INTERNAL ONLY
252 #define CPP_TEMPLATE_AUX_1(DECL, ...)                                           \
253     CPP_concept CPP_CONCEPT_NAME_(DECL) = __VA_ARGS__
254 
255 #define CPP_concept_ref(NAME, ...)                                              \
256     CPP_PP_CAT(NAME, _concept_)<__VA_ARGS__>
257 
258 #else // ^^^^ with concepts / without concepts vvvv
259 
260 #define CPP_template CPP_template_sfinae
261 #define CPP_template_def CPP_template_def_sfinae
262 #define CPP_member CPP_member_sfinae
263 #define CPP_ctor CPP_ctor_sfinae
264 #define CPP_concept_ref(NAME, ...)                                              \
265     (1u == sizeof(CPP_PP_CAT(NAME, _concept_)(                                  \
266         (::concepts::detail::tag<__VA_ARGS__>*)nullptr)))
267 
268 /// INTERNAL ONLY
269 #define CPP_TEMPLATE_AUX_ CPP_TEMPLATE_SFINAE_AUX_
270 
271 #endif
272 
273 #define CPP_template_sfinae(...)                                                \
274     CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                            \
275     template<__VA_ARGS__ CPP_TEMPLATE_SFINAE_AUX_
276 
277 /// INTERNAL ONLY
278 #define CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_concept                               \
279     CPP_PP_PROBE(~)
280 
281 /// INTERNAL ONLY
282 #define CPP_TEMPLATE_SFINAE_AUX_WHICH_(FIRST, ...)                              \
283     CPP_PP_EVAL(                                                                \
284         CPP_PP_CHECK,                                                           \
285         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_, FIRST))
286 
287 /// INTERNAL ONLY
288 #define CPP_TEMPLATE_SFINAE_AUX_(...)                                           \
289     CPP_PP_CAT(                                                                 \
290         CPP_TEMPLATE_SFINAE_AUX_,                                               \
291         CPP_TEMPLATE_SFINAE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__)
292 
293 // A template with a requires clause
294 /// INTERNAL ONLY
295 #define CPP_TEMPLATE_SFINAE_AUX_0(...) ,                                        \
296     bool CPP_true = true,                                                       \
297     std::enable_if_t<                                                           \
298         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) &&                  \
299         CPP_BOOL(CPP_true),                                                     \
300         int> = 0>                                                               \
301     CPP_PP_IGNORE_CXX2A_COMPAT_END
302 
303 // A concept definition
304 /// INTERNAL ONLY
305 #define CPP_TEMPLATE_SFINAE_AUX_1(DECL, ...) ,                                  \
306         bool CPP_true = true,                                                   \
307         std::enable_if_t<__VA_ARGS__ && CPP_BOOL(CPP_true), int> = 0>           \
308     auto CPP_CONCEPT_NAME_(DECL)(                                               \
309         ::concepts::detail::tag<CPP_CONCEPT_PARAMS_(DECL)>*)                    \
310         -> char(&)[1];                                                          \
311     auto CPP_CONCEPT_NAME_(DECL)(...) -> char(&)[2]                             \
312     CPP_PP_IGNORE_CXX2A_COMPAT_END
313 
314 /// INTERNAL ONLY
315 #define CPP_CONCEPT_NAME_(DECL)                                                 \
316     CPP_PP_EVAL(                                                                \
317         CPP_PP_CAT,                                                             \
318         CPP_PP_EVAL(CPP_PP_FIRST, CPP_EAT_CONCEPT_(DECL)), _concept_)
319 
320 /// INTERNAL ONLY
321 #define CPP_CONCEPT_PARAMS_(DECL)                                               \
322     CPP_PP_EVAL(CPP_PP_SECOND, CPP_EAT_CONCEPT_(DECL))
323 
324 /// INTERNAL ONLY
325 #define CPP_EAT_CONCEPT_(DECL)                                                  \
326     CPP_PP_CAT(CPP_EAT_CONCEPT_, DECL)
327 
328 /// INTERNAL ONLY
329 #define CPP_EAT_CONCEPT_concept
330 
331 #define CPP_and_sfinae                                                          \
332     && CPP_BOOL(CPP_true), int> = 0, std::enable_if_t<
333 
334 #define CPP_template_def_sfinae(...)                                            \
335     template<__VA_ARGS__ CPP_TEMPLATE_DEF_SFINAE_AUX_
336 
337 /// INTERNAL ONLY
338 #define CPP_TEMPLATE_DEF_SFINAE_AUX_(...) ,                                     \
339     bool CPP_true,                                                              \
340     std::enable_if_t<                                                           \
341         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) &&                  \
342         CPP_BOOL(CPP_true),                                                     \
343         int>>
344 
345 #define CPP_and_sfinae_def                                                      \
346     && CPP_BOOL(CPP_true), int>, std::enable_if_t<
347 
348 /// INTERNAL ONLY
349 #define CPP_TEMPLATE_SFINAE_AUX_3_requires
350 
351 #define CPP_member_sfinae                                                       \
352     CPP_broken_friend_member
353 
354 #define CPP_ctor_sfinae(TYPE)                                                   \
355     CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                            \
356     TYPE CPP_CTOR_SFINAE_IMPL_1_
357 
358 /// INTERNAL ONLY
359 #define CPP_CTOR_SFINAE_IMPL_1_(...)                                            \
360     (__VA_ARGS__                                                                \
361         CPP_PP_COMMA_IIF(                                                       \
362             CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__)))                       \
363     CPP_CTOR_SFINAE_REQUIRES
364 
365 /// INTERNAL ONLY
366 #define CPP_CTOR_SFINAE_PROBE_NOEXCEPT_noexcept                                 \
367     CPP_PP_PROBE(~)
368 
369 /// INTERNAL ONLY
370 #define CPP_CTOR_SFINAE_MAKE_PROBE(FIRST,...)                                   \
371     CPP_PP_CAT(CPP_CTOR_SFINAE_PROBE_NOEXCEPT_, FIRST)
372 
373 /// INTERNAL ONLY
374 #define CPP_CTOR_SFINAE_REQUIRES(...)                                           \
375     CPP_PP_CAT(                                                                 \
376         CPP_CTOR_SFINAE_REQUIRES_,                                              \
377         CPP_PP_EVAL(                                                            \
378             CPP_PP_CHECK,                                                       \
379             CPP_CTOR_SFINAE_MAKE_PROBE(__VA_ARGS__,)))(__VA_ARGS__)
380 
381 // No noexcept-clause:
382 /// INTERNAL ONLY
383 #define CPP_CTOR_SFINAE_REQUIRES_0(...)                                         \
384     std::enable_if_t<                                                           \
385         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) && CPP_TRUE_FN,     \
386         ::concepts::detail::Nil                                                 \
387     > = {})                                                                     \
388     CPP_PP_IGNORE_CXX2A_COMPAT_END
389 
390 // Yes noexcept-clause:
391 /// INTERNAL ONLY
392 #define CPP_CTOR_SFINAE_REQUIRES_1(...)                                         \
393     std::enable_if_t<                                                           \
394         CPP_PP_EVAL(CPP_PP_CAT,                                                 \
395             CPP_TEMPLATE_SFINAE_AUX_3_,                                         \
396             CPP_PP_CAT(CPP_CTOR_SFINAE_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN,\
397         ::concepts::detail::Nil                                                 \
398     > = {})                                                                     \
399     CPP_PP_EXPAND(CPP_PP_CAT(CPP_CTOR_SFINAE_SHOW_NOEXCEPT_, __VA_ARGS__)))
400 
401 /// INTERNAL ONLY
402 #define CPP_CTOR_SFINAE_EAT_NOEXCEPT_noexcept(...)
403 
404 /// INTERNAL ONLY
405 #define CPP_CTOR_SFINAE_SHOW_NOEXCEPT_noexcept(...)                             \
406     noexcept(__VA_ARGS__)                                                       \
407     CPP_PP_IGNORE_CXX2A_COMPAT_END                                              \
408     CPP_PP_EAT CPP_PP_LPAREN
409 
410 #ifdef CPP_DOXYGEN_INVOKED
411 #define CPP_broken_friend_ret(...)                                              \
412     __VA_ARGS__ CPP_PP_EXPAND
413 
414 #else // ^^^ CPP_DOXYGEN_INVOKED / not CPP_DOXYGEN_INVOKED vvv
415 #define CPP_broken_friend_ret(...)                                              \
416     ::concepts::return_t<                                                       \
417         __VA_ARGS__,                                                            \
418         std::enable_if_t<CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_
419 
420 /// INTERNAL ONLY
421 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_(...)                                 \
422     CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(CPP_PP_CAT(                            \
423         CPP_TEMPLATE_AUX_2_, __VA_ARGS__))
424 
425 /// INTERNAL ONLY
426 #define CPP_TEMPLATE_AUX_2_requires
427 
428 /// INTERNAL ONLY
429 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(...)                               \
430     __VA_ARGS__ && CPP_TRUE_FN>>
431 
432 #ifdef CPP_WORKAROUND_MSVC_779763
433 #define CPP_broken_friend_member                                                \
434     template<::concepts::detail::CPP_true_t const &CPP_true_fn =                \
435         ::concepts::detail::CPP_true_fn_>
436 
437 #else // ^^^ workaround / no workaround vvv
438 #define CPP_broken_friend_member                                                \
439     template<bool (&CPP_true_fn)(::concepts::detail::xNil) =                    \
440         ::concepts::detail::CPP_true_fn>
441 
442 #endif // CPP_WORKAROUND_MSVC_779763
443 #endif
444 
445 #if CPP_CXX_CONCEPTS
446 #define CPP_requires(NAME, REQS)                                                \
447 CPP_concept CPP_PP_CAT(NAME, _requires_) =                                      \
448     CPP_PP_CAT(CPP_REQUIRES_, REQS)
449 
450 #define CPP_requires_ref(NAME, ...)                                             \
451     CPP_PP_CAT(NAME, _requires_)<__VA_ARGS__>
452 
453 /// INTERNAL ONLY
454 #define CPP_REQUIRES_requires(...)                                              \
455     requires(__VA_ARGS__) CPP_REQUIRES_AUX_
456 
457 /// INTERNAL ONLY
458 #define CPP_REQUIRES_AUX_(...)                                                  \
459     { __VA_ARGS__; }
460 
461 #else
462 #define CPP_requires(NAME, REQS)                                                \
463     auto CPP_PP_CAT(NAME, _requires_test_)                                      \
464     CPP_REQUIRES_AUX_(NAME, CPP_REQUIRES_ ## REQS)
465 
466 #define CPP_requires_ref(NAME, ...)                                             \
467     (1u == sizeof(CPP_PP_CAT(NAME, _requires_)(                                 \
468         (::concepts::detail::tag<__VA_ARGS__>*)nullptr)))
469 
470 /// INTERNAL ONLY
471 #define CPP_REQUIRES_requires(...)                                              \
472     (__VA_ARGS__) -> decltype CPP_REQUIRES_RETURN_
473 
474 /// INTERNAL ONLY
475 #define CPP_REQUIRES_RETURN_(...) (__VA_ARGS__, void()) {}
476 
477 /// INTERNAL ONLY
478 #define CPP_REQUIRES_AUX_(NAME, ...)                                            \
479     __VA_ARGS__                                                                 \
480     template<typename... As>                                                    \
481     auto CPP_PP_CAT(NAME, _requires_)(                                          \
482         ::concepts::detail::tag<As...> *,                                       \
483         decltype(&CPP_PP_CAT(NAME, _requires_test_)<As...>) = nullptr)          \
484         -> char(&)[1];                                                          \
485     auto CPP_PP_CAT(NAME, _requires_)(...) -> char(&)[2]
486 
487 #endif
488 
489 #if CPP_CXX_CONCEPTS
490 
491 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED
492 #define CPP_ret(...)                                                            \
493     __VA_ARGS__ CPP_RET_AUX_
494 #define CPP_RET_AUX_(...) __VA_ARGS__ `
495 #else
496 #define CPP_ret(...)                                                            \
497     __VA_ARGS__ CPP_PP_EXPAND
498 #endif
499 
500 #else
501 #define CPP_ret                                                                 \
502     CPP_broken_friend_ret
503 
504 #endif
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 // CPP_fun
508 #if CPP_CXX_CONCEPTS
509 
510 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED
511 /// INTERNAL ONLY
512 #define CPP_FUN_IMPL_1_(...)                                                    \
513     (__VA_ARGS__)                                                               \
514     CPP_FUN_IMPL_2_
515 #define CPP_FUN_IMPL_2_(...)                                                    \
516     __VA_ARGS__ `
517 #else
518 /// INTERNAL ONLY
519 #define CPP_FUN_IMPL_1_(...)                                                    \
520     (__VA_ARGS__)                                                               \
521     CPP_PP_EXPAND
522 #endif
523 
524 #define CPP_fun(X) X CPP_FUN_IMPL_1_
525 #else
526 /// INTERNAL ONLY
527 #define CPP_FUN_IMPL_1_(...)                                                    \
528     (__VA_ARGS__                                                                \
529         CPP_PP_COMMA_IIF(                                                       \
530             CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__)))                       \
531     CPP_FUN_IMPL_REQUIRES
532 
533 /// INTERNAL ONLY
534 #define CPP_FUN_IMPL_REQUIRES(...)                                              \
535     CPP_PP_EVAL2_(                                                              \
536         CPP_FUN_IMPL_SELECT_CONST_,                                             \
537         (__VA_ARGS__,)                                                          \
538     )(__VA_ARGS__)
539 
540 /// INTERNAL ONLY
541 #define CPP_FUN_IMPL_SELECT_CONST_(MAYBE_CONST, ...)                            \
542     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_,                                      \
543         CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT(                                   \
544             CPP_PP_PROBE_CONST_PROBE_, MAYBE_CONST)))
545 
546 /// INTERNAL ONLY
547 #define CPP_PP_PROBE_CONST_PROBE_const CPP_PP_PROBE(~)
548 
549 /// INTERNAL ONLY
550 #define CPP_FUN_IMPL_SELECT_CONST_1(...)                                        \
551     CPP_PP_EVAL(                                                                \
552         CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_,                                    \
553         CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__),)(                     \
554         CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__))
555 
556 /// INTERNAL ONLY
557 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...)                \
558     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_,                             \
559         CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT(                                  \
560             CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT)))
561 
562 /// INTERNAL ONLY
563 #define CPP_PP_PROBE_NOEXCEPT_PROBE_noexcept CPP_PP_PROBE(~)
564 
565 /// INTERNAL ONLY
566 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_0(...)                               \
567     std::enable_if_t<                                                           \
568         CPP_PP_EVAL(                                                            \
569             CPP_PP_CAT,                                                         \
570             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
571             __VA_ARGS__) && CPP_TRUE_FN,                                           \
572         ::concepts::detail::Nil                                                 \
573     > = {}) const                                                               \
574     CPP_PP_IGNORE_CXX2A_COMPAT_END
575 
576 /// INTERNAL ONLY
577 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_1(...)                               \
578     std::enable_if_t<                                                           \
579         CPP_PP_EVAL(                                                            \
580             CPP_PP_CAT,                                                         \
581             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
582             CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN,   \
583         ::concepts::detail::Nil                                                 \
584     > = {}) const                                                               \
585     CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__)))
586 
587 /// INTERNAL ONLY
588 #define CPP_FUN_IMPL_EAT_NOEXCEPT_noexcept(...)
589 
590 /// INTERNAL ONLY
591 #define CPP_FUN_IMPL_SHOW_NOEXCEPT_noexcept(...)                                \
592     noexcept(__VA_ARGS__) CPP_PP_IGNORE_CXX2A_COMPAT_END                        \
593     CPP_PP_EAT CPP_PP_LPAREN
594 
595 /// INTERNAL ONLY
596 #define CPP_FUN_IMPL_SELECT_CONST_0(...)                                        \
597     CPP_PP_EVAL_(                                                               \
598         CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_,                                 \
599         (__VA_ARGS__,)                                                          \
600     )(__VA_ARGS__)
601 
602 /// INTERNAL ONLY
603 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...)             \
604     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_,                          \
605           CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT(                                \
606             CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT)))
607 
608 /// INTERNAL ONLY
609 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_0(...)                            \
610     std::enable_if_t<                                                           \
611         CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, __VA_ARGS__) && CPP_TRUE_FN,        \
612         ::concepts::detail::Nil                                                 \
613     > = {})                                                                     \
614     CPP_PP_IGNORE_CXX2A_COMPAT_END
615 
616 /// INTERNAL ONLY
617 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_1(...)                            \
618     std::enable_if_t<                                                           \
619         CPP_PP_EVAL(                                                            \
620             CPP_PP_CAT,                                                         \
621             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
622             CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__)                 \
623         ) && CPP_TRUE_FN,                                                          \
624         ::concepts::detail::Nil                                                 \
625     > = {})                                                                     \
626     CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__)))
627 
628 /// INTERNAL ONLY
629 #define CPP_FUN_IMPL_EAT_CONST_const
630 
631 /// INTERNAL ONLY
632 #define CPP_FUN_IMPL_EAT_REQUIRES_requires
633 
634 ////////////////////////////////////////////////////////////////////////////////
635 // CPP_fun
636 // Usage:
637 //   template <typename A, typename B>
638 //   void CPP_fun(foo)(A a, B b)([const]opt [noexcept(true)]opt
639 //       requires Concept1<A> && Concept2<B>)
640 //   {}
641 //
642 // Note: This macro cannot be used when the last function argument is a
643 //       parameter pack.
644 #define CPP_fun(X) CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN X CPP_FUN_IMPL_1_
645 #endif
646 
647 ////////////////////////////////////////////////////////////////////////////////
648 // CPP_auto_fun
649 // Usage:
650 //   template <typename A, typename B>
651 //   auto CPP_auto_fun(foo)(A a, B b)([const]opt [noexcept(cond)]opt)opt
652 //   (
653 //       return a + b
654 //   )
655 #define CPP_auto_fun(X) X CPP_AUTO_FUN_IMPL_
656 
657 /// INTERNAL ONLY
658 #define CPP_AUTO_FUN_IMPL_(...) (__VA_ARGS__) CPP_AUTO_FUN_RETURNS_
659 
660 /// INTERNAL ONLY
661 #define CPP_AUTO_FUN_RETURNS_(...)                                              \
662     CPP_PP_EVAL2_(                                                              \
663         CPP_AUTO_FUN_SELECT_RETURNS_,                                           \
664         (__VA_ARGS__,)                                                          \
665     )(__VA_ARGS__)
666 
667 /// INTERNAL ONLY
668 #define CPP_AUTO_FUN_SELECT_RETURNS_(MAYBE_CONST, ...)                          \
669     CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_CONST_,                                     \
670         CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT(                                   \
671             CPP_PP_PROBE_CONST_MUTABLE_PROBE_, MAYBE_CONST)))
672 
673 /// INTERNAL ONLY
674 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_const CPP_PP_PROBE_N(~, 1)
675 
676 /// INTERNAL ONLY
677 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_mutable CPP_PP_PROBE_N(~, 2)
678 
679 /// INTERNAL ONLY
680 #define CPP_PP_EAT_MUTABLE_mutable
681 
682 /// INTERNAL ONLY
683 #define CPP_AUTO_FUN_RETURNS_CONST_2(...)                                       \
684     CPP_PP_CAT(CPP_PP_EAT_MUTABLE_, __VA_ARGS__) CPP_AUTO_FUN_RETURNS_CONST_0
685 
686 /// INTERNAL ONLY
687 #define CPP_AUTO_FUN_RETURNS_CONST_1(...)                                       \
688     __VA_ARGS__ CPP_AUTO_FUN_RETURNS_CONST_0
689 
690 /// INTERNAL ONLY
691 #define CPP_AUTO_FUN_RETURNS_CONST_0(...)                                       \
692     CPP_PP_EVAL(CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_,                                \
693         CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_, __VA_ARGS__))
694 
695 /// INTERNAL ONLY
696 #define CPP_AUTO_FUN_RETURNS_return
697 
698 #ifdef __cpp_guaranteed_copy_elision
699 /// INTERNAL ONLY
700 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...)                                    \
701     noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__)                    \
702     { return (__VA_ARGS__); }
703 
704 #else
705 /// INTERNAL ONLY
706 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...)                                    \
707     noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) ->                   \
708     decltype(__VA_ARGS__)                                                       \
709     { return (__VA_ARGS__); }
710 
711 #endif
712 
713 namespace concepts
714 {
715     template<bool B>
716     using bool_ = std::integral_constant<bool, B>;
717 
718 #if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
719     template<bool...Bs>
720     CPP_INLINE_VAR constexpr bool and_v = (Bs &&...);
721 
722     template<bool...Bs>
723     CPP_INLINE_VAR constexpr bool or_v = (Bs ||...);
724 #else
725     namespace detail
726     {
727         template<bool...>
728         struct bools;
729     } // namespace detail
730 
731     template<bool...Bs>
732     CPP_INLINE_VAR constexpr bool and_v =
733         META_IS_SAME(detail::bools<Bs..., true>, detail::bools<true, Bs...>);
734 
735     template<bool...Bs>
736     CPP_INLINE_VAR constexpr bool or_v =
737         !META_IS_SAME(detail::bools<Bs..., false>, detail::bools<false, Bs...>);
738 #endif
739 
740     template<typename>
741     struct return_t_
742     {
743         template<typename T>
744         using invoke = T;
745     };
746 
747     template<typename T, typename EnableIf>
748     using return_t = meta::invoke<return_t_<EnableIf>, T>;
749 
750     namespace detail
751     {
752         struct ignore
753         {
754             template<class... Args>
ignoreconcepts::detail::ignore755             constexpr ignore(Args&&...) noexcept {}
756         };
757 
758         template<class>
true_()759         constexpr bool true_()
760         {
761             return true;
762         }
763 
764         template<typename...>
765         struct tag;
766 
767         template<typename T>
768         CPP_INLINE_VAR constexpr T instance_ = T{};
769 
770         template<typename>
requires_()771         constexpr bool requires_()
772         {
773             return true;
774         }
775 
776         struct Nil
777         {};
778 
779 #ifdef CPP_WORKAROUND_MSVC_779763
780         enum class xNil {};
781 
782         struct CPP_true_t
783         {
operator ()concepts::detail::CPP_true_t784             constexpr bool operator()(Nil) const noexcept
785             {
786                 return true;
787             }
operator ()concepts::detail::CPP_true_t788             constexpr bool operator()(xNil) const noexcept
789             {
790                 return true;
791             }
792         };
793 
794         CPP_INLINE_VAR constexpr CPP_true_t CPP_true_fn_ {};
795 
CPP_true_fn(xNil)796         constexpr bool CPP_true_fn(xNil)
797         {
798             return true;
799         }
800 #else
801         using xNil = Nil;
802 #endif
803 
CPP_true_fn(Nil)804         constexpr bool CPP_true_fn(Nil)
805         {
806             return true;
807         }
808     } // namespace detail
809 
810 #if defined(__clang__) || defined(_MSC_VER)
811     template<bool B>
requires_()812     std::enable_if_t<B> requires_()
813     {}
814 #else
815     template<bool B>
816     CPP_INLINE_VAR constexpr std::enable_if_t<B, int> requires_ = 0;
817 #endif
818 
819     inline namespace defs
820     {
821         ////////////////////////////////////////////////////////////////////////
822         // Utility concepts
823         ////////////////////////////////////////////////////////////////////////
824 
825         template<bool B>
826         CPP_concept is_true = B;
827 
828         template<typename... Args>
829         CPP_concept type = true;
830 
831         template<class T, template<typename...> class Trait, typename... Args>
832         CPP_concept satisfies =
833             static_cast<bool>(Trait<T, Args...>::type::value);
834 
835         ////////////////////////////////////////////////////////////////////////
836         // Core language concepts
837         ////////////////////////////////////////////////////////////////////////
838 
839         template<typename A, typename B>
840         CPP_concept same_as =
841             META_IS_SAME(A, B) && META_IS_SAME(B, A);
842 
843         /// \cond
844         template<typename A, typename B>
845         CPP_concept not_same_as_ =
846             (!same_as<remove_cvref_t<A>, remove_cvref_t<B>>);
847 
848         // Workaround bug in the Standard Library:
849         // From cannot be an incomplete class type despite that
850         // is_convertible<X, Y> should be equivalent to is_convertible<X&&, Y>
851         // in such a case.
852         template<typename From, typename To>
853         CPP_concept implicitly_convertible_to =
854             std::is_convertible<std::add_rvalue_reference_t<From>, To>::value;
855 
856         template<typename From, typename To>
857         CPP_requires(explicitly_convertible_to_,
858             requires(From(*from)()) //
859             (
860                 static_cast<To>(from())
861             ));
862         template<typename From, typename To>
863         CPP_concept explicitly_convertible_to =
864             CPP_requires_ref(concepts::explicitly_convertible_to_, From, To);
865         /// \endcond
866 
867         template<typename From, typename To>
868         CPP_concept convertible_to =
869             implicitly_convertible_to<From, To> &&
870             explicitly_convertible_to<From, To>;
871 
872         CPP_template(typename T, typename U)(
873         concept (derived_from_)(T, U),
874             convertible_to<T const volatile *, U const volatile *>
875         );
876         template<typename T, typename U>
877         CPP_concept derived_from =
878             META_IS_BASE_OF(U, T) &&
879             CPP_concept_ref(concepts::derived_from_, T, U);
880 
881         CPP_template(typename T, typename U)(
882         concept (common_reference_with_)(T, U),
883             same_as<common_reference_t<T, U>, common_reference_t<U, T>> CPP_and
884             convertible_to<T, common_reference_t<T, U>> CPP_and
885             convertible_to<U, common_reference_t<T, U>>
886         );
887         template<typename T, typename U>
888         CPP_concept common_reference_with =
889             CPP_concept_ref(concepts::common_reference_with_, T, U);
890 
891         CPP_template(typename T, typename U)(
892         concept (common_with_)(T, U),
893             same_as<common_type_t<T, U>, common_type_t<U, T>> CPP_and
894             convertible_to<T, common_type_t<T, U>> CPP_and
895             convertible_to<U, common_type_t<T, U>> CPP_and
896             common_reference_with<
897                 std::add_lvalue_reference_t<T const>,
898                 std::add_lvalue_reference_t<U const>> CPP_and
899             common_reference_with<
900                 std::add_lvalue_reference_t<common_type_t<T, U>>,
901                 common_reference_t<
902                     std::add_lvalue_reference_t<T const>,
903                     std::add_lvalue_reference_t<U const>>>
904         );
905         template<typename T, typename U>
906         CPP_concept common_with =
907             CPP_concept_ref(concepts::common_with_, T, U);
908 
909         template<typename T>
910         CPP_concept integral =
911             std::is_integral<T>::value;
912 
913         template<typename T>
914         CPP_concept signed_integral =
915             integral<T> &&
916             std::is_signed<T>::value;
917 
918         template<typename T>
919         CPP_concept unsigned_integral =
920             integral<T> &&
921             !signed_integral<T>;
922 
923         template<typename T, typename U>
924         CPP_requires(assignable_from_,
925             requires(T t, U && u) //
926             (
927                 t = (U &&) u,
928                 requires_<same_as<T, decltype(t = (U &&) u)>>
929             ));
930         template<typename T, typename U>
931         CPP_concept assignable_from =
932             std::is_lvalue_reference<T>::value &&
933             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
934             CPP_requires_ref(defs::assignable_from_, T, U);
935 
936         template<typename T>
937         CPP_requires(swappable_,
938             requires(T & t, T & u) //
939             (
940                 concepts::swap(t, u)
941             ));
942         template<typename T>
943         CPP_concept swappable =
944             CPP_requires_ref(defs::swappable_, T);
945 
946         template<typename T, typename U>
947         CPP_requires(swappable_with_,
948             requires(T && t, U && u) //
949             (
950                 concepts::swap((T &&) t, (T &&) t),
951                 concepts::swap((U &&) u, (U &&) u),
952                 concepts::swap((U &&) u, (T &&) t),
953                 concepts::swap((T &&) t, (U &&) u)
954             ));
955         template<typename T, typename U>
956         CPP_concept swappable_with =
957             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
958             CPP_requires_ref(defs::swappable_with_, T, U);
959 
960     }  // inline namespace defs
961 
962     namespace detail
963     {
964         template<typename T>
965         CPP_concept boolean_testable_impl_ = convertible_to<T, bool>;
966 
967         template<typename T>
968         CPP_requires(boolean_testable_frag_,
969             requires(T && t) //
970             (
971                 !(T&&) t,
972                 concepts::requires_<boolean_testable_impl_<decltype(!(T&&) t)>>
973             ));
974 
975         template<typename T>
976         CPP_concept boolean_testable_ =
977             CPP_requires_ref(boolean_testable_frag_, T) &&
978             boolean_testable_impl_<T>;
979 
980         CPP_DIAGNOSTIC_PUSH
981         CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
982 
983         template<typename T, typename U>
984         CPP_requires(weakly_equality_comparable_with_frag_,
985             requires(detail::as_cref_t<T> t, detail::as_cref_t<U> u) //
986             (
987                 concepts::requires_<boolean_testable_<decltype(t == u)>>,
988                 concepts::requires_<boolean_testable_<decltype(t != u)>>,
989                 concepts::requires_<boolean_testable_<decltype(u == t)>>,
990                 concepts::requires_<boolean_testable_<decltype(u != t)>>
991             ));
992         template<typename T, typename U>
993         CPP_concept weakly_equality_comparable_with_ =
994             CPP_requires_ref(weakly_equality_comparable_with_frag_, T, U);
995 
996         template<typename T, typename U>
997         CPP_requires(partially_ordered_with_frag_,
998             requires(detail::as_cref_t<T>& t, detail::as_cref_t<U>& u) //
999             (
1000                 concepts::requires_<boolean_testable_<decltype(t < u)>>,
1001                 concepts::requires_<boolean_testable_<decltype(t > u)>>,
1002                 concepts::requires_<boolean_testable_<decltype(t <= u)>>,
1003                 concepts::requires_<boolean_testable_<decltype(t >= u)>>,
1004                 concepts::requires_<boolean_testable_<decltype(u < t)>>,
1005                 concepts::requires_<boolean_testable_<decltype(u > t)>>,
1006                 concepts::requires_<boolean_testable_<decltype(u <= t)>>,
1007                 concepts::requires_<boolean_testable_<decltype(u >= t)>>
1008             ));
1009         template<typename T, typename U>
1010         CPP_concept partially_ordered_with_ =
1011             CPP_requires_ref(partially_ordered_with_frag_, T, U);
1012 
1013         CPP_DIAGNOSTIC_POP
1014     } // namespace detail
1015 
1016     inline namespace defs
1017     {
1018         ////////////////////////////////////////////////////////////////////////
1019         // Comparison concepts
1020         ////////////////////////////////////////////////////////////////////////
1021 
1022         template<typename T>
1023         CPP_concept equality_comparable =
1024             detail::weakly_equality_comparable_with_<T, T>;
1025 
1026         CPP_template(typename T, typename U)(
1027         concept (equality_comparable_with_)(T, U),
1028             equality_comparable<
1029                 common_reference_t<detail::as_cref_t<T>, detail::as_cref_t<U>>>
1030         );
1031         template<typename T, typename U>
1032         CPP_concept equality_comparable_with =
1033             equality_comparable<T> &&
1034             equality_comparable<U> &&
1035             detail::weakly_equality_comparable_with_<T, U> &&
1036             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
1037             CPP_concept_ref(concepts::equality_comparable_with_, T, U);
1038 
1039         template<typename T>
1040         CPP_concept totally_ordered =
1041             equality_comparable<T> &&
1042             detail::partially_ordered_with_<T, T>;
1043 
1044         CPP_template(typename T, typename U)(
1045         concept (totally_ordered_with_)(T, U),
1046             totally_ordered<
1047                 common_reference_t<
1048                     detail::as_cref_t<T>,
1049                     detail::as_cref_t<U>>> CPP_and
1050             detail::partially_ordered_with_<T, U>);
1051 
1052         template<typename T, typename U>
1053         CPP_concept totally_ordered_with =
1054             totally_ordered<T> &&
1055             totally_ordered<U> &&
1056             equality_comparable_with<T, U> &&
1057             CPP_concept_ref(concepts::totally_ordered_with_, T, U);
1058 
1059         ////////////////////////////////////////////////////////////////////////
1060         // Object concepts
1061         ////////////////////////////////////////////////////////////////////////
1062 
1063         template<typename T>
1064         CPP_concept destructible =
1065             std::is_nothrow_destructible<T>::value;
1066 
1067         template<typename T, typename... Args>
1068         CPP_concept constructible_from =
1069             destructible<T> &&
1070             META_IS_CONSTRUCTIBLE(T, Args...);
1071 
1072         template<typename T>
1073         CPP_concept default_constructible =
1074             constructible_from<T>;
1075 
1076         template<typename T>
1077         CPP_concept move_constructible =
1078             constructible_from<T, T> &&
1079             convertible_to<T, T>;
1080 
1081         CPP_template(typename T)(
1082         concept (copy_constructible_)(T),
1083             constructible_from<T, T &> &&
1084             constructible_from<T, T const &> &&
1085             constructible_from<T, T const> &&
1086             convertible_to<T &, T> &&
1087             convertible_to<T const &, T> &&
1088             convertible_to<T const, T>);
1089         template<typename T>
1090         CPP_concept copy_constructible =
1091             move_constructible<T> &&
1092             CPP_concept_ref(concepts::copy_constructible_, T);
1093 
1094         CPP_template(typename T)(
1095         concept (move_assignable_)(T),
1096             assignable_from<T &, T>
1097         );
1098         template<typename T>
1099         CPP_concept movable =
1100             std::is_object<T>::value &&
1101             move_constructible<T> &&
1102             CPP_concept_ref(concepts::move_assignable_, T) &&
1103             swappable<T>;
1104 
1105         CPP_template(typename T)(
1106         concept (copy_assignable_)(T),
1107             assignable_from<T &, T const &>
1108         );
1109         template<typename T>
1110         CPP_concept copyable =
1111             copy_constructible<T> &&
1112             movable<T> &&
1113             CPP_concept_ref(concepts::copy_assignable_, T);
1114 
1115         template<typename T>
1116         CPP_concept semiregular =
1117             copyable<T> &&
1118             default_constructible<T>;
1119             // Axiom: copies are independent. See Fundamentals of Generic
1120             // Programming http://www.stepanovpapers.com/DeSt98.pdf
1121 
1122         template<typename T>
1123         CPP_concept regular =
1124             semiregular<T> &&
1125             equality_comparable<T>;
1126 
1127     } // inline namespace defs
1128 } // namespace concepts
1129 
1130 #endif // RANGES_V3_UTILITY_CONCEPTS_HPP
1131