ax_cxx_compile_stdcxx.m4 (23055B)
1 # =========================================================================== 2 # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html 3 # =========================================================================== 4 # 5 # SYNOPSIS 6 # 7 # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) 8 # 9 # DESCRIPTION 10 # 11 # Check for baseline language coverage in the compiler for the specified 12 # version of the C++ standard. If necessary, add switches to CXX and 13 # CXXCPP to enable support. VERSION may be '11', '14', '17', '20', or 14 # '23' for the respective C++ standard version. 15 # 16 # The second argument, if specified, indicates whether you insist on an 17 # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. 18 # -std=c++11). If neither is specified, you get whatever works, with 19 # preference for no added switch, and then for an extended mode. 20 # 21 # The third argument, if specified 'mandatory' or if left unspecified, 22 # indicates that baseline support for the specified C++ standard is 23 # required and that the macro should error out if no mode with that 24 # support is found. If specified 'optional', then configuration proceeds 25 # regardless, after defining HAVE_CXX${VERSION} if and only if a 26 # supporting mode is found. 27 # 28 # LICENSE 29 # 30 # Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> 31 # Copyright (c) 2012 Zack Weinberg <zackw@panix.com> 32 # Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> 33 # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> 34 # Copyright (c) 2015 Paul Norman <penorman@mac.com> 35 # Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> 36 # Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> 37 # Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com> 38 # Copyright (c) 2020 Jason Merrill <jason@redhat.com> 39 # Copyright (c) 2021, 2024 Jörn Heusipp <osmanx@problemloesungsmaschine.de> 40 # Copyright (c) 2015, 2022, 2023, 2024 Olly Betts 41 # 42 # Copying and distribution of this file, with or without modification, are 43 # permitted in any medium without royalty provided the copyright notice 44 # and this notice are preserved. This file is offered as-is, without any 45 # warranty. 46 47 #serial 25 48 49 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro 50 dnl (serial version number 13). 51 52 AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl 53 m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], 54 [$1], [14], [ax_cxx_compile_alternatives="14 1y"], 55 [$1], [17], [ax_cxx_compile_alternatives="17 1z"], 56 [$1], [20], [ax_cxx_compile_alternatives="20"], 57 [$1], [23], [ax_cxx_compile_alternatives="23"], 58 [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl 59 m4_if([$2], [], [], 60 [$2], [ext], [], 61 [$2], [noext], [], 62 [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl 63 m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], 64 [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], 65 [$3], [optional], [ax_cxx_compile_cxx$1_required=false], 66 [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) 67 AC_LANG_PUSH([C++])dnl 68 ac_success=no 69 70 m4_if([$2], [], [dnl 71 AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, 72 ax_cv_cxx_compile_cxx$1, 73 [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 74 [ax_cv_cxx_compile_cxx$1=yes], 75 [ax_cv_cxx_compile_cxx$1=no])]) 76 if test x$ax_cv_cxx_compile_cxx$1 = xyes; then 77 ac_success=yes 78 fi]) 79 80 m4_if([$2], [noext], [], [dnl 81 if test x$ac_success = xno; then 82 for alternative in ${ax_cxx_compile_alternatives}; do 83 switch="-std=gnu++${alternative}" 84 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 85 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 86 $cachevar, 87 [ac_save_CXX="$CXX" 88 CXX="$CXX $switch" 89 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 90 [eval $cachevar=yes], 91 [eval $cachevar=no]) 92 CXX="$ac_save_CXX"]) 93 if eval test x\$$cachevar = xyes; then 94 CXX="$CXX $switch" 95 if test -n "$CXXCPP" ; then 96 CXXCPP="$CXXCPP $switch" 97 fi 98 ac_success=yes 99 break 100 fi 101 done 102 fi]) 103 104 m4_if([$2], [ext], [], [dnl 105 if test x$ac_success = xno; then 106 dnl HP's aCC needs +std=c++11 according to: 107 dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf 108 dnl Cray's crayCC needs "-h std=c++11" 109 dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) 110 for alternative in ${ax_cxx_compile_alternatives}; do 111 for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do 112 if test x"$switch" = xMSVC; then 113 dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide 114 dnl with -std=c++17. We suffix the cache variable name with _MSVC to 115 dnl avoid this. 116 switch=-std:c++${alternative} 117 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) 118 else 119 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 120 fi 121 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 122 $cachevar, 123 [ac_save_CXX="$CXX" 124 CXX="$CXX $switch" 125 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 126 [eval $cachevar=yes], 127 [eval $cachevar=no]) 128 CXX="$ac_save_CXX"]) 129 if eval test x\$$cachevar = xyes; then 130 CXX="$CXX $switch" 131 if test -n "$CXXCPP" ; then 132 CXXCPP="$CXXCPP $switch" 133 fi 134 ac_success=yes 135 break 136 fi 137 done 138 if test x$ac_success = xyes; then 139 break 140 fi 141 done 142 fi]) 143 AC_LANG_POP([C++]) 144 if test x$ax_cxx_compile_cxx$1_required = xtrue; then 145 if test x$ac_success = xno; then 146 AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) 147 fi 148 fi 149 if test x$ac_success = xno; then 150 HAVE_CXX$1=0 151 AC_MSG_NOTICE([No compiler with C++$1 support was found]) 152 else 153 HAVE_CXX$1=1 154 AC_DEFINE(HAVE_CXX$1,1, 155 [define if the compiler supports basic C++$1 syntax]) 156 fi 157 AC_SUBST(HAVE_CXX$1) 158 ]) 159 160 161 dnl Test body for checking C++11 support 162 163 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], 164 [_AX_CXX_COMPILE_STDCXX_testbody_new_in_11] 165 ) 166 167 dnl Test body for checking C++14 support 168 169 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], 170 [_AX_CXX_COMPILE_STDCXX_testbody_new_in_11 171 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14] 172 ) 173 174 dnl Test body for checking C++17 support 175 176 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], 177 [_AX_CXX_COMPILE_STDCXX_testbody_new_in_11 178 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 179 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17] 180 ) 181 182 dnl Test body for checking C++20 support 183 184 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], 185 [_AX_CXX_COMPILE_STDCXX_testbody_new_in_11 186 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 187 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 188 _AX_CXX_COMPILE_STDCXX_testbody_new_in_20] 189 ) 190 191 dnl Test body for checking C++23 support 192 193 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_23], 194 [_AX_CXX_COMPILE_STDCXX_testbody_new_in_11 195 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 196 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 197 _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 198 _AX_CXX_COMPILE_STDCXX_testbody_new_in_23] 199 ) 200 201 202 dnl Tests for new features in C++11 203 204 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ 205 206 // If the compiler admits that it is not ready for C++11, why torture it? 207 // Hopefully, this will speed up the test. 208 209 #ifndef __cplusplus 210 211 #error "This is not a C++ compiler" 212 213 // MSVC always sets __cplusplus to 199711L in older versions; newer versions 214 // only set it correctly if /Zc:__cplusplus is specified as well as a 215 // /std:c++NN switch: 216 // 217 // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ 218 // 219 // The value __cplusplus ought to have is available in _MSVC_LANG since 220 // Visual Studio 2015 Update 3: 221 // 222 // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros 223 // 224 // This was also the first MSVC version to support C++14 so we can't use the 225 // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having 226 // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. 227 #elif __cplusplus < 201103L && !defined _MSC_VER 228 229 #error "This is not a C++11 compiler" 230 231 #else 232 233 namespace cxx11 234 { 235 236 namespace test_static_assert 237 { 238 239 template <typename T> 240 struct check 241 { 242 static_assert(sizeof(int) <= sizeof(T), "not big enough"); 243 }; 244 245 } 246 247 namespace test_final_override 248 { 249 250 struct Base 251 { 252 virtual ~Base() {} 253 virtual void f() {} 254 }; 255 256 struct Derived : public Base 257 { 258 virtual ~Derived() override {} 259 virtual void f() override {} 260 }; 261 262 } 263 264 namespace test_double_right_angle_brackets 265 { 266 267 template < typename T > 268 struct check {}; 269 270 typedef check<void> single_type; 271 typedef check<check<void>> double_type; 272 typedef check<check<check<void>>> triple_type; 273 typedef check<check<check<check<void>>>> quadruple_type; 274 275 } 276 277 namespace test_decltype 278 { 279 280 int 281 f() 282 { 283 int a = 1; 284 decltype(a) b = 2; 285 return a + b; 286 } 287 288 } 289 290 namespace test_type_deduction 291 { 292 293 template < typename T1, typename T2 > 294 struct is_same 295 { 296 static const bool value = false; 297 }; 298 299 template < typename T > 300 struct is_same<T, T> 301 { 302 static const bool value = true; 303 }; 304 305 template < typename T1, typename T2 > 306 auto 307 add(T1 a1, T2 a2) -> decltype(a1 + a2) 308 { 309 return a1 + a2; 310 } 311 312 int 313 test(const int c, volatile int v) 314 { 315 static_assert(is_same<int, decltype(0)>::value == true, ""); 316 static_assert(is_same<int, decltype(c)>::value == false, ""); 317 static_assert(is_same<int, decltype(v)>::value == false, ""); 318 auto ac = c; 319 auto av = v; 320 auto sumi = ac + av + 'x'; 321 auto sumf = ac + av + 1.0; 322 static_assert(is_same<int, decltype(ac)>::value == true, ""); 323 static_assert(is_same<int, decltype(av)>::value == true, ""); 324 static_assert(is_same<int, decltype(sumi)>::value == true, ""); 325 static_assert(is_same<int, decltype(sumf)>::value == false, ""); 326 static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); 327 return (sumf > 0.0) ? sumi : add(c, v); 328 } 329 330 } 331 332 namespace test_noexcept 333 { 334 335 int f() { return 0; } 336 int g() noexcept { return 0; } 337 338 static_assert(noexcept(f()) == false, ""); 339 static_assert(noexcept(g()) == true, ""); 340 341 } 342 343 namespace test_constexpr 344 { 345 346 template < typename CharT > 347 unsigned long constexpr 348 strlen_c_r(const CharT *const s, const unsigned long acc) noexcept 349 { 350 return *s ? strlen_c_r(s + 1, acc + 1) : acc; 351 } 352 353 template < typename CharT > 354 unsigned long constexpr 355 strlen_c(const CharT *const s) noexcept 356 { 357 return strlen_c_r(s, 0UL); 358 } 359 360 static_assert(strlen_c("") == 0UL, ""); 361 static_assert(strlen_c("1") == 1UL, ""); 362 static_assert(strlen_c("example") == 7UL, ""); 363 static_assert(strlen_c("another\0example") == 7UL, ""); 364 365 } 366 367 namespace test_rvalue_references 368 { 369 370 template < int N > 371 struct answer 372 { 373 static constexpr int value = N; 374 }; 375 376 answer<1> f(int&) { return answer<1>(); } 377 answer<2> f(const int&) { return answer<2>(); } 378 answer<3> f(int&&) { return answer<3>(); } 379 380 void 381 test() 382 { 383 int i = 0; 384 const int c = 0; 385 static_assert(decltype(f(i))::value == 1, ""); 386 static_assert(decltype(f(c))::value == 2, ""); 387 static_assert(decltype(f(0))::value == 3, ""); 388 } 389 390 } 391 392 namespace test_uniform_initialization 393 { 394 395 struct test 396 { 397 static const int zero {}; 398 static const int one {1}; 399 }; 400 401 static_assert(test::zero == 0, ""); 402 static_assert(test::one == 1, ""); 403 404 } 405 406 namespace test_lambdas 407 { 408 409 void 410 test1() 411 { 412 auto lambda1 = [](){}; 413 auto lambda2 = lambda1; 414 lambda1(); 415 lambda2(); 416 } 417 418 int 419 test2() 420 { 421 auto a = [](int i, int j){ return i + j; }(1, 2); 422 auto b = []() -> int { return '0'; }(); 423 auto c = [=](){ return a + b; }(); 424 auto d = [&](){ return c; }(); 425 auto e = [a, &b](int x) mutable { 426 const auto identity = [](int y){ return y; }; 427 for (auto i = 0; i < a; ++i) 428 a += b--; 429 return x + identity(a + b); 430 }(0); 431 return a + b + c + d + e; 432 } 433 434 int 435 test3() 436 { 437 const auto nullary = [](){ return 0; }; 438 const auto unary = [](int x){ return x; }; 439 using nullary_t = decltype(nullary); 440 using unary_t = decltype(unary); 441 const auto higher1st = [](nullary_t f){ return f(); }; 442 const auto higher2nd = [unary](nullary_t f1){ 443 return [unary, f1](unary_t f2){ return f2(unary(f1())); }; 444 }; 445 return higher1st(nullary) + higher2nd(nullary)(unary); 446 } 447 448 } 449 450 namespace test_variadic_templates 451 { 452 453 template <int...> 454 struct sum; 455 456 template <int N0, int... N1toN> 457 struct sum<N0, N1toN...> 458 { 459 static constexpr auto value = N0 + sum<N1toN...>::value; 460 }; 461 462 template <> 463 struct sum<> 464 { 465 static constexpr auto value = 0; 466 }; 467 468 static_assert(sum<>::value == 0, ""); 469 static_assert(sum<1>::value == 1, ""); 470 static_assert(sum<23>::value == 23, ""); 471 static_assert(sum<1, 2>::value == 3, ""); 472 static_assert(sum<5, 5, 11>::value == 21, ""); 473 static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); 474 475 } 476 477 // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae 478 // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function 479 // because of this. 480 namespace test_template_alias_sfinae 481 { 482 483 struct foo {}; 484 485 template<typename T> 486 using member = typename T::member_type; 487 488 template<typename T> 489 void func(...) {} 490 491 template<typename T> 492 void func(member<T>*) {} 493 494 void test(); 495 496 void test() { func<foo>(0); } 497 498 } 499 500 } // namespace cxx11 501 502 #endif // __cplusplus >= 201103L 503 504 ]]) 505 506 507 dnl Tests for new features in C++14 508 509 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ 510 511 // If the compiler admits that it is not ready for C++14, why torture it? 512 // Hopefully, this will speed up the test. 513 514 #ifndef __cplusplus 515 516 #error "This is not a C++ compiler" 517 518 #elif __cplusplus < 201402L && !defined _MSC_VER 519 520 #error "This is not a C++14 compiler" 521 522 #else 523 524 namespace cxx14 525 { 526 527 namespace test_polymorphic_lambdas 528 { 529 530 int 531 test() 532 { 533 const auto lambda = [](auto&&... args){ 534 const auto istiny = [](auto x){ 535 return (sizeof(x) == 1UL) ? 1 : 0; 536 }; 537 const int aretiny[] = { istiny(args)... }; 538 return aretiny[0]; 539 }; 540 return lambda(1, 1L, 1.0f, '1'); 541 } 542 543 } 544 545 namespace test_binary_literals 546 { 547 548 constexpr auto ivii = 0b0000000000101010; 549 static_assert(ivii == 42, "wrong value"); 550 551 } 552 553 namespace test_generalized_constexpr 554 { 555 556 template < typename CharT > 557 constexpr unsigned long 558 strlen_c(const CharT *const s) noexcept 559 { 560 auto length = 0UL; 561 for (auto p = s; *p; ++p) 562 ++length; 563 return length; 564 } 565 566 static_assert(strlen_c("") == 0UL, ""); 567 static_assert(strlen_c("x") == 1UL, ""); 568 static_assert(strlen_c("test") == 4UL, ""); 569 static_assert(strlen_c("another\0test") == 7UL, ""); 570 571 } 572 573 namespace test_lambda_init_capture 574 { 575 576 int 577 test() 578 { 579 auto x = 0; 580 const auto lambda1 = [a = x](int b){ return a + b; }; 581 const auto lambda2 = [a = lambda1(x)](){ return a; }; 582 return lambda2(); 583 } 584 585 } 586 587 namespace test_digit_separators 588 { 589 590 constexpr auto ten_million = 100'000'000; 591 static_assert(ten_million == 100000000, ""); 592 593 } 594 595 namespace test_return_type_deduction 596 { 597 598 auto f(int& x) { return x; } 599 decltype(auto) g(int& x) { return x; } 600 601 template < typename T1, typename T2 > 602 struct is_same 603 { 604 static constexpr auto value = false; 605 }; 606 607 template < typename T > 608 struct is_same<T, T> 609 { 610 static constexpr auto value = true; 611 }; 612 613 int 614 test() 615 { 616 auto x = 0; 617 static_assert(is_same<int, decltype(f(x))>::value, ""); 618 static_assert(is_same<int&, decltype(g(x))>::value, ""); 619 return x; 620 } 621 622 } 623 624 } // namespace cxx14 625 626 #endif // __cplusplus >= 201402L 627 628 ]]) 629 630 631 dnl Tests for new features in C++17 632 633 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ 634 635 // If the compiler admits that it is not ready for C++17, why torture it? 636 // Hopefully, this will speed up the test. 637 638 #ifndef __cplusplus 639 640 #error "This is not a C++ compiler" 641 642 #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L 643 644 #error "This is not a C++17 compiler" 645 646 #else 647 648 #include <initializer_list> 649 #include <utility> 650 #include <type_traits> 651 652 namespace cxx17 653 { 654 655 namespace test_constexpr_lambdas 656 { 657 658 constexpr int foo = [](){return 42;}(); 659 660 } 661 662 namespace test::nested_namespace::definitions 663 { 664 665 } 666 667 namespace test_fold_expression 668 { 669 670 template<typename... Args> 671 int multiply(Args... args) 672 { 673 return (args * ... * 1); 674 } 675 676 template<typename... Args> 677 bool all(Args... args) 678 { 679 return (args && ...); 680 } 681 682 } 683 684 namespace test_extended_static_assert 685 { 686 687 static_assert (true); 688 689 } 690 691 namespace test_auto_brace_init_list 692 { 693 694 auto foo = {5}; 695 auto bar {5}; 696 697 static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value); 698 static_assert(std::is_same<int, decltype(bar)>::value); 699 } 700 701 namespace test_typename_in_template_template_parameter 702 { 703 704 template<template<typename> typename X> struct D; 705 706 } 707 708 namespace test_fallthrough_nodiscard_maybe_unused_attributes 709 { 710 711 int f1() 712 { 713 return 42; 714 } 715 716 [[nodiscard]] int f2() 717 { 718 [[maybe_unused]] auto unused = f1(); 719 720 switch (f1()) 721 { 722 case 17: 723 f1(); 724 [[fallthrough]]; 725 case 42: 726 f1(); 727 } 728 return f1(); 729 } 730 731 } 732 733 namespace test_extended_aggregate_initialization 734 { 735 736 struct base1 737 { 738 int b1, b2 = 42; 739 }; 740 741 struct base2 742 { 743 base2() { 744 b3 = 42; 745 } 746 int b3; 747 }; 748 749 struct derived : base1, base2 750 { 751 int d; 752 }; 753 754 derived d1 {{1, 2}, {}, 4}; // full initialization 755 derived d2 {{}, {}, 4}; // value-initialized bases 756 757 } 758 759 namespace test_general_range_based_for_loop 760 { 761 762 struct iter 763 { 764 int i; 765 766 int& operator* () 767 { 768 return i; 769 } 770 771 const int& operator* () const 772 { 773 return i; 774 } 775 776 iter& operator++() 777 { 778 ++i; 779 return *this; 780 } 781 }; 782 783 struct sentinel 784 { 785 int i; 786 }; 787 788 bool operator== (const iter& i, const sentinel& s) 789 { 790 return i.i == s.i; 791 } 792 793 bool operator!= (const iter& i, const sentinel& s) 794 { 795 return !(i == s); 796 } 797 798 struct range 799 { 800 iter begin() const 801 { 802 return {0}; 803 } 804 805 sentinel end() const 806 { 807 return {5}; 808 } 809 }; 810 811 void f() 812 { 813 range r {}; 814 815 for (auto i : r) 816 { 817 [[maybe_unused]] auto v = i; 818 } 819 } 820 821 } 822 823 namespace test_lambda_capture_asterisk_this_by_value 824 { 825 826 struct t 827 { 828 int i; 829 int foo() 830 { 831 return [*this]() 832 { 833 return i; 834 }(); 835 } 836 }; 837 838 } 839 840 namespace test_enum_class_construction 841 { 842 843 enum class byte : unsigned char 844 {}; 845 846 byte foo {42}; 847 848 } 849 850 namespace test_constexpr_if 851 { 852 853 template <bool cond> 854 int f () 855 { 856 if constexpr(cond) 857 { 858 return 13; 859 } 860 else 861 { 862 return 42; 863 } 864 } 865 866 } 867 868 namespace test_selection_statement_with_initializer 869 { 870 871 int f() 872 { 873 return 13; 874 } 875 876 int f2() 877 { 878 if (auto i = f(); i > 0) 879 { 880 return 3; 881 } 882 883 switch (auto i = f(); i + 4) 884 { 885 case 17: 886 return 2; 887 888 default: 889 return 1; 890 } 891 } 892 893 } 894 895 namespace test_template_argument_deduction_for_class_templates 896 { 897 898 template <typename T1, typename T2> 899 struct pair 900 { 901 pair (T1 p1, T2 p2) 902 : m1 {p1}, 903 m2 {p2} 904 {} 905 906 T1 m1; 907 T2 m2; 908 }; 909 910 void f() 911 { 912 [[maybe_unused]] auto p = pair{13, 42u}; 913 } 914 915 } 916 917 namespace test_non_type_auto_template_parameters 918 { 919 920 template <auto n> 921 struct B 922 {}; 923 924 B<5> b1; 925 B<'a'> b2; 926 927 } 928 929 namespace test_structured_bindings 930 { 931 932 int arr[2] = { 1, 2 }; 933 std::pair<int, int> pr = { 1, 2 }; 934 935 auto f1() -> int(&)[2] 936 { 937 return arr; 938 } 939 940 auto f2() -> std::pair<int, int>& 941 { 942 return pr; 943 } 944 945 struct S 946 { 947 int x1 : 2; 948 volatile double y1; 949 }; 950 951 S f3() 952 { 953 return {}; 954 } 955 956 auto [ x1, y1 ] = f1(); 957 auto& [ xr1, yr1 ] = f1(); 958 auto [ x2, y2 ] = f2(); 959 auto& [ xr2, yr2 ] = f2(); 960 const auto [ x3, y3 ] = f3(); 961 962 } 963 964 namespace test_exception_spec_type_system 965 { 966 967 struct Good {}; 968 struct Bad {}; 969 970 void g1() noexcept; 971 void g2(); 972 973 template<typename T> 974 Bad 975 f(T*, T*); 976 977 template<typename T1, typename T2> 978 Good 979 f(T1*, T2*); 980 981 static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); 982 983 } 984 985 namespace test_inline_variables 986 { 987 988 template<class T> void f(T) 989 {} 990 991 template<class T> inline T g(T) 992 { 993 return T{}; 994 } 995 996 template<> inline void f<>(int) 997 {} 998 999 template<> int g<>(int) 1000 { 1001 return 5; 1002 } 1003 1004 } 1005 1006 } // namespace cxx17 1007 1008 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L 1009 1010 ]]) 1011 1012 1013 dnl Tests for new features in C++20 1014 1015 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ 1016 1017 #ifndef __cplusplus 1018 1019 #error "This is not a C++ compiler" 1020 1021 #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L 1022 1023 #error "This is not a C++20 compiler" 1024 1025 #else 1026 1027 #include <version> 1028 1029 namespace cxx20 1030 { 1031 1032 // As C++20 supports feature test macros in the standard, there is no 1033 // immediate need to actually test for feature availability on the 1034 // Autoconf side. 1035 1036 } // namespace cxx20 1037 1038 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L 1039 1040 ]]) 1041 1042 1043 dnl Tests for new features in C++23 1044 1045 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_23], [[ 1046 1047 #ifndef __cplusplus 1048 1049 #error "This is not a C++ compiler" 1050 1051 #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202302L 1052 1053 #error "This is not a C++23 compiler" 1054 1055 #else 1056 1057 #include <version> 1058 1059 namespace cxx23 1060 { 1061 1062 // As C++23 supports feature test macros in the standard, there is no 1063 // immediate need to actually test for feature availability on the 1064 // Autoconf side. 1065 1066 } // namespace cxx23 1067 1068 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202302L 1069 1070 ]])