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 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 10 212 #define CPP_auto_member template<typename...> 213 #else 214 #define CPP_auto_member 215 #endif 216 217 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED 218 /// INTERNAL ONLY 219 #define CPP_CTOR_IMPL_1_(...) (__VA_ARGS__) CPP_CTOR_IMPL_2_ 220 #define CPP_CTOR_IMPL_2_(...) __VA_ARGS__ ` 221 #else 222 /// INTERNAL ONLY 223 #define CPP_CTOR_IMPL_1_(...) (__VA_ARGS__) CPP_PP_EXPAND 224 #endif 225 226 /// INTERNAL ONLY 227 #define CPP_TEMPLATE_AUX_(...) \ 228 > CPP_PP_CAT( \ 229 CPP_TEMPLATE_AUX_, \ 230 CPP_TEMPLATE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__) 231 232 /// INTERNAL ONLY 233 #define CPP_TEMPLATE_AUX_WHICH_(FIRST, ...) \ 234 CPP_PP_EVAL( \ 235 CPP_PP_CHECK, \ 236 CPP_PP_CAT(CPP_TEMPLATE_PROBE_CONCEPT_, FIRST)) 237 238 /// INTERNAL ONLY 239 #define CPP_TEMPLATE_PROBE_CONCEPT_concept \ 240 CPP_PP_PROBE(~) 241 242 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED 243 // A template with a requires clause. Turn the requires clause into 244 // a Doxygen precondition block. 245 /// INTERNAL ONLY 246 #define CPP_TEMPLATE_AUX_0(...) __VA_ARGS__` 247 #define requires requires ` 248 249 #else 250 // A template with a requires clause 251 /// INTERNAL ONLY 252 #define CPP_TEMPLATE_AUX_0(...) __VA_ARGS__ 253 #endif 254 255 // A concept definition 256 /// INTERNAL ONLY 257 #define CPP_TEMPLATE_AUX_1(DECL, ...) \ 258 CPP_concept CPP_CONCEPT_NAME_(DECL) = __VA_ARGS__ 259 260 #define CPP_concept_ref(NAME, ...) \ 261 CPP_PP_CAT(NAME, _concept_)<__VA_ARGS__> 262 263 #else // ^^^^ with concepts / without concepts vvvv 264 265 #define CPP_template CPP_template_sfinae 266 #define CPP_template_def CPP_template_def_sfinae 267 #define CPP_member CPP_member_sfinae 268 #define CPP_auto_member CPP_member_sfinae 269 #define CPP_ctor CPP_ctor_sfinae 270 #define CPP_concept_ref(NAME, ...) \ 271 (1u == sizeof(CPP_PP_CAT(NAME, _concept_)( \ 272 (::concepts::detail::tag<__VA_ARGS__>*)nullptr))) 273 274 /// INTERNAL ONLY 275 #define CPP_TEMPLATE_AUX_ CPP_TEMPLATE_SFINAE_AUX_ 276 277 #endif 278 279 #define CPP_template_sfinae(...) \ 280 CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \ 281 template<__VA_ARGS__ CPP_TEMPLATE_SFINAE_AUX_ 282 283 /// INTERNAL ONLY 284 #define CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_concept \ 285 CPP_PP_PROBE(~) 286 287 /// INTERNAL ONLY 288 #define CPP_TEMPLATE_SFINAE_AUX_WHICH_(FIRST, ...) \ 289 CPP_PP_EVAL( \ 290 CPP_PP_CHECK, \ 291 CPP_PP_CAT(CPP_TEMPLATE_SFINAE_PROBE_CONCEPT_, FIRST)) 292 293 /// INTERNAL ONLY 294 #define CPP_TEMPLATE_SFINAE_AUX_(...) \ 295 CPP_PP_CAT( \ 296 CPP_TEMPLATE_SFINAE_AUX_, \ 297 CPP_TEMPLATE_SFINAE_AUX_WHICH_(__VA_ARGS__,))(__VA_ARGS__) 298 299 // A template with a requires clause 300 /// INTERNAL ONLY 301 #define CPP_TEMPLATE_SFINAE_AUX_0(...) , \ 302 bool CPP_true = true, \ 303 std::enable_if_t< \ 304 CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) && \ 305 CPP_BOOL(CPP_true), \ 306 int> = 0> \ 307 CPP_PP_IGNORE_CXX2A_COMPAT_END 308 309 // A concept definition 310 /// INTERNAL ONLY 311 #define CPP_TEMPLATE_SFINAE_AUX_1(DECL, ...) , \ 312 bool CPP_true = true, \ 313 std::enable_if_t<__VA_ARGS__ && CPP_BOOL(CPP_true), int> = 0> \ 314 auto CPP_CONCEPT_NAME_(DECL)( \ 315 ::concepts::detail::tag<CPP_CONCEPT_PARAMS_(DECL)>*) \ 316 -> char(&)[1]; \ 317 auto CPP_CONCEPT_NAME_(DECL)(...) -> char(&)[2] \ 318 CPP_PP_IGNORE_CXX2A_COMPAT_END 319 320 /// INTERNAL ONLY 321 #define CPP_CONCEPT_NAME_(DECL) \ 322 CPP_PP_EVAL( \ 323 CPP_PP_CAT, \ 324 CPP_PP_EVAL(CPP_PP_FIRST, CPP_EAT_CONCEPT_(DECL)), _concept_) 325 326 /// INTERNAL ONLY 327 #define CPP_CONCEPT_PARAMS_(DECL) \ 328 CPP_PP_EVAL(CPP_PP_SECOND, CPP_EAT_CONCEPT_(DECL)) 329 330 /// INTERNAL ONLY 331 #define CPP_EAT_CONCEPT_(DECL) \ 332 CPP_PP_CAT(CPP_EAT_CONCEPT_, DECL) 333 334 /// INTERNAL ONLY 335 #define CPP_EAT_CONCEPT_concept 336 337 #define CPP_and_sfinae \ 338 && CPP_BOOL(CPP_true), int> = 0, std::enable_if_t< 339 340 #define CPP_template_def_sfinae(...) \ 341 template<__VA_ARGS__ CPP_TEMPLATE_DEF_SFINAE_AUX_ 342 343 /// INTERNAL ONLY 344 #define CPP_TEMPLATE_DEF_SFINAE_AUX_(...) , \ 345 bool CPP_true, \ 346 std::enable_if_t< \ 347 CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) && \ 348 CPP_BOOL(CPP_true), \ 349 int>> 350 351 #define CPP_and_sfinae_def \ 352 && CPP_BOOL(CPP_true), int>, std::enable_if_t< 353 354 /// INTERNAL ONLY 355 #define CPP_TEMPLATE_SFINAE_AUX_3_requires 356 357 #define CPP_member_sfinae \ 358 CPP_broken_friend_member 359 360 #define CPP_ctor_sfinae(TYPE) \ 361 CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN \ 362 TYPE CPP_CTOR_SFINAE_IMPL_1_ 363 364 /// INTERNAL ONLY 365 #define CPP_CTOR_SFINAE_IMPL_1_(...) \ 366 (__VA_ARGS__ \ 367 CPP_PP_COMMA_IIF( \ 368 CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__))) \ 369 CPP_CTOR_SFINAE_REQUIRES 370 371 /// INTERNAL ONLY 372 #define CPP_CTOR_SFINAE_PROBE_NOEXCEPT_noexcept \ 373 CPP_PP_PROBE(~) 374 375 /// INTERNAL ONLY 376 #define CPP_CTOR_SFINAE_MAKE_PROBE(FIRST,...) \ 377 CPP_PP_CAT(CPP_CTOR_SFINAE_PROBE_NOEXCEPT_, FIRST) 378 379 /// INTERNAL ONLY 380 #define CPP_CTOR_SFINAE_REQUIRES(...) \ 381 CPP_PP_CAT( \ 382 CPP_CTOR_SFINAE_REQUIRES_, \ 383 CPP_PP_EVAL( \ 384 CPP_PP_CHECK, \ 385 CPP_CTOR_SFINAE_MAKE_PROBE(__VA_ARGS__,)))(__VA_ARGS__) 386 387 // No noexcept-clause: 388 /// INTERNAL ONLY 389 #define CPP_CTOR_SFINAE_REQUIRES_0(...) \ 390 std::enable_if_t< \ 391 CPP_PP_CAT(CPP_TEMPLATE_SFINAE_AUX_3_, __VA_ARGS__) && CPP_TRUE_FN, \ 392 ::concepts::detail::Nil \ 393 > = {}) \ 394 CPP_PP_IGNORE_CXX2A_COMPAT_END 395 396 // Yes noexcept-clause: 397 /// INTERNAL ONLY 398 #define CPP_CTOR_SFINAE_REQUIRES_1(...) \ 399 std::enable_if_t< \ 400 CPP_PP_EVAL(CPP_PP_CAT, \ 401 CPP_TEMPLATE_SFINAE_AUX_3_, \ 402 CPP_PP_CAT(CPP_CTOR_SFINAE_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN,\ 403 ::concepts::detail::Nil \ 404 > = {}) \ 405 CPP_PP_EXPAND(CPP_PP_CAT(CPP_CTOR_SFINAE_SHOW_NOEXCEPT_, __VA_ARGS__))) 406 407 /// INTERNAL ONLY 408 #define CPP_CTOR_SFINAE_EAT_NOEXCEPT_noexcept(...) 409 410 /// INTERNAL ONLY 411 #define CPP_CTOR_SFINAE_SHOW_NOEXCEPT_noexcept(...) \ 412 noexcept(__VA_ARGS__) \ 413 CPP_PP_IGNORE_CXX2A_COMPAT_END \ 414 CPP_PP_EAT CPP_PP_LPAREN 415 416 #ifdef CPP_DOXYGEN_INVOKED 417 #define CPP_broken_friend_ret(...) \ 418 __VA_ARGS__ CPP_PP_EXPAND 419 420 #else // ^^^ CPP_DOXYGEN_INVOKED / not CPP_DOXYGEN_INVOKED vvv 421 #define CPP_broken_friend_ret(...) \ 422 ::concepts::return_t< \ 423 __VA_ARGS__, \ 424 std::enable_if_t<CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_ 425 426 /// INTERNAL ONLY 427 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_(...) \ 428 CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(CPP_PP_CAT( \ 429 CPP_TEMPLATE_AUX_2_, __VA_ARGS__)) 430 431 /// INTERNAL ONLY 432 #define CPP_TEMPLATE_AUX_2_requires 433 434 /// INTERNAL ONLY 435 #define CPP_BROKEN_FRIEND_RETURN_TYPE_AUX_3_(...) \ 436 (__VA_ARGS__ && CPP_TRUE_FN)>> 437 438 #ifdef CPP_WORKAROUND_MSVC_779763 439 #define CPP_broken_friend_member \ 440 template<::concepts::detail::CPP_true_t const &CPP_true_fn = \ 441 ::concepts::detail::CPP_true_fn_> 442 443 #else // ^^^ workaround / no workaround vvv 444 #define CPP_broken_friend_member \ 445 template<bool (&CPP_true_fn)(::concepts::detail::xNil) = \ 446 ::concepts::detail::CPP_true_fn> 447 448 #endif // CPP_WORKAROUND_MSVC_779763 449 #endif 450 451 #if CPP_CXX_CONCEPTS 452 #define CPP_requires(NAME, REQS) \ 453 CPP_concept CPP_PP_CAT(NAME, _requires_) = \ 454 CPP_PP_CAT(CPP_REQUIRES_, REQS) 455 456 #define CPP_requires_ref(NAME, ...) \ 457 CPP_PP_CAT(NAME, _requires_)<__VA_ARGS__> 458 459 /// INTERNAL ONLY 460 #define CPP_REQUIRES_requires(...) \ 461 requires(__VA_ARGS__) CPP_REQUIRES_AUX_ 462 463 /// INTERNAL ONLY 464 #define CPP_REQUIRES_AUX_(...) \ 465 { __VA_ARGS__; } 466 467 #else 468 #define CPP_requires(NAME, REQS) \ 469 auto CPP_PP_CAT(NAME, _requires_test_) \ 470 CPP_REQUIRES_AUX_(NAME, CPP_REQUIRES_ ## REQS) 471 472 #define CPP_requires_ref(NAME, ...) \ 473 (1u == sizeof(CPP_PP_CAT(NAME, _requires_)( \ 474 (::concepts::detail::tag<__VA_ARGS__>*)nullptr))) 475 476 /// INTERNAL ONLY 477 #define CPP_REQUIRES_requires(...) \ 478 (__VA_ARGS__) -> decltype CPP_REQUIRES_RETURN_ 479 480 /// INTERNAL ONLY 481 #define CPP_REQUIRES_RETURN_(...) (__VA_ARGS__, void()) {} 482 483 /// INTERNAL ONLY 484 #define CPP_REQUIRES_AUX_(NAME, ...) \ 485 __VA_ARGS__ \ 486 template<typename... As> \ 487 auto CPP_PP_CAT(NAME, _requires_)( \ 488 ::concepts::detail::tag<As...> *, \ 489 decltype(&CPP_PP_CAT(NAME, _requires_test_)<As...>) = nullptr) \ 490 -> char(&)[1]; \ 491 auto CPP_PP_CAT(NAME, _requires_)(...) -> char(&)[2] 492 493 #endif 494 495 #if CPP_CXX_CONCEPTS 496 497 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED 498 #define CPP_ret(...) \ 499 __VA_ARGS__ CPP_RET_AUX_ 500 #define CPP_RET_AUX_(...) __VA_ARGS__ ` 501 #else 502 #define CPP_ret(...) \ 503 __VA_ARGS__ CPP_PP_EXPAND 504 #endif 505 506 #else 507 #define CPP_ret \ 508 CPP_broken_friend_ret 509 510 #endif 511 512 //////////////////////////////////////////////////////////////////////////////// 513 // CPP_fun 514 #if CPP_CXX_CONCEPTS 515 516 #if defined(CPP_DOXYGEN_INVOKED) && CPP_DOXYGEN_INVOKED 517 /// INTERNAL ONLY 518 #define CPP_FUN_IMPL_1_(...) \ 519 (__VA_ARGS__) \ 520 CPP_FUN_IMPL_2_ 521 #define CPP_FUN_IMPL_2_(...) \ 522 __VA_ARGS__ ` 523 #else 524 /// INTERNAL ONLY 525 #define CPP_FUN_IMPL_1_(...) \ 526 (__VA_ARGS__) \ 527 CPP_PP_EXPAND 528 #endif 529 530 #define CPP_fun(X) X CPP_FUN_IMPL_1_ 531 #else 532 /// INTERNAL ONLY 533 #define CPP_FUN_IMPL_1_(...) \ 534 (__VA_ARGS__ \ 535 CPP_PP_COMMA_IIF( \ 536 CPP_PP_NOT(CPP_PP_IS_NOT_EMPTY(__VA_ARGS__))) \ 537 CPP_FUN_IMPL_REQUIRES 538 539 /// INTERNAL ONLY 540 #define CPP_FUN_IMPL_REQUIRES(...) \ 541 CPP_PP_EVAL2_( \ 542 CPP_FUN_IMPL_SELECT_CONST_, \ 543 (__VA_ARGS__,) \ 544 )(__VA_ARGS__) 545 546 /// INTERNAL ONLY 547 #define CPP_FUN_IMPL_SELECT_CONST_(MAYBE_CONST, ...) \ 548 CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_, \ 549 CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT( \ 550 CPP_PP_PROBE_CONST_PROBE_, MAYBE_CONST))) 551 552 /// INTERNAL ONLY 553 #define CPP_PP_PROBE_CONST_PROBE_const CPP_PP_PROBE(~) 554 555 /// INTERNAL ONLY 556 #define CPP_FUN_IMPL_SELECT_CONST_1(...) \ 557 CPP_PP_EVAL( \ 558 CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_, \ 559 CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__),)( \ 560 CPP_PP_CAT(CPP_FUN_IMPL_EAT_CONST_, __VA_ARGS__)) 561 562 /// INTERNAL ONLY 563 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...) \ 564 CPP_PP_CAT(CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_, \ 565 CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT( \ 566 CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT))) 567 568 /// INTERNAL ONLY 569 #define CPP_PP_PROBE_NOEXCEPT_PROBE_noexcept CPP_PP_PROBE(~) 570 571 /// INTERNAL ONLY 572 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_0(...) \ 573 std::enable_if_t< \ 574 CPP_PP_EVAL( \ 575 CPP_PP_CAT, \ 576 CPP_FUN_IMPL_EAT_REQUIRES_, \ 577 __VA_ARGS__) && CPP_TRUE_FN, \ 578 ::concepts::detail::Nil \ 579 > = {}) const \ 580 CPP_PP_IGNORE_CXX2A_COMPAT_END 581 582 /// INTERNAL ONLY 583 #define CPP_FUN_IMPL_SELECT_CONST_NOEXCEPT_1(...) \ 584 std::enable_if_t< \ 585 CPP_PP_EVAL( \ 586 CPP_PP_CAT, \ 587 CPP_FUN_IMPL_EAT_REQUIRES_, \ 588 CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__)) && CPP_TRUE_FN, \ 589 ::concepts::detail::Nil \ 590 > = {}) const \ 591 CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__))) 592 593 /// INTERNAL ONLY 594 #define CPP_FUN_IMPL_EAT_NOEXCEPT_noexcept(...) 595 596 /// INTERNAL ONLY 597 #define CPP_FUN_IMPL_SHOW_NOEXCEPT_noexcept(...) \ 598 noexcept(__VA_ARGS__) CPP_PP_IGNORE_CXX2A_COMPAT_END \ 599 CPP_PP_EAT CPP_PP_LPAREN 600 601 /// INTERNAL ONLY 602 #define CPP_FUN_IMPL_SELECT_CONST_0(...) \ 603 CPP_PP_EVAL_( \ 604 CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_, \ 605 (__VA_ARGS__,) \ 606 )(__VA_ARGS__) 607 608 /// INTERNAL ONLY 609 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_(MAYBE_NOEXCEPT, ...) \ 610 CPP_PP_CAT(CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_, \ 611 CPP_PP_EVAL2(CPP_PP_CHECK, CPP_PP_CAT( \ 612 CPP_PP_PROBE_NOEXCEPT_PROBE_, MAYBE_NOEXCEPT))) 613 614 /// INTERNAL ONLY 615 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_0(...) \ 616 std::enable_if_t< \ 617 CPP_PP_CAT(CPP_FUN_IMPL_EAT_REQUIRES_, __VA_ARGS__) && CPP_TRUE_FN, \ 618 ::concepts::detail::Nil \ 619 > = {}) \ 620 CPP_PP_IGNORE_CXX2A_COMPAT_END 621 622 /// INTERNAL ONLY 623 #define CPP_FUN_IMPL_SELECT_NONCONST_NOEXCEPT_1(...) \ 624 std::enable_if_t< \ 625 CPP_PP_EVAL( \ 626 CPP_PP_CAT, \ 627 CPP_FUN_IMPL_EAT_REQUIRES_, \ 628 CPP_PP_CAT(CPP_FUN_IMPL_EAT_NOEXCEPT_, __VA_ARGS__) \ 629 ) && CPP_TRUE_FN, \ 630 ::concepts::detail::Nil \ 631 > = {}) \ 632 CPP_PP_EXPAND(CPP_PP_CAT(CPP_FUN_IMPL_SHOW_NOEXCEPT_, __VA_ARGS__))) 633 634 /// INTERNAL ONLY 635 #define CPP_FUN_IMPL_EAT_CONST_const 636 637 /// INTERNAL ONLY 638 #define CPP_FUN_IMPL_EAT_REQUIRES_requires 639 640 //////////////////////////////////////////////////////////////////////////////// 641 // CPP_fun 642 // Usage: 643 // template <typename A, typename B> 644 // void CPP_fun(foo)(A a, B b)([const]opt [noexcept(true)]opt 645 // requires Concept1<A> && Concept2<B>) 646 // {} 647 // 648 // Note: This macro cannot be used when the last function argument is a 649 // parameter pack. 650 #define CPP_fun(X) CPP_PP_IGNORE_CXX2A_COMPAT_BEGIN X CPP_FUN_IMPL_1_ 651 #endif 652 653 //////////////////////////////////////////////////////////////////////////////// 654 // CPP_auto_fun 655 // Usage: 656 // template <typename A, typename B> 657 // auto CPP_auto_fun(foo)(A a, B b)([const]opt [noexcept(cond)]opt)opt 658 // ( 659 // return a + b 660 // ) 661 #define CPP_auto_fun(X) X CPP_AUTO_FUN_IMPL_ 662 663 /// INTERNAL ONLY 664 #define CPP_AUTO_FUN_IMPL_(...) (__VA_ARGS__) CPP_AUTO_FUN_RETURNS_ 665 666 /// INTERNAL ONLY 667 #define CPP_AUTO_FUN_RETURNS_(...) \ 668 CPP_PP_EVAL2_( \ 669 CPP_AUTO_FUN_SELECT_RETURNS_, \ 670 (__VA_ARGS__,) \ 671 )(__VA_ARGS__) 672 673 /// INTERNAL ONLY 674 #define CPP_AUTO_FUN_SELECT_RETURNS_(MAYBE_CONST, ...) \ 675 CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_CONST_, \ 676 CPP_PP_EVAL(CPP_PP_CHECK, CPP_PP_CAT( \ 677 CPP_PP_PROBE_CONST_MUTABLE_PROBE_, MAYBE_CONST))) 678 679 /// INTERNAL ONLY 680 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_const CPP_PP_PROBE_N(~, 1) 681 682 /// INTERNAL ONLY 683 #define CPP_PP_PROBE_CONST_MUTABLE_PROBE_mutable CPP_PP_PROBE_N(~, 2) 684 685 /// INTERNAL ONLY 686 #define CPP_PP_EAT_MUTABLE_mutable 687 688 /// INTERNAL ONLY 689 #define CPP_AUTO_FUN_RETURNS_CONST_2(...) \ 690 CPP_PP_CAT(CPP_PP_EAT_MUTABLE_, __VA_ARGS__) CPP_AUTO_FUN_RETURNS_CONST_0 691 692 /// INTERNAL ONLY 693 #define CPP_AUTO_FUN_RETURNS_CONST_1(...) \ 694 __VA_ARGS__ CPP_AUTO_FUN_RETURNS_CONST_0 695 696 /// INTERNAL ONLY 697 #define CPP_AUTO_FUN_RETURNS_CONST_0(...) \ 698 CPP_PP_EVAL(CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_, \ 699 CPP_PP_CAT(CPP_AUTO_FUN_RETURNS_, __VA_ARGS__)) 700 701 /// INTERNAL ONLY 702 #define CPP_AUTO_FUN_RETURNS_return 703 704 #ifdef __cpp_guaranteed_copy_elision 705 /// INTERNAL ONLY 706 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...) \ 707 noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) \ 708 { return (__VA_ARGS__); } 709 710 #else 711 /// INTERNAL ONLY 712 #define CPP_AUTO_FUN_DECLTYPE_NOEXCEPT_(...) \ 713 noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) -> \ 714 decltype(__VA_ARGS__) \ 715 { return (__VA_ARGS__); } 716 717 #endif 718 719 namespace concepts 720 { 721 template<bool B> 722 using bool_ = std::integral_constant<bool, B>; 723 724 #if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603 725 template<bool...Bs> 726 CPP_INLINE_VAR constexpr bool and_v = (Bs &&...); 727 728 template<bool...Bs> 729 CPP_INLINE_VAR constexpr bool or_v = (Bs ||...); 730 #else 731 namespace detail 732 { 733 template<bool...> 734 struct bools; 735 } // namespace detail 736 737 template<bool...Bs> 738 CPP_INLINE_VAR constexpr bool and_v = 739 META_IS_SAME(detail::bools<Bs..., true>, detail::bools<true, Bs...>); 740 741 template<bool...Bs> 742 CPP_INLINE_VAR constexpr bool or_v = 743 !META_IS_SAME(detail::bools<Bs..., false>, detail::bools<false, Bs...>); 744 #endif 745 746 template<typename> 747 struct return_t_ 748 { 749 template<typename T> 750 using invoke = T; 751 }; 752 753 template<typename T, typename EnableIf> 754 using return_t = meta::invoke<return_t_<EnableIf>, T>; 755 756 namespace detail 757 { 758 struct ignore 759 { 760 template<class... Args> ignoreconcepts::detail::ignore761 constexpr ignore(Args&&...) noexcept {} 762 }; 763 764 template<class> true_()765 constexpr bool true_() 766 { 767 return true; 768 } 769 770 template<typename...> 771 struct tag; 772 773 template<typename T> 774 CPP_INLINE_VAR constexpr T instance_ = T{}; 775 776 template<typename> requires_()777 constexpr bool requires_() 778 { 779 return true; 780 } 781 782 struct Nil 783 {}; 784 785 #ifdef CPP_WORKAROUND_MSVC_779763 786 enum class xNil {}; 787 788 struct CPP_true_t 789 { operator ()concepts::detail::CPP_true_t790 constexpr bool operator()(Nil) const noexcept 791 { 792 return true; 793 } operator ()concepts::detail::CPP_true_t794 constexpr bool operator()(xNil) const noexcept 795 { 796 return true; 797 } 798 }; 799 800 CPP_INLINE_VAR constexpr CPP_true_t CPP_true_fn_ {}; 801 CPP_true_fn(xNil)802 constexpr bool CPP_true_fn(xNil) 803 { 804 return true; 805 } 806 #else 807 using xNil = Nil; 808 #endif 809 CPP_true_fn(Nil)810 constexpr bool CPP_true_fn(Nil) 811 { 812 return true; 813 } 814 } // namespace detail 815 816 #if defined(__clang__) || defined(_MSC_VER) 817 template<bool B> requires_()818 std::enable_if_t<B> requires_() 819 {} 820 #else 821 template<bool B> 822 CPP_INLINE_VAR constexpr std::enable_if_t<B, int> requires_ = 0; 823 #endif 824 825 inline namespace defs 826 { 827 //////////////////////////////////////////////////////////////////////// 828 // Utility concepts 829 //////////////////////////////////////////////////////////////////////// 830 831 template<bool B> 832 CPP_concept is_true = B; 833 834 template<typename... Args> 835 CPP_concept type = true; 836 837 template<class T, template<typename...> class Trait, typename... Args> 838 CPP_concept satisfies = 839 static_cast<bool>(Trait<T, Args...>::type::value); 840 841 //////////////////////////////////////////////////////////////////////// 842 // Core language concepts 843 //////////////////////////////////////////////////////////////////////// 844 845 template<typename A, typename B> 846 CPP_concept same_as = 847 META_IS_SAME(A, B) && META_IS_SAME(B, A); 848 849 /// \cond 850 template<typename A, typename B> 851 CPP_concept not_same_as_ = 852 (!same_as<remove_cvref_t<A>, remove_cvref_t<B>>); 853 854 // Workaround bug in the Standard Library: 855 // From cannot be an incomplete class type despite that 856 // is_convertible<X, Y> should be equivalent to is_convertible<X&&, Y> 857 // in such a case. 858 template<typename From, typename To> 859 CPP_concept implicitly_convertible_to = 860 std::is_convertible<std::add_rvalue_reference_t<From>, To>::value; 861 862 template<typename From, typename To> 863 CPP_requires(explicitly_convertible_to_, 864 requires(From(*from)()) // 865 ( 866 static_cast<To>(from()) 867 )); 868 template<typename From, typename To> 869 CPP_concept explicitly_convertible_to = 870 CPP_requires_ref(concepts::explicitly_convertible_to_, From, To); 871 /// \endcond 872 873 template<typename From, typename To> 874 CPP_concept convertible_to = 875 implicitly_convertible_to<From, To> && 876 explicitly_convertible_to<From, To>; 877 878 CPP_template(typename T, typename U)( 879 concept (derived_from_)(T, U), 880 convertible_to<T const volatile *, U const volatile *> 881 ); 882 template<typename T, typename U> 883 CPP_concept derived_from = 884 META_IS_BASE_OF(U, T) && 885 CPP_concept_ref(concepts::derived_from_, T, U); 886 887 CPP_template(typename T, typename U)( 888 concept (common_reference_with_)(T, U), 889 same_as<common_reference_t<T, U>, common_reference_t<U, T>> CPP_and 890 convertible_to<T, common_reference_t<T, U>> CPP_and 891 convertible_to<U, common_reference_t<T, U>> 892 ); 893 template<typename T, typename U> 894 CPP_concept common_reference_with = 895 CPP_concept_ref(concepts::common_reference_with_, T, U); 896 897 CPP_template(typename T, typename U)( 898 concept (common_with_)(T, U), 899 same_as<common_type_t<T, U>, common_type_t<U, T>> CPP_and 900 convertible_to<T, common_type_t<T, U>> CPP_and 901 convertible_to<U, common_type_t<T, U>> CPP_and 902 common_reference_with< 903 std::add_lvalue_reference_t<T const>, 904 std::add_lvalue_reference_t<U const>> CPP_and 905 common_reference_with< 906 std::add_lvalue_reference_t<common_type_t<T, U>>, 907 common_reference_t< 908 std::add_lvalue_reference_t<T const>, 909 std::add_lvalue_reference_t<U const>>> 910 ); 911 template<typename T, typename U> 912 CPP_concept common_with = 913 CPP_concept_ref(concepts::common_with_, T, U); 914 915 template<typename T> 916 CPP_concept integral = 917 std::is_integral<T>::value; 918 919 template<typename T> 920 CPP_concept signed_integral = 921 integral<T> && 922 std::is_signed<T>::value; 923 924 template<typename T> 925 CPP_concept unsigned_integral = 926 integral<T> && 927 !signed_integral<T>; 928 929 template<typename T, typename U> 930 CPP_requires(assignable_from_, 931 requires(T t, U && u) // 932 ( 933 t = (U &&) u, 934 requires_<same_as<T, decltype(t = (U &&) u)>> 935 )); 936 template<typename T, typename U> 937 CPP_concept assignable_from = 938 std::is_lvalue_reference<T>::value && 939 common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> && 940 CPP_requires_ref(defs::assignable_from_, T, U); 941 942 template<typename T> 943 CPP_requires(swappable_, 944 requires(T & t, T & u) // 945 ( 946 concepts::swap(t, u) 947 )); 948 template<typename T> 949 CPP_concept swappable = 950 CPP_requires_ref(defs::swappable_, T); 951 952 template<typename T, typename U> 953 CPP_requires(swappable_with_, 954 requires(T && t, U && u) // 955 ( 956 concepts::swap((T &&) t, (T &&) t), 957 concepts::swap((U &&) u, (U &&) u), 958 concepts::swap((U &&) u, (T &&) t), 959 concepts::swap((T &&) t, (U &&) u) 960 )); 961 template<typename T, typename U> 962 CPP_concept swappable_with = 963 common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> && 964 CPP_requires_ref(defs::swappable_with_, T, U); 965 966 } // inline namespace defs 967 968 namespace detail 969 { 970 template<typename T> 971 CPP_concept boolean_testable_impl_ = convertible_to<T, bool>; 972 973 template<typename T> 974 CPP_requires(boolean_testable_frag_, 975 requires(T && t) // 976 ( 977 !(T&&) t, 978 concepts::requires_<boolean_testable_impl_<decltype(!(T&&) t)>> 979 )); 980 981 template<typename T> 982 CPP_concept boolean_testable_ = 983 CPP_requires_ref(boolean_testable_frag_, T) && 984 boolean_testable_impl_<T>; 985 986 CPP_DIAGNOSTIC_PUSH 987 CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL 988 989 template<typename T, typename U> 990 CPP_requires(weakly_equality_comparable_with_frag_, 991 requires(detail::as_cref_t<T> t, detail::as_cref_t<U> u) // 992 ( 993 concepts::requires_<boolean_testable_<decltype(t == u)>>, 994 concepts::requires_<boolean_testable_<decltype(t != u)>>, 995 concepts::requires_<boolean_testable_<decltype(u == t)>>, 996 concepts::requires_<boolean_testable_<decltype(u != t)>> 997 )); 998 template<typename T, typename U> 999 CPP_concept weakly_equality_comparable_with_ = 1000 CPP_requires_ref(weakly_equality_comparable_with_frag_, T, U); 1001 1002 template<typename T, typename U> 1003 CPP_requires(partially_ordered_with_frag_, 1004 requires(detail::as_cref_t<T>& t, detail::as_cref_t<U>& u) // 1005 ( 1006 concepts::requires_<boolean_testable_<decltype(t < u)>>, 1007 concepts::requires_<boolean_testable_<decltype(t > u)>>, 1008 concepts::requires_<boolean_testable_<decltype(t <= u)>>, 1009 concepts::requires_<boolean_testable_<decltype(t >= u)>>, 1010 concepts::requires_<boolean_testable_<decltype(u < t)>>, 1011 concepts::requires_<boolean_testable_<decltype(u > t)>>, 1012 concepts::requires_<boolean_testable_<decltype(u <= t)>>, 1013 concepts::requires_<boolean_testable_<decltype(u >= t)>> 1014 )); 1015 template<typename T, typename U> 1016 CPP_concept partially_ordered_with_ = 1017 CPP_requires_ref(partially_ordered_with_frag_, T, U); 1018 1019 CPP_DIAGNOSTIC_POP 1020 } // namespace detail 1021 1022 inline namespace defs 1023 { 1024 //////////////////////////////////////////////////////////////////////// 1025 // Comparison concepts 1026 //////////////////////////////////////////////////////////////////////// 1027 1028 template<typename T> 1029 CPP_concept equality_comparable = 1030 detail::weakly_equality_comparable_with_<T, T>; 1031 1032 CPP_template(typename T, typename U)( 1033 concept (equality_comparable_with_)(T, U), 1034 equality_comparable< 1035 common_reference_t<detail::as_cref_t<T>, detail::as_cref_t<U>>> 1036 ); 1037 template<typename T, typename U> 1038 CPP_concept equality_comparable_with = 1039 equality_comparable<T> && 1040 equality_comparable<U> && 1041 detail::weakly_equality_comparable_with_<T, U> && 1042 common_reference_with<detail::as_cref_t<T>, detail::as_cref_t<U>> && 1043 CPP_concept_ref(concepts::equality_comparable_with_, T, U); 1044 1045 template<typename T> 1046 CPP_concept totally_ordered = 1047 equality_comparable<T> && 1048 detail::partially_ordered_with_<T, T>; 1049 1050 CPP_template(typename T, typename U)( 1051 concept (totally_ordered_with_)(T, U), 1052 totally_ordered< 1053 common_reference_t< 1054 detail::as_cref_t<T>, 1055 detail::as_cref_t<U>>> CPP_and 1056 detail::partially_ordered_with_<T, U>); 1057 1058 template<typename T, typename U> 1059 CPP_concept totally_ordered_with = 1060 totally_ordered<T> && 1061 totally_ordered<U> && 1062 equality_comparable_with<T, U> && 1063 CPP_concept_ref(concepts::totally_ordered_with_, T, U); 1064 1065 //////////////////////////////////////////////////////////////////////// 1066 // Object concepts 1067 //////////////////////////////////////////////////////////////////////// 1068 1069 template<typename T> 1070 CPP_concept destructible = 1071 std::is_nothrow_destructible<T>::value; 1072 1073 template<typename T, typename... Args> 1074 CPP_concept constructible_from = 1075 destructible<T> && 1076 META_IS_CONSTRUCTIBLE(T, Args...); 1077 1078 template<typename T> 1079 CPP_concept default_constructible = 1080 constructible_from<T>; 1081 1082 template<typename T> 1083 CPP_concept move_constructible = 1084 constructible_from<T, T> && 1085 convertible_to<T, T>; 1086 1087 CPP_template(typename T)( 1088 concept (copy_constructible_)(T), 1089 constructible_from<T, T &> && 1090 constructible_from<T, T const &> && 1091 constructible_from<T, T const> && 1092 convertible_to<T &, T> && 1093 convertible_to<T const &, T> && 1094 convertible_to<T const, T>); 1095 template<typename T> 1096 CPP_concept copy_constructible = 1097 move_constructible<T> && 1098 CPP_concept_ref(concepts::copy_constructible_, T); 1099 1100 CPP_template(typename T)( 1101 concept (move_assignable_)(T), 1102 assignable_from<T &, T> 1103 ); 1104 template<typename T> 1105 CPP_concept movable = 1106 std::is_object<T>::value && 1107 move_constructible<T> && 1108 CPP_concept_ref(concepts::move_assignable_, T) && 1109 swappable<T>; 1110 1111 CPP_template(typename T)( 1112 concept (copy_assignable_)(T), 1113 assignable_from<T &, T const &> 1114 ); 1115 template<typename T> 1116 CPP_concept copyable = 1117 copy_constructible<T> && 1118 movable<T> && 1119 CPP_concept_ref(concepts::copy_assignable_, T); 1120 1121 template<typename T> 1122 CPP_concept semiregular = 1123 copyable<T> && 1124 default_constructible<T>; 1125 // Axiom: copies are independent. See Fundamentals of Generic 1126 // Programming http://www.stepanovpapers.com/DeSt98.pdf 1127 1128 template<typename T> 1129 CPP_concept regular = 1130 semiregular<T> && 1131 equality_comparable<T>; 1132 1133 } // inline namespace defs 1134 } // namespace concepts 1135 1136 #endif // RANGES_V3_UTILITY_CONCEPTS_HPP 1137