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