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