quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

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 ]])