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