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