Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:11:16

0001 /// \file
0002 //  CPP, the Concepts PreProcessor library
0003 //
0004 //  Copyright Eric Niebler 2018-present
0005 //  Copyright (c) 2018-present, Facebook, Inc.
0006 //  Copyright (c) 2020-present, Google LLC.
0007 //
0008 //  Use, modification and distribution is subject to the
0009 //  Boost Software License, Version 1.0. (See accompanying
0010 //  file LICENSE_1_0.txt or copy at
0011 //  http://www.boost.org/LICENSE_1_0.txt)
0012 //
0013 // This source code is licensed under the MIT license found in the
0014 // LICENSE file in the root directory of this source tree.
0015 //
0016 // Project home: https://github.com/ericniebler/range-v3
0017 //
0018 
0019 #ifndef CPP_CONCEPTS_HPP
0020 #define CPP_CONCEPTS_HPP
0021 
0022 // clang-format off
0023 
0024 #include <initializer_list>
0025 #include <utility>
0026 #include <type_traits>
0027 #include <concepts/swap.hpp>
0028 #include <concepts/type_traits.hpp>
0029 
0030 // Disable buggy clang compatibility warning about "requires" and "concept" being
0031 // C++20 keywords.
0032 // https://bugs.llvm.org/show_bug.cgi?id=43708
0033 #if defined(__clang__) && __cplusplus <= 201703L
0034 #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                                \
0035     CPP_DIAGNOSTIC_PUSH                                                                 \
0036     CPP_DIAGNOSTIC_IGNORE_CPP2A_COMPAT
0037 
0038 #define CPP_PP_IGNORE_CXX2A_COMPAT_END                                                  \
0039     CPP_DIAGNOSTIC_POP
0040 
0041 #else
0042 #define CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN
0043 #define CPP_PP_IGNORE_CXX2A_COMPAT_END
0044 #endif
0045 
0046 #if defined(_MSC_VER) && !defined(__clang__)
0047 #define CPP_WORKAROUND_MSVC_779763 // FATAL_UNREACHABLE calling constexpr function via template parameter
0048 #define CPP_WORKAROUND_MSVC_784772 // Failure to invoke *explicit* bool conversion in a constant expression
0049 #endif
0050 
0051 #if !defined(CPP_CXX_CONCEPTS)
0052 #ifdef CPP_DOXYGEN_INVOKED
0053 #define CPP_CXX_CONCEPTS 201800L
0054 #elif defined(__cpp_concepts) && __cpp_concepts > 0
0055 // gcc-6 concepts are too buggy to use
0056 #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 7
0057 #define CPP_CXX_CONCEPTS __cpp_concepts
0058 #else
0059 #define CPP_CXX_CONCEPTS 0L
0060 #endif
0061 #else
0062 #define CPP_CXX_CONCEPTS 0L
0063 #endif
0064 #endif
0065 
0066 #define CPP_PP_CAT_(X, ...)  X ## __VA_ARGS__
0067 #define CPP_PP_CAT(X, ...)   CPP_PP_CAT_(X, __VA_ARGS__)
0068 
0069 #define CPP_PP_EVAL_(X, ARGS) X ARGS
0070 #define CPP_PP_EVAL(X, ...) CPP_PP_EVAL_(X, (__VA_ARGS__))
0071 
0072 #define CPP_PP_EVAL2_(X, ARGS) X ARGS
0073 #define CPP_PP_EVAL2(X, ...) CPP_PP_EVAL2_(X, (__VA_ARGS__))
0074 
0075 #define CPP_PP_EXPAND(...) __VA_ARGS__
0076 #define CPP_PP_EAT(...)
0077 
0078 #define CPP_PP_FIRST(LIST) CPP_PP_FIRST_ LIST
0079 #define CPP_PP_FIRST_(...) __VA_ARGS__ CPP_PP_EAT
0080 
0081 #define CPP_PP_SECOND(LIST) CPP_PP_SECOND_ LIST
0082 #define CPP_PP_SECOND_(...) CPP_PP_EXPAND
0083 
0084 #define CPP_PP_CHECK(...) CPP_PP_EXPAND(CPP_PP_CHECK_N(__VA_ARGS__, 0,))
0085 #define CPP_PP_CHECK_N(x, n, ...) n
0086 #define CPP_PP_PROBE(x) x, 1,
0087 #define CPP_PP_PROBE_N(x, n) x, n,
0088 
0089 #define CPP_PP_IS_PAREN(x) CPP_PP_CHECK(CPP_PP_IS_PAREN_PROBE x)
0090 #define CPP_PP_IS_PAREN_PROBE(...) CPP_PP_PROBE(~)
0091 
0092 // CPP_CXX_VA_OPT
0093 #ifndef CPP_CXX_VA_OPT
0094 #if __cplusplus > 201703L
0095 #define CPP_CXX_VA_OPT_(...) CPP_PP_CHECK(__VA_OPT__(,) 1)
0096 #define CPP_CXX_VA_OPT CPP_CXX_VA_OPT_(~)
0097 #else
0098 #define CPP_CXX_VA_OPT 0
0099 #endif
0100 #endif // CPP_CXX_VA_OPT
0101 
0102 // The final CPP_PP_EXPAND here is to avoid
0103 // https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly
0104 #define CPP_PP_COUNT(...)                                                       \
0105     CPP_PP_EXPAND(CPP_PP_COUNT_(__VA_ARGS__,                                    \
0106         50, 49, 48, 47, 46, 45, 44, 43, 42, 41,                                 \
0107         40, 39, 38, 37, 36, 35, 34, 33, 32, 31,                                 \
0108         30, 29, 28, 27, 26, 25, 24, 23, 22, 21,                                 \
0109         20, 19, 18, 17, 16, 15, 14, 13, 12, 11,                                 \
0110         10, 9, 8, 7, 6, 5, 4, 3, 2, 1,))
0111 
0112 #define CPP_PP_COUNT_(                                                          \
0113     _01, _02, _03, _04, _05, _06, _07, _08, _09, _10,                           \
0114     _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,                           \
0115     _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,                           \
0116     _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,                           \
0117     _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, N, ...)                   \
0118     N
0119 
0120 #define CPP_PP_IIF(BIT) CPP_PP_CAT_(CPP_PP_IIF_, BIT)
0121 #define CPP_PP_IIF_0(TRUE, ...) __VA_ARGS__
0122 #define CPP_PP_IIF_1(TRUE, ...) TRUE
0123 
0124 #define CPP_PP_LPAREN (
0125 #define CPP_PP_RPAREN )
0126 
0127 #define CPP_PP_NOT(BIT) CPP_PP_CAT_(CPP_PP_NOT_, BIT)
0128 #define CPP_PP_NOT_0 1
0129 #define CPP_PP_NOT_1 0
0130 
0131 #define CPP_PP_EMPTY()
0132 #define CPP_PP_COMMA() ,
0133 #define CPP_PP_LBRACE() {
0134 #define CPP_PP_RBRACE() }
0135 #define CPP_PP_COMMA_IIF(X)                                                     \
0136     CPP_PP_IIF(X)(CPP_PP_EMPTY, CPP_PP_COMMA)()
0137 
0138 #define CPP_PP_FOR_EACH(M, ...)                                                 \
0139     CPP_PP_FOR_EACH_N(CPP_PP_COUNT(__VA_ARGS__), M, __VA_ARGS__)
0140 #define CPP_PP_FOR_EACH_N(N, M, ...)                                            \
0141     CPP_PP_CAT(CPP_PP_FOR_EACH_, N)(M, __VA_ARGS__)
0142 #define CPP_PP_FOR_EACH_1(M, _1)                                                \
0143     M(_1)
0144 #define CPP_PP_FOR_EACH_2(M, _1, _2)                                            \
0145     M(_1), M(_2)
0146 #define CPP_PP_FOR_EACH_3(M, _1, _2, _3)                                        \
0147     M(_1), M(_2), M(_3)
0148 #define CPP_PP_FOR_EACH_4(M, _1, _2, _3, _4)                                    \
0149     M(_1), M(_2), M(_3), M(_4)
0150 #define CPP_PP_FOR_EACH_5(M, _1, _2, _3, _4, _5)                                \
0151     M(_1), M(_2), M(_3), M(_4), M(_5)
0152 #define CPP_PP_FOR_EACH_6(M, _1, _2, _3, _4, _5, _6)                            \
0153     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6)
0154 #define CPP_PP_FOR_EACH_7(M, _1, _2, _3, _4, _5, _6, _7)                        \
0155     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6), M(_7)
0156 #define CPP_PP_FOR_EACH_8(M, _1, _2, _3, _4, _5, _6, _7, _8)                    \
0157     M(_1), M(_2), M(_3), M(_4), M(_5), M(_6), M(_7), M(_8)
0158 
0159 #define CPP_PP_PROBE_EMPTY_PROBE_CPP_PP_PROBE_EMPTY                             \
0160     CPP_PP_PROBE(~)
0161 
0162 #define CPP_PP_PROBE_EMPTY()
0163 #define CPP_PP_IS_NOT_EMPTY(...)                                                \
0164     CPP_PP_EVAL(                                                                \
0165         CPP_PP_CHECK,                                                           \
0166         CPP_PP_CAT(                                                             \
0167             CPP_PP_PROBE_EMPTY_PROBE_,                                          \
0168             CPP_PP_PROBE_EMPTY __VA_ARGS__ ()))
0169 
0170 #if defined(_MSC_VER) && !defined(__clang__) && (__cplusplus <= 201703L)
0171 #define CPP_BOOL(...) ::meta::bool_<__VA_ARGS__>::value
0172 #define CPP_TRUE_FN                                                             \
0173     !::concepts::detail::instance_<                                             \
0174         decltype(CPP_true_fn(::concepts::detail::xNil{}))>
0175 
0176 #define CPP_NOT(...) (!CPP_BOOL(__VA_ARGS__))
0177 #else
0178 #define CPP_BOOL(...) __VA_ARGS__
0179 #define CPP_TRUE_FN CPP_true_fn(::concepts::detail::xNil{})
0180 #define CPP_NOT(...) (!(__VA_ARGS__))
0181 #endif
0182 
0183 #define CPP_assert(...)                                                         \
0184     static_assert(static_cast<bool>(__VA_ARGS__),                               \
0185         "Concept assertion failed : " #__VA_ARGS__)
0186 
0187 #define CPP_assert_msg static_assert
0188 
0189 #if CPP_CXX_CONCEPTS || defined(CPP_DOXYGEN_INVOKED)
0190 #define CPP_concept META_CONCEPT
0191 #define CPP_and &&
0192 
0193 #else
0194 #define CPP_concept CPP_INLINE_VAR constexpr bool
0195 #define CPP_and CPP_and_sfinae
0196 
0197 #endif
0198 
0199 ////////////////////////////////////////////////////////////////////////////////
0200 // CPP_template
0201 // Usage:
0202 //   CPP_template(typename A, typename B)
0203 //     (requires Concept1<A> CPP_and Concept2<B>)
0204 //   void foo(A a, B b)
0205 //   {}
0206 #if CPP_CXX_CONCEPTS
0207 #if defined(CPP_DOXYGEN_INVOKED)
0208 #define CPP_template(...) template<__VA_ARGS__> CPP_TEMPLATE_EXPAND_
0209 #define CPP_TEMPLATE_EXPAND_(X,Y) X Y
0210 #else
0211 #define CPP_template(...) template<__VA_ARGS__ CPP_TEMPLATE_AUX_
0212 #endif
0213 #define CPP_template_def CPP_template
0214 #define CPP_member
0215 #define CPP_ctor(TYPE) TYPE CPP_CTOR_IMPL_1_
0216 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 10
0217 #define CPP_auto_member template<typename...>
0218 #else
0219 #define CPP_auto_member
0220 #endif
0221 
0222 /// INTERNAL ONLY
0223 #define CPP_CTOR_IMPL_1_(...) (__VA_ARGS__) CPP_PP_EXPAND
0224 
0225 /// INTERNAL ONLY
0226 #define CPP_TEMPLATE_AUX_(...)                                                  \
0227     > CPP_PP_CAT(                                                               \
0228         CPP_TEMPLATE_AUX_,                                                      \
0229         CPP_TEMPLATE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__)
0230 
0231 /// INTERNAL ONLY
0232 #define CPP_TEMPLATE_AUX_WHICH_(FIRST, ...)                                     \
0233     CPP_PP_EVAL(                                                                \
0234         CPP_PP_CHECK,                                                           \
0235         CPP_PP_CAT(CPP_TEMPLATE_PROBE_CONCEPT_, FIRST))
0236 
0237 /// INTERNAL ONLY
0238 #define CPP_TEMPLATE_PROBE_CONCEPT_concept                                      \
0239     CPP_PP_PROBE(~)
0240 
0241 // A template with a requires clause
0242 /// INTERNAL ONLY
0243 #define CPP_TEMPLATE_AUX_0(...) __VA_ARGS__
0244 
0245 // A concept definition
0246 /// INTERNAL ONLY
0247 #define CPP_TEMPLATE_AUX_1(DECL, ...)                                           \
0248     CPP_concept CPP_CONCEPT_NAME_(DECL) = __VA_ARGS__
0249 
0250 #if defined(CPP_DOXYGEN_INVOKED)
0251 #define CPP_concept_ref(NAME, ...)                                              \
0252     NAME<__VA_ARGS__>
0253 #else
0254 #define CPP_concept_ref(NAME, ...)                                              \
0255     CPP_PP_CAT(NAME, concept_)<__VA_ARGS__>
0256 #endif
0257 
0258 #else // ^^^^ with concepts / without concepts vvvv
0259 
0260 #define CPP_template CPP_template_sfinae
0261 #define CPP_template_def CPP_template_def_sfinae
0262 #define CPP_member CPP_member_sfinae
0263 #define CPP_auto_member CPP_member_sfinae
0264 #define CPP_ctor CPP_ctor_sfinae
0265 #define CPP_concept_ref(NAME, ...)                                              \
0266     (1u == sizeof(CPP_PP_CAT(NAME, concept_)(                                   \
0267         (::concepts::detail::tag<__VA_ARGS__>*)nullptr)))
0268 
0269 /// INTERNAL ONLY
0270 #define CPP_TEMPLATE_AUX_ CPP_TEMPLATE_SFINAE_AUX_
0271 
0272 #endif
0273 
0274 #define CPP_template_sfinae(...)                                                \
0275     CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                            \
0276     template<__VA_ARGS__ CPP_TEMPLATE_SFINAE_AUX_
0277 
0278 /// INTERNAL ONLY
0279 #define CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_concept                               \
0280     CPP_PP_PROBE(~)
0281 
0282 /// INTERNAL ONLY
0283 #define CPP_TEMPLATE_SFINAE_AUX_WHICH_(FIRST, ...)                              \
0284     CPP_PP_EVAL(                                                                \
0285         CPP_PP_CHECK,                                                           \
0286         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_, FIRST))
0287 
0288 /// INTERNAL ONLY
0289 #define CPP_TEMPLATE_SFINAE_AUX_(...)                                           \
0290     CPP_PP_CAT(                                                                 \
0291         CPP_TEMPLATE_SFINAE_AUX_,                                               \
0292         CPP_TEMPLATE_SFINAE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__)
0293 
0294 // A template with a requires clause
0295 /// INTERNAL ONLY
0296 #define CPP_TEMPLATE_SFINAE_AUX_0(...) ,                                        \
0297     bool CPP_true = true,                                                       \
0298     std::enable_if_t<                                                           \
0299         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) &&                  \
0300         CPP_BOOL(CPP_true),                                                     \
0301         int> = 0>                                                               \
0302     CPP_PP_IGNORE_CXX2A_COMPAT_END
0303 
0304 // A concept definition
0305 /// INTERNAL ONLY
0306 #define CPP_TEMPLATE_SFINAE_AUX_1(DECL, ...) ,                                  \
0307         bool CPP_true = true,                                                   \
0308         std::enable_if_t<__VA_ARGS__ && CPP_BOOL(CPP_true), int> = 0>           \
0309     auto CPP_CONCEPT_NAME_(DECL)(                                               \
0310         ::concepts::detail::tag<CPP_CONCEPT_PARAMS_(DECL)>*)                    \
0311         -> char(&)[1];                                                          \
0312     auto CPP_CONCEPT_NAME_(DECL)(...) -> char(&)[2]                             \
0313     CPP_PP_IGNORE_CXX2A_COMPAT_END
0314 
0315 /// INTERNAL ONLY
0316 #define CPP_CONCEPT_NAME_(DECL)                                                 \
0317     CPP_PP_EVAL(                                                                \
0318         CPP_PP_CAT,                                                             \
0319         CPP_PP_EVAL(CPP_PP_FIRST, CPP_EAT_CONCEPT_(DECL)), concept_)
0320 
0321 /// INTERNAL ONLY
0322 #define CPP_CONCEPT_PARAMS_(DECL)                                               \
0323     CPP_PP_EVAL(CPP_PP_SECOND, CPP_EAT_CONCEPT_(DECL))
0324 
0325 /// INTERNAL ONLY
0326 #define CPP_EAT_CONCEPT_(DECL)                                                  \
0327     CPP_PP_CAT(CPP_EAT_CONCEPT_, DECL)
0328 
0329 /// INTERNAL ONLY
0330 #define CPP_EAT_CONCEPT_concept
0331 
0332 /// INTERNAL ONLY
0333 #define CPP_and_sfinae                                                          \
0334     && CPP_BOOL(CPP_true), int> = 0, std::enable_if_t<
0335 
0336 /// INTERNAL ONLY
0337 #define CPP_template_def_sfinae(...)                                            \
0338     template<__VA_ARGS__ CPP_TEMPLATE_DEF_SFINAE_AUX_
0339 
0340 /// INTERNAL ONLY
0341 #define CPP_TEMPLATE_DEF_SFINAE_AUX_(...) ,                                     \
0342     bool CPP_true,                                                              \
0343     std::enable_if_t<                                                           \
0344         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) &&                  \
0345         CPP_BOOL(CPP_true),                                                     \
0346         int>>
0347 
0348 /// INTERNAL ONLY
0349 #define CPP_and_sfinae_def                                                      \
0350     && CPP_BOOL(CPP_true), int>, std::enable_if_t<
0351 
0352 /// INTERNAL ONLY
0353 #define CPP_TEMPLATE_SFINAE_AUX_3_requires
0354 
0355 /// INTERNAL ONLY
0356 #define CPP_member_sfinae                                                       \
0357     CPP_broken_friend_member
0358 
0359 /// INTERNAL ONLY
0360 #define CPP_ctor_sfinae(TYPE)                                                   \
0361     CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN                                            \
0362     TYPE CPP_CTOR_SFINAE_IMPL_1_
0363 
0364 /// INTERNAL ONLY
0365 #define CPP_CTOR_SFINAE_IMPL_1_(...)                                            \
0366     (__VA_ARGS__                                                                \
0367         CPP_PP_COMMA_IIF(                                                       \
0368             CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__)))                       \
0369     CPP_CTOR_SFINAE_REQUIRES
0370 
0371 /// INTERNAL ONLY
0372 #define CPP_CTOR_SFINAE_PROBE_NOEXCEPT_noexcept                                 \
0373     CPP_PP_PROBE(~)
0374 
0375 /// INTERNAL ONLY
0376 #define CPP_CTOR_SFINAE_MAKE_PROBE(FIRST,...)                                   \
0377     CPP_PP_CAT(CPP_CTOR_SFINAE_PROBE_NOEXCEPT_, FIRST)
0378 
0379 /// INTERNAL ONLY
0380 #define CPP_CTOR_SFINAE_REQUIRES(...)                                           \
0381     CPP_PP_CAT(                                                                 \
0382         CPP_CTOR_SFINAE_REQUIRES_,                                              \
0383         CPP_PP_EVAL(                                                            \
0384             CPP_PP_CHECK,                                                       \
0385             CPP_CTOR_SFINAE_MAKE_PROBE(__VA_ARGS__,)))(__VA_ARGS__)
0386 
0387 // No noexcept-clause:
0388 /// INTERNAL ONLY
0389 #define CPP_CTOR_SFINAE_REQUIRES_0(...)                                         \
0390     std::enable_if_t<                                                           \
0391         CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) && CPP_TRUE_FN,     \
0392         ::concepts::detail::Nil                                                 \
0393     > = {})                                                                     \
0394     CPP_PP_IGNORE_CXX2A_COMPAT_END
0395 
0396 // Yes noexcept-clause:
0397 /// INTERNAL ONLY
0398 #define CPP_CTOR_SFINAE_REQUIRES_1(...)                                         \
0399     std::enable_if_t<                                                           \
0400         CPP_PP_EVAL(CPP_PP_CAT,                                                 \
0401             CPP_TEMPLATE_SFINAE_AUX_3_,                                         \
0402             CPP_PP_CAT(CPP_CTOR_SFINAE_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN,\
0403         ::concepts::detail::Nil                                                 \
0404     > = {})                                                                     \
0405     CPP_PP_EXPAND(CPP_PP_CAT(CPP_CTOR_SFINAE_SHOW_NOEXCEPT_, __VA_ARGS__)))
0406 
0407 /// INTERNAL ONLY
0408 #define CPP_CTOR_SFINAE_EAT_NOEXCEPT_noexcept(...)
0409 
0410 /// INTERNAL ONLY
0411 #define CPP_CTOR_SFINAE_SHOW_NOEXCEPT_noexcept(...)                             \
0412     noexcept(__VA_ARGS__)                                                       \
0413     CPP_PP_IGNORE_CXX2A_COMPAT_END                                              \
0414     CPP_PP_EAT CPP_PP_LPAREN
0415 
0416 #ifdef CPP_DOXYGEN_INVOKED
0417 /// INTERNAL ONLY
0418 #define CPP_broken_friend_ret(...)                                              \
0419     __VA_ARGS__ CPP_PP_EXPAND
0420 
0421 #else // ^^^ CPP_DOXYGEN_INVOKED / not CPP_DOXYGEN_INVOKED vvv
0422 #define CPP_broken_friend_ret(...)                                              \
0423     ::concepts::return_t<                                                       \
0424         __VA_ARGS__,                                                            \
0425         std::enable_if_t<CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_
0426 
0427 /// INTERNAL ONLY
0428 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_(...)                                 \
0429     CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(CPP_PP_CAT(                            \
0430         CPP_TEMPLATE_AUX_2_, __VA_ARGS__))
0431 
0432 /// INTERNAL ONLY
0433 #define CPP_TEMPLATE_AUX_2_requires
0434 
0435 /// INTERNAL ONLY
0436 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(...)                               \
0437     (__VA_ARGS__ && CPP_TRUE_FN)>>
0438 
0439 #ifdef CPP_WORKAROUND_MSVC_779763
0440 /// INTERNAL ONLY
0441 #define CPP_broken_friend_member                                                \
0442     template<::concepts::detail::CPP_true_t const &CPP_true_fn =                \
0443         ::concepts::detail::CPP_true_fn_>
0444 
0445 #else // ^^^ workaround / no workaround vvv
0446 /// INTERNAL ONLY
0447 #define CPP_broken_friend_member                                                \
0448     template<bool (&CPP_true_fn)(::concepts::detail::xNil) =                    \
0449         ::concepts::detail::CPP_true_fn>
0450 
0451 #endif // CPP_WORKAROUND_MSVC_779763
0452 #endif
0453 
0454 #if CPP_CXX_CONCEPTS
0455 #if defined(CPP_DOXYGEN_INVOKED)
0456 #define CPP_requires(NAME, REQS)                                                \
0457     concept NAME =                                                              \
0458         CPP_PP_CAT(CPP_REQUIRES_, REQS)
0459 #define CPP_requires_ref(NAME, ...)                                             \
0460     NAME<__VA_ARGS__>
0461 #else
0462 #define CPP_requires(NAME, REQS)                                                \
0463     CPP_concept CPP_PP_CAT(NAME, requires_) =                                   \
0464         CPP_PP_CAT(CPP_REQUIRES_, REQS)
0465 #define CPP_requires_ref(NAME, ...)                                             \
0466     CPP_PP_CAT(NAME, requires_)<__VA_ARGS__>
0467 #endif
0468 
0469 /// INTERNAL ONLY
0470 #define CPP_REQUIRES_requires(...)                                              \
0471     requires(__VA_ARGS__) CPP_REQUIRES_AUX_
0472 
0473 /// INTERNAL ONLY
0474 #define CPP_REQUIRES_AUX_(...)                                                  \
0475     { __VA_ARGS__; }
0476 
0477 #else
0478 #define CPP_requires(NAME, REQS)                                                \
0479     auto CPP_PP_CAT(NAME, requires_test_)                                       \
0480     CPP_REQUIRES_AUX_(NAME, CPP_REQUIRES_ ## REQS)
0481 
0482 #define CPP_requires_ref(NAME, ...)                                             \
0483     (1u == sizeof(CPP_PP_CAT(NAME, requires_)(                                  \
0484         (::concepts::detail::tag<__VA_ARGS__>*)nullptr)))
0485 
0486 /// INTERNAL ONLY
0487 #define CPP_REQUIRES_requires(...)                                              \
0488     (__VA_ARGS__) -> decltype CPP_REQUIRES_RETURN_
0489 
0490 /// INTERNAL ONLY
0491 #define CPP_REQUIRES_RETURN_(...) (__VA_ARGS__, void()) {}
0492 
0493 /// INTERNAL ONLY
0494 #define CPP_REQUIRES_AUX_(NAME, ...)                                            \
0495     __VA_ARGS__                                                                 \
0496     template<typename... As>                                                    \
0497     auto CPP_PP_CAT(NAME, requires_)(                                           \
0498         ::concepts::detail::tag<As...> *,                                       \
0499         decltype(&CPP_PP_CAT(NAME, requires_test_)<As...>) = nullptr)           \
0500         -> char(&)[1];                                                          \
0501     auto CPP_PP_CAT(NAME, requires_)(...) -> char(&)[2]
0502 
0503 #endif
0504 
0505 #if CPP_CXX_CONCEPTS
0506 #define CPP_ret(...)                                                            \
0507     __VA_ARGS__ CPP_PP_EXPAND
0508 #else
0509 #define CPP_ret                                                                 \
0510     CPP_broken_friend_ret
0511 #endif
0512 
0513 ////////////////////////////////////////////////////////////////////////////////
0514 // CPP_fun
0515 #if CPP_CXX_CONCEPTS
0516 
0517 /// INTERNAL ONLY
0518 #define CPP_FUN_IMPL_1_(...)                                                    \
0519     (__VA_ARGS__)                                                               \
0520     CPP_PP_EXPAND
0521 
0522 #define CPP_fun(X) X CPP_FUN_IMPL_1_
0523 #else
0524 /// INTERNAL ONLY
0525 #define CPP_FUN_IMPL_1_(...)                                                    \
0526     (__VA_ARGS__                                                                \
0527         CPP_PP_COMMA_IIF(                                                       \
0528             CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__)))                       \
0529     CPP_FUN_IMPL_REQUIRES
0530 
0531 /// INTERNAL ONLY
0532 #define CPP_FUN_IMPL_REQUIRES(...)                                              \
0533     CPP_PP_EVAL2_(                                                              \
0534         CPP_FUN_IMPL_SELECT_CONST_,                                             \
0535         (__VA_ARGS__,)                                                          \
0536     )(__VA_ARGS__)
0537 
0538 /// INTERNAL ONLY
0539 #define CPP_FUN_IMPL_SELECT_CONST_(MAYBE_CONST, ...)                            \
0540     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_,                                      \
0541         CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT(                                   \
0542             CPP_PP_PROBE_CONST_PROBE_, MAYBE_CONST)))
0543 
0544 /// INTERNAL ONLY
0545 #define CPP_PP_PROBE_CONST_PROBE_const CPP_PP_PROBE(~)
0546 
0547 /// INTERNAL ONLY
0548 #define CPP_FUN_IMPL_SELECT_CONST_1(...)                                        \
0549     CPP_PP_EVAL(                                                                \
0550         CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_,                                    \
0551         CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__),)(                     \
0552         CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__))
0553 
0554 /// INTERNAL ONLY
0555 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...)                \
0556     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_,                             \
0557         CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT(                                  \
0558             CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT)))
0559 
0560 /// INTERNAL ONLY
0561 #define CPP_PP_PROBE_NOEXCEPT_PROBE_noexcept CPP_PP_PROBE(~)
0562 
0563 /// INTERNAL ONLY
0564 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_0(...)                               \
0565     std::enable_if_t<                                                           \
0566         CPP_PP_EVAL(                                                            \
0567             CPP_PP_CAT,                                                         \
0568             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
0569             __VA_ARGS__) && CPP_TRUE_FN,                                        \
0570         ::concepts::detail::Nil                                                 \
0571     > = {}) const                                                               \
0572     CPP_PP_IGNORE_CXX2A_COMPAT_END
0573 
0574 /// INTERNAL ONLY
0575 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_1(...)                               \
0576     std::enable_if_t<                                                           \
0577         CPP_PP_EVAL(                                                            \
0578             CPP_PP_CAT,                                                         \
0579             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
0580             CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN,\
0581         ::concepts::detail::Nil                                                 \
0582     > = {}) const                                                               \
0583     CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__)))
0584 
0585 /// INTERNAL ONLY
0586 #define CPP_FUN_IMPL_EAT_NOEXCEPT_noexcept(...)
0587 
0588 /// INTERNAL ONLY
0589 #define CPP_FUN_IMPL_SHOW_NOEXCEPT_noexcept(...)                                \
0590     noexcept(__VA_ARGS__) CPP_PP_IGNORE_CXX2A_COMPAT_END                        \
0591     CPP_PP_EAT CPP_PP_LPAREN
0592 
0593 /// INTERNAL ONLY
0594 #define CPP_FUN_IMPL_SELECT_CONST_0(...)                                        \
0595     CPP_PP_EVAL_(                                                               \
0596         CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_,                                 \
0597         (__VA_ARGS__,)                                                          \
0598     )(__VA_ARGS__)
0599 
0600 /// INTERNAL ONLY
0601 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...)             \
0602     CPP_PP_CAT(CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_,                          \
0603           CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT(                                \
0604             CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT)))
0605 
0606 /// INTERNAL ONLY
0607 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_0(...)                            \
0608     std::enable_if_t<                                                           \
0609         CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, __VA_ARGS__) && CPP_TRUE_FN,     \
0610         ::concepts::detail::Nil                                                 \
0611     > = {})                                                                     \
0612     CPP_PP_IGNORE_CXX2A_COMPAT_END
0613 
0614 /// INTERNAL ONLY
0615 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_1(...)                            \
0616     std::enable_if_t<                                                           \
0617         CPP_PP_EVAL(                                                            \
0618             CPP_PP_CAT,                                                         \
0619             CPP_FUN_IMPL_EAT_REQUIRES_,                                         \
0620             CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__)                 \
0621         ) && CPP_TRUE_FN,                                                       \
0622         ::concepts::detail::Nil                                                 \
0623     > = {})                                                                     \
0624     CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__)))
0625 
0626 /// INTERNAL ONLY
0627 #define CPP_FUN_IMPL_EAT_CONST_const
0628 
0629 /// INTERNAL ONLY
0630 #define CPP_FUN_IMPL_EAT_REQUIRES_requires
0631 
0632 ////////////////////////////////////////////////////////////////////////////////
0633 // CPP_fun
0634 // Usage:
0635 //   template <typename A, typename B>
0636 //   void CPP_fun(foo)(A a, B b)([const]opt [noexcept(true)]opt
0637 //       requires Concept1<A> && Concept2<B>)
0638 //   {}
0639 //
0640 // Note: This macro cannot be used when the last function argument is a
0641 //       parameter pack.
0642 #define CPP_fun(X) CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN X CPP_FUN_IMPL_1_
0643 #endif
0644 
0645 ////////////////////////////////////////////////////////////////////////////////
0646 // CPP_auto_fun
0647 // Usage:
0648 //   template <typename A, typename B>
0649 //   auto CPP_auto_fun(foo)(A a, B b)([const]opt [noexcept(cond)]opt)opt
0650 //   (
0651 //       return a + b
0652 //   )
0653 #define CPP_auto_fun(X) X CPP_AUTO_FUN_IMPL_
0654 
0655 /// INTERNAL ONLY
0656 #define CPP_AUTO_FUN_IMPL_(...) (__VA_ARGS__) CPP_AUTO_FUN_RETURNS_
0657 
0658 /// INTERNAL ONLY
0659 #define CPP_AUTO_FUN_RETURNS_(...)                                              \
0660     CPP_PP_EVAL2_(                                                              \
0661         CPP_AUTO_FUN_SELECT_RETURNS_,                                           \
0662         (__VA_ARGS__,)                                                          \
0663     )(__VA_ARGS__)
0664 
0665 /// INTERNAL ONLY
0666 #define CPP_AUTO_FUN_SELECT_RETURNS_(MAYBE_CONST, ...)                          \
0667     CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_CONST_,                                     \
0668         CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT(                                   \
0669             CPP_PP_PROBE_CONST_MUTABLE_PROBE_, MAYBE_CONST)))
0670 
0671 /// INTERNAL ONLY
0672 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_const CPP_PP_PROBE_N(~, 1)
0673 
0674 /// INTERNAL ONLY
0675 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_mutable CPP_PP_PROBE_N(~, 2)
0676 
0677 /// INTERNAL ONLY
0678 #define CPP_PP_EAT_MUTABLE_mutable
0679 
0680 /// INTERNAL ONLY
0681 #define CPP_AUTO_FUN_RETURNS_CONST_2(...)                                       \
0682     CPP_PP_CAT(CPP_PP_EAT_MUTABLE_, __VA_ARGS__) CPP_AUTO_FUN_RETURNS_CONST_0
0683 
0684 /// INTERNAL ONLY
0685 #define CPP_AUTO_FUN_RETURNS_CONST_1(...)                                       \
0686     __VA_ARGS__ CPP_AUTO_FUN_RETURNS_CONST_0
0687 
0688 /// INTERNAL ONLY
0689 #define CPP_AUTO_FUN_RETURNS_CONST_0(...)                                       \
0690     CPP_PP_EVAL(CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_,                                \
0691         CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_, __VA_ARGS__))
0692 
0693 /// INTERNAL ONLY
0694 #define CPP_AUTO_FUN_RETURNS_return
0695 
0696 #ifdef __cpp_guaranteed_copy_elision
0697 /// INTERNAL ONLY
0698 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...)                                    \
0699     noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__)                    \
0700     { return (__VA_ARGS__); }
0701 
0702 #else
0703 /// INTERNAL ONLY
0704 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...)                                    \
0705     noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) ->                   \
0706     decltype(__VA_ARGS__)                                                       \
0707     { return (__VA_ARGS__); }
0708 
0709 #endif
0710 
0711 #if defined(CPP_DOXYGEN_INVOKED)
0712 #define concept(NAME) concept NAME CPP_CONCEPT_EQUALS_
0713 #define CPP_CONCEPT_EQUALS_(...) =
0714 #endif
0715 
0716 namespace concepts
0717 {
0718     template<bool B>
0719     using bool_ = std::integral_constant<bool, B>;
0720 
0721 #if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
0722     template<bool...Bs>
0723     CPP_INLINE_VAR constexpr bool and_v = (Bs &&...);
0724 
0725     template<bool...Bs>
0726     CPP_INLINE_VAR constexpr bool or_v = (Bs ||...);
0727 #else
0728     namespace detail
0729     {
0730         template<bool...>
0731         struct bools;
0732     } // namespace detail
0733 
0734     template<bool...Bs>
0735     CPP_INLINE_VAR constexpr bool and_v =
0736         META_IS_SAME(detail::bools<Bs..., true>, detail::bools<true, Bs...>);
0737 
0738     template<bool...Bs>
0739     CPP_INLINE_VAR constexpr bool or_v =
0740         !META_IS_SAME(detail::bools<Bs..., false>, detail::bools<false, Bs...>);
0741 #endif
0742 
0743     template<typename>
0744     struct return_t_
0745     {
0746         template<typename T>
0747         using invoke = T;
0748     };
0749 
0750     template<typename T, typename EnableIf>
0751     using return_t = meta::invoke<return_t_<EnableIf>, T>;
0752 
0753     /// \cond
0754     namespace detail
0755     {
0756         struct ignore
0757         {
0758             template<class... Args>
0759             constexpr ignore(Args&&...) noexcept {}
0760         };
0761 
0762         template<class>
0763         constexpr bool true_()
0764         {
0765             return true;
0766         }
0767 
0768         template<typename...>
0769         struct tag;
0770 
0771         template<typename T>
0772         CPP_INLINE_VAR constexpr T instance_ = T{};
0773 
0774         template<typename>
0775         constexpr bool requires_()
0776         {
0777             return true;
0778         }
0779 
0780         struct Nil
0781         {};
0782 
0783 #ifdef CPP_WORKAROUND_MSVC_779763
0784         enum class xNil {};
0785 
0786         struct CPP_true_t
0787         {
0788             constexpr bool operator()(Nil) const noexcept
0789             {
0790                 return true;
0791             }
0792             constexpr bool operator()(xNil) const noexcept
0793             {
0794                 return true;
0795             }
0796         };
0797 
0798         CPP_INLINE_VAR constexpr CPP_true_t CPP_true_fn_ {};
0799 
0800         constexpr bool CPP_true_fn(xNil)
0801         {
0802             return true;
0803         }
0804 #else
0805         using xNil = Nil;
0806 #endif
0807 
0808         constexpr bool CPP_true_fn(Nil)
0809         {
0810             return true;
0811         }
0812     } // namespace detail
0813     /// \endcond
0814 
0815 #if defined(__clang__) || defined(_MSC_VER)
0816     template<bool B>
0817     std::enable_if_t<B> requires_()
0818     {}
0819 #else
0820     template<bool B>
0821     CPP_INLINE_VAR constexpr std::enable_if_t<B, int> requires_ = 0;
0822 #endif
0823 
0824     inline namespace defs
0825     {
0826         ////////////////////////////////////////////////////////////////////////
0827         // Utility concepts
0828         ////////////////////////////////////////////////////////////////////////
0829 
0830         /// \concept is_true
0831         /// \brief The \c is_true concept
0832         template<bool B>
0833         CPP_concept is_true = B;
0834 
0835         /// \concept type
0836         /// \brief The \c type concept
0837         template<typename... Args>
0838         CPP_concept type = true;
0839 
0840         /// \concept satisfies
0841         /// \brief The \c satisfies concept
0842         template<class T, template<typename...> class Trait, typename... Args>
0843         CPP_concept satisfies =
0844             static_cast<bool>(Trait<T, Args...>::type::value);
0845 
0846         ////////////////////////////////////////////////////////////////////////
0847         // Core language concepts
0848         ////////////////////////////////////////////////////////////////////////
0849 
0850         /// \concept same_as
0851         /// \brief The \c same_as concept
0852         template<typename A, typename B>
0853         CPP_concept same_as =
0854             META_IS_SAME(A, B) && META_IS_SAME(B, A);
0855 
0856         /// \cond
0857         /// \concept not_same_as_
0858         /// \brief The \c not_same_as_ concept
0859         template<typename A, typename B>
0860         CPP_concept not_same_as_ =
0861             (!same_as<remove_cvref_t<A>, remove_cvref_t<B>>);
0862         /// \endcond
0863 
0864         // Workaround bug in the Standard Library:
0865         // From cannot be an incomplete class type despite that
0866         // is_convertible<X, Y> should be equivalent to is_convertible<X&&, Y>
0867         // in such a case.
0868         /// \concept implicitly_convertible_to
0869         /// \brief The \c implicitly_convertible_to concept
0870         template<typename From, typename To>
0871         CPP_concept implicitly_convertible_to =
0872             std::is_convertible<std::add_rvalue_reference_t<From>, To>::value;
0873 
0874         /// \concept explicitly_convertible_to_
0875         /// \brief The \c explicitly_convertible_to_ concept
0876         template<typename From, typename To>
0877         CPP_requires(explicitly_convertible_to_,
0878             requires(From(*from)()) //
0879             (
0880                 static_cast<To>(from())
0881             ));
0882         /// \concept explicitly_convertible_to
0883         /// \brief The \c explicitly_convertible_to concept
0884         template<typename From, typename To>
0885         CPP_concept explicitly_convertible_to =
0886             CPP_requires_ref(concepts::explicitly_convertible_to_, From, To);
0887 
0888         /// \concept convertible_to
0889         /// \brief The \c convertible_to concept
0890         template<typename From, typename To>
0891         CPP_concept convertible_to =
0892             implicitly_convertible_to<From, To> &&
0893             explicitly_convertible_to<From, To>;
0894 
0895         /// \concept derived_from_
0896         /// \brief The \c derived_from_ concept
0897         CPP_template(typename T, typename U)(
0898         concept (derived_from_)(T, U),
0899             convertible_to<T const volatile *, U const volatile *>
0900         );
0901         /// \concept derived_from
0902         /// \brief The \c derived_from concept
0903         template<typename T, typename U>
0904         CPP_concept derived_from =
0905             META_IS_BASE_OF(U, T) &&
0906             CPP_concept_ref(concepts::derived_from_, T, U);
0907 
0908         /// \concept common_reference_with_
0909         /// \brief The \c common_reference_with_ concept
0910         CPP_template(typename T, typename U)(
0911         concept (common_reference_with_)(T, U),
0912             same_as<common_reference_t<T, U>, common_reference_t<U, T>> CPP_and
0913             convertible_to<T, common_reference_t<T, U>> CPP_and
0914             convertible_to<U, common_reference_t<T, U>>
0915         );
0916         /// \concept common_reference_with
0917         /// \brief The \c common_reference_with concept
0918         template<typename T, typename U>
0919         CPP_concept common_reference_with =
0920             CPP_concept_ref(concepts::common_reference_with_, T, U);
0921 
0922         /// \concept common_with_
0923         /// \brief The \c common_with_ concept
0924         CPP_template(typename T, typename U)(
0925         concept (common_with_)(T, U),
0926             same_as<common_type_t<T, U>, common_type_t<U, T>> CPP_and
0927             convertible_to<T, common_type_t<T, U>> CPP_and
0928             convertible_to<U, common_type_t<T, U>> CPP_and
0929             common_reference_with<
0930                 std::add_lvalue_reference_t<T const>,
0931                 std::add_lvalue_reference_t<U const>> CPP_and
0932             common_reference_with<
0933                 std::add_lvalue_reference_t<common_type_t<T, U>>,
0934                 common_reference_t<
0935                     std::add_lvalue_reference_t<T const>,
0936                     std::add_lvalue_reference_t<U const>>>
0937         );
0938         /// \concept common_with
0939         /// \brief The \c common_with concept
0940         template<typename T, typename U>
0941         CPP_concept common_with =
0942             CPP_concept_ref(concepts::common_with_, T, U);
0943 
0944         /// \concept integral
0945         /// \brief The \c integral concept
0946         template<typename T>
0947         CPP_concept integral =
0948             std::is_integral<T>::value;
0949 
0950         /// \concept signed_integral
0951         /// \brief The \c signed_integral concept
0952         template<typename T>
0953         CPP_concept signed_integral =
0954             integral<T> &&
0955             std::is_signed<T>::value;
0956 
0957         /// \concept unsigned_integral
0958         /// \brief The \c unsigned_integral concept
0959         template<typename T>
0960         CPP_concept unsigned_integral =
0961             integral<T> &&
0962             !signed_integral<T>;
0963 
0964         /// \concept assignable_from_
0965         /// \brief The \c assignable_from_ concept
0966         template<typename T, typename U>
0967         CPP_requires(assignable_from_,
0968             requires(T t, U && u) //
0969             (
0970                 t = (U &&) u,
0971                 requires_<same_as<T, decltype(t = (U &&) u)>>
0972             ));
0973         /// \concept assignable_from
0974         /// \brief The \c assignable_from concept
0975         template<typename T, typename U>
0976         CPP_concept assignable_from =
0977             std::is_lvalue_reference<T>::value &&
0978             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
0979             CPP_requires_ref(defs::assignable_from_, T, U);
0980 
0981         /// \concept swappable_
0982         /// \brief The \c swappable_ concept
0983         template<typename T>
0984         CPP_requires(swappable_,
0985             requires(T & t, T & u) //
0986             (
0987                 concepts::swap(t, u)
0988             ));
0989         /// \concept swappable
0990         /// \brief The \c swappable concept
0991         template<typename T>
0992         CPP_concept swappable =
0993             CPP_requires_ref(defs::swappable_, T);
0994 
0995         /// \concept swappable_with_
0996         /// \brief The \c swappable_with_ concept
0997         template<typename T, typename U>
0998         CPP_requires(swappable_with_,
0999             requires(T && t, U && u) //
1000             (
1001                 concepts::swap((T &&) t, (T &&) t),
1002                 concepts::swap((U &&) u, (U &&) u),
1003                 concepts::swap((U &&) u, (T &&) t),
1004                 concepts::swap((T &&) t, (U &&) u)
1005             ));
1006         /// \concept swappable_with
1007         /// \brief The \c swappable_with concept
1008         template<typename T, typename U>
1009         CPP_concept swappable_with =
1010             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
1011             CPP_requires_ref(defs::swappable_with_, T, U);
1012 
1013     }  // inline namespace defs
1014 
1015     namespace detail
1016     {
1017         /// \concept boolean_testable_impl_
1018         /// \brief The \c boolean_testable_impl_ concept
1019         template<typename T>
1020         CPP_concept boolean_testable_impl_ = convertible_to<T, bool>;
1021 
1022         /// \concept boolean_testable_frag_
1023         /// \brief The \c boolean_testable_frag_ concept
1024         template<typename T>
1025         CPP_requires(boolean_testable_frag_,
1026             requires(T && t) //
1027             (
1028                 !(T&&) t,
1029                 concepts::requires_<boolean_testable_impl_<decltype(!(T&&) t)>>
1030             ));
1031 
1032         /// \concept boolean_testable_
1033         /// \brief The \c boolean_testable_ concept
1034         template<typename T>
1035         CPP_concept boolean_testable_ =
1036             CPP_requires_ref(boolean_testable_frag_, T) &&
1037             boolean_testable_impl_<T>;
1038 
1039         CPP_DIAGNOSTIC_PUSH
1040         CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
1041 
1042         /// \concept weakly_equality_comparable_with_frag_
1043         /// \brief The \c weakly_equality_comparable_with_frag_ concept
1044         template<typename T, typename U>
1045         CPP_requires(weakly_equality_comparable_with_frag_,
1046             requires(detail::as_cref_t<T> t, detail::as_cref_t<U> u) //
1047             (
1048                 concepts::requires_<boolean_testable_<decltype(t == u)>>,
1049                 concepts::requires_<boolean_testable_<decltype(t != u)>>,
1050                 concepts::requires_<boolean_testable_<decltype(u == t)>>,
1051                 concepts::requires_<boolean_testable_<decltype(u != t)>>
1052             ));
1053         /// \concept weakly_equality_comparable_with_
1054         /// \brief The \c weakly_equality_comparable_with_ concept
1055         template<typename T, typename U>
1056         CPP_concept weakly_equality_comparable_with_ =
1057             CPP_requires_ref(weakly_equality_comparable_with_frag_, T, U);
1058 
1059         /// \concept partially_ordered_with_frag_
1060         /// \brief The \c partially_ordered_with_frag_ concept
1061         template<typename T, typename U>
1062         CPP_requires(partially_ordered_with_frag_,
1063             requires(detail::as_cref_t<T>& t, detail::as_cref_t<U>& u) //
1064             (
1065                 concepts::requires_<boolean_testable_<decltype(t < u)>>,
1066                 concepts::requires_<boolean_testable_<decltype(t > u)>>,
1067                 concepts::requires_<boolean_testable_<decltype(t <= u)>>,
1068                 concepts::requires_<boolean_testable_<decltype(t >= u)>>,
1069                 concepts::requires_<boolean_testable_<decltype(u < t)>>,
1070                 concepts::requires_<boolean_testable_<decltype(u > t)>>,
1071                 concepts::requires_<boolean_testable_<decltype(u <= t)>>,
1072                 concepts::requires_<boolean_testable_<decltype(u >= t)>>
1073             ));
1074         /// \concept partially_ordered_with_
1075         /// \brief The \c partially_ordered_with_ concept
1076         template<typename T, typename U>
1077         CPP_concept partially_ordered_with_ =
1078             CPP_requires_ref(partially_ordered_with_frag_, T, U);
1079 
1080         CPP_DIAGNOSTIC_POP
1081     } // namespace detail
1082 
1083     inline namespace defs
1084     {
1085         ////////////////////////////////////////////////////////////////////////
1086         // Comparison concepts
1087         ////////////////////////////////////////////////////////////////////////
1088 
1089         /// \concept equality_comparable
1090         /// \brief The \c equality_comparable concept
1091         template<typename T>
1092         CPP_concept equality_comparable =
1093             detail::weakly_equality_comparable_with_<T, T>;
1094 
1095         /// \concept equality_comparable_with_
1096         /// \brief The \c equality_comparable_with_ concept
1097         CPP_template(typename T, typename U)(
1098         concept (equality_comparable_with_)(T, U),
1099             equality_comparable<
1100                 common_reference_t<detail::as_cref_t<T>, detail::as_cref_t<U>>>
1101         );
1102         /// \concept equality_comparable_with
1103         /// \brief The \c equality_comparable_with concept
1104         template<typename T, typename U>
1105         CPP_concept equality_comparable_with =
1106             equality_comparable<T> &&
1107             equality_comparable<U> &&
1108             detail::weakly_equality_comparable_with_<T, U> &&
1109             common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> &&
1110             CPP_concept_ref(concepts::equality_comparable_with_, T, U);
1111 
1112         /// \concept totally_ordered
1113         /// \brief The \c totally_ordered concept
1114         template<typename T>
1115         CPP_concept totally_ordered =
1116             equality_comparable<T> &&
1117             detail::partially_ordered_with_<T, T>;
1118 
1119         /// \concept totally_ordered_with_
1120         /// \brief The \c totally_ordered_with_ concept
1121         CPP_template(typename T, typename U)(
1122         concept (totally_ordered_with_)(T, U),
1123             totally_ordered<
1124                 common_reference_t<
1125                     detail::as_cref_t<T>,
1126                     detail::as_cref_t<U>>> CPP_and
1127             detail::partially_ordered_with_<T, U>);
1128 
1129         /// \concept totally_ordered_with
1130         /// \brief The \c totally_ordered_with concept
1131         template<typename T, typename U>
1132         CPP_concept totally_ordered_with =
1133             totally_ordered<T> &&
1134             totally_ordered<U> &&
1135             equality_comparable_with<T, U> &&
1136             CPP_concept_ref(concepts::totally_ordered_with_, T, U);
1137 
1138         ////////////////////////////////////////////////////////////////////////
1139         // Object concepts
1140         ////////////////////////////////////////////////////////////////////////
1141 
1142         /// \concept destructible
1143         /// \brief The \c destructible concept
1144         template<typename T>
1145         CPP_concept destructible =
1146             std::is_nothrow_destructible<T>::value;
1147 
1148         /// \concept constructible_from
1149         /// \brief The \c constructible_from concept
1150         template<typename T, typename... Args>
1151         CPP_concept constructible_from =
1152             destructible<T> &&
1153             META_IS_CONSTRUCTIBLE(T, Args...);
1154 
1155         /// \concept default_constructible
1156         /// \brief The \c default_constructible concept
1157         template<typename T>
1158         CPP_concept default_constructible =
1159             constructible_from<T>;
1160 
1161         /// \concept move_constructible
1162         /// \brief The \c move_constructible concept
1163         template<typename T>
1164         CPP_concept move_constructible =
1165             constructible_from<T, T> &&
1166             convertible_to<T, T>;
1167 
1168         /// \concept copy_constructible_
1169         /// \brief The \c copy_constructible_ concept
1170         CPP_template(typename T)(
1171         concept (copy_constructible_)(T),
1172             constructible_from<T, T &> &&
1173             constructible_from<T, T const &> &&
1174             constructible_from<T, T const> &&
1175             convertible_to<T &, T> &&
1176             convertible_to<T const &, T> &&
1177             convertible_to<T const, T>);
1178         /// \concept copy_constructible
1179         /// \brief The \c copy_constructible concept
1180         template<typename T>
1181         CPP_concept copy_constructible =
1182             move_constructible<T> &&
1183             CPP_concept_ref(concepts::copy_constructible_, T);
1184 
1185         /// \concept move_assignable_
1186         /// \brief The \c move_assignable_ concept
1187         CPP_template(typename T)(
1188         concept (move_assignable_)(T),
1189             assignable_from<T &, T>
1190         );
1191         /// \concept movable
1192         /// \brief The \c movable concept
1193         template<typename T>
1194         CPP_concept movable =
1195             std::is_object<T>::value &&
1196             move_constructible<T> &&
1197             CPP_concept_ref(concepts::move_assignable_, T) &&
1198             swappable<T>;
1199 
1200         /// \concept copy_assignable_
1201         /// \brief The \c copy_assignable_ concept
1202         CPP_template(typename T)(
1203         concept (copy_assignable_)(T),
1204             assignable_from<T &, T const &>
1205         );
1206         /// \concept copyable
1207         /// \brief The \c copyable concept
1208         template<typename T>
1209         CPP_concept copyable =
1210             copy_constructible<T> &&
1211             movable<T> &&
1212             CPP_concept_ref(concepts::copy_assignable_, T);
1213 
1214         /// \concept semiregular
1215         /// \brief The \c semiregular concept
1216         template<typename T>
1217         CPP_concept semiregular =
1218             copyable<T> &&
1219             default_constructible<T>;
1220             // Axiom: copies are independent. See Fundamentals of Generic
1221             // Programming http://www.stepanovpapers.com/DeSt98.pdf
1222 
1223         /// \concept regular
1224         /// \brief The \c regular concept
1225         template<typename T>
1226         CPP_concept regular =
1227             semiregular<T> &&
1228             equality_comparable<T>;
1229 
1230     } // inline namespace defs
1231 } // namespace concepts
1232 
1233 #endif // RANGES_V3_UTILITY_CONCEPTS_HPP