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