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