1<<<<<<< HEAD 2# =========================================================================== 3# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html 4# =========================================================================== 5# 6# SYNOPSIS 7# 8# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) 9# 10# DESCRIPTION 11# 12# Check for baseline language coverage in the compiler for the specified 13# version of the C++ standard. If necessary, add switches to CXX and 14# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) 15# or '14' (for the C++14 standard). 16# 17# The second argument, if specified, indicates whether you insist on an 18# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. 19# -std=c++11). If neither is specified, you get whatever works, with 20# preference for an extended mode. 21# 22# The third argument, if specified 'mandatory' or if left unspecified, 23# indicates that baseline support for the specified C++ standard is 24# required and that the macro should error out if no mode with that 25# support is found. If specified 'optional', then configuration proceeds 26# regardless, after defining HAVE_CXX${VERSION} if and only if a 27# supporting mode is found. 28# 29# LICENSE 30# 31# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> 32# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> 33# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> 34# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> 35# Copyright (c) 2015 Paul Norman <penorman@mac.com> 36# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> 37# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> 38# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com> 39# 40# Copying and distribution of this file, with or without modification, are 41# permitted in any medium without royalty provided the copyright notice 42# and this notice are preserved. This file is offered as-is, without any 43# warranty. 44 45#serial 11 46 47dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro 48dnl (serial version number 13). 49 50AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl 51 m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], 52 [$1], [14], [ax_cxx_compile_alternatives="14 1y"], 53 [$1], [17], [ax_cxx_compile_alternatives="17 1z"], 54 [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl 55 m4_if([$2], [], [], 56 [$2], [ext], [], 57 [$2], [noext], [], 58 [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl 59 m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], 60 [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], 61 [$3], [optional], [ax_cxx_compile_cxx$1_required=false], 62 [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) 63 AC_LANG_PUSH([C++])dnl 64 ac_success=no 65 66 m4_if([$2], [noext], [], [dnl 67 if test x$ac_success = xno; then 68 for alternative in ${ax_cxx_compile_alternatives}; do 69 switch="-std=gnu++${alternative}" 70 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 71 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 72 $cachevar, 73 [ac_save_CXX="$CXX" 74 CXX="$CXX $switch" 75 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 76 [eval $cachevar=yes], 77 [eval $cachevar=no]) 78 CXX="$ac_save_CXX"]) 79 if eval test x\$$cachevar = xyes; then 80 CXX="$CXX $switch" 81 if test -n "$CXXCPP" ; then 82 CXXCPP="$CXXCPP $switch" 83 fi 84 ac_success=yes 85 break 86 fi 87 done 88 fi]) 89 90 m4_if([$2], [ext], [], [dnl 91 if test x$ac_success = xno; then 92 dnl HP's aCC needs +std=c++11 according to: 93 dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf 94 dnl Cray's crayCC needs "-h std=c++11" 95 for alternative in ${ax_cxx_compile_alternatives}; do 96 for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do 97 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 98 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 99 $cachevar, 100 [ac_save_CXX="$CXX" 101 CXX="$CXX $switch" 102 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 103 [eval $cachevar=yes], 104 [eval $cachevar=no]) 105 CXX="$ac_save_CXX"]) 106 if eval test x\$$cachevar = xyes; then 107 CXX="$CXX $switch" 108 if test -n "$CXXCPP" ; then 109 CXXCPP="$CXXCPP $switch" 110 fi 111 ac_success=yes 112 break 113 fi 114 done 115 if test x$ac_success = xyes; then 116 break 117 fi 118 done 119 fi]) 120 AC_LANG_POP([C++]) 121 if test x$ax_cxx_compile_cxx$1_required = xtrue; then 122 if test x$ac_success = xno; then 123 AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) 124 fi 125 fi 126 if test x$ac_success = xno; then 127 HAVE_CXX$1=0 128 AC_MSG_NOTICE([No compiler with C++$1 support was found]) 129 else 130 HAVE_CXX$1=1 131 AC_DEFINE(HAVE_CXX$1,1, 132 [define if the compiler supports basic C++$1 syntax]) 133 fi 134 AC_SUBST(HAVE_CXX$1) 135]) 136 137 138dnl Test body for checking C++11 support 139 140m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], 141 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 142) 143 144 145dnl Test body for checking C++14 support 146 147m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], 148 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 149 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 150) 151 152m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], 153 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 154 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 155 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 156) 157 158dnl Tests for new features in C++11 159 160m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ 161 162// If the compiler admits that it is not ready for C++11, why torture it? 163// Hopefully, this will speed up the test. 164 165#ifndef __cplusplus 166 167#error "This is not a C++ compiler" 168 169#elif __cplusplus < 201103L 170 171#error "This is not a C++11 compiler" 172 173#else 174 175namespace cxx11 176{ 177 178 namespace test_static_assert 179 { 180 181 template <typename T> 182 struct check 183 { 184 static_assert(sizeof(int) <= sizeof(T), "not big enough"); 185 }; 186 187 } 188 189 namespace test_final_override 190 { 191 192 struct Base 193 { 194 virtual ~Base() {} 195 virtual void f() {} 196 }; 197 198 struct Derived : public Base 199 { 200 virtual ~Derived() override {} 201 virtual void f() override {} 202 }; 203 204 } 205 206 namespace test_double_right_angle_brackets 207 { 208 209 template < typename T > 210 struct check {}; 211 212 typedef check<void> single_type; 213 typedef check<check<void>> double_type; 214 typedef check<check<check<void>>> triple_type; 215 typedef check<check<check<check<void>>>> quadruple_type; 216 217 } 218 219 namespace test_decltype 220 { 221 222 int 223 f() 224 { 225 int a = 1; 226 decltype(a) b = 2; 227 return a + b; 228 } 229 230 } 231 232 namespace test_type_deduction 233 { 234 235 template < typename T1, typename T2 > 236 struct is_same 237 { 238 static const bool value = false; 239 }; 240 241 template < typename T > 242 struct is_same<T, T> 243 { 244 static const bool value = true; 245 }; 246 247 template < typename T1, typename T2 > 248 auto 249 add(T1 a1, T2 a2) -> decltype(a1 + a2) 250 { 251 return a1 + a2; 252 } 253 254 int 255 test(const int c, volatile int v) 256 { 257 static_assert(is_same<int, decltype(0)>::value == true, ""); 258 static_assert(is_same<int, decltype(c)>::value == false, ""); 259 static_assert(is_same<int, decltype(v)>::value == false, ""); 260 auto ac = c; 261 auto av = v; 262 auto sumi = ac + av + 'x'; 263 auto sumf = ac + av + 1.0; 264 static_assert(is_same<int, decltype(ac)>::value == true, ""); 265 static_assert(is_same<int, decltype(av)>::value == true, ""); 266 static_assert(is_same<int, decltype(sumi)>::value == true, ""); 267 static_assert(is_same<int, decltype(sumf)>::value == false, ""); 268 static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); 269 return (sumf > 0.0) ? sumi : add(c, v); 270 } 271 272 } 273 274 namespace test_noexcept 275 { 276 277 int f() { return 0; } 278 int g() noexcept { return 0; } 279 280 static_assert(noexcept(f()) == false, ""); 281 static_assert(noexcept(g()) == true, ""); 282 283 } 284 285 namespace test_constexpr 286 { 287 288 template < typename CharT > 289 unsigned long constexpr 290 strlen_c_r(const CharT *const s, const unsigned long acc) noexcept 291 { 292 return *s ? strlen_c_r(s + 1, acc + 1) : acc; 293 } 294 295 template < typename CharT > 296 unsigned long constexpr 297 strlen_c(const CharT *const s) noexcept 298 { 299 return strlen_c_r(s, 0UL); 300 } 301 302 static_assert(strlen_c("") == 0UL, ""); 303 static_assert(strlen_c("1") == 1UL, ""); 304 static_assert(strlen_c("example") == 7UL, ""); 305 static_assert(strlen_c("another\0example") == 7UL, ""); 306 307 } 308 309 namespace test_rvalue_references 310 { 311 312 template < int N > 313 struct answer 314 { 315 static constexpr int value = N; 316 }; 317 318 answer<1> f(int&) { return answer<1>(); } 319 answer<2> f(const int&) { return answer<2>(); } 320 answer<3> f(int&&) { return answer<3>(); } 321 322 void 323 test() 324 { 325 int i = 0; 326 const int c = 0; 327 static_assert(decltype(f(i))::value == 1, ""); 328 static_assert(decltype(f(c))::value == 2, ""); 329 static_assert(decltype(f(0))::value == 3, ""); 330 } 331 332 } 333 334 namespace test_uniform_initialization 335 { 336 337 struct test 338 { 339 static const int zero {}; 340 static const int one {1}; 341 }; 342 343 static_assert(test::zero == 0, ""); 344 static_assert(test::one == 1, ""); 345 346 } 347 348 namespace test_lambdas 349 { 350 351 void 352 test1() 353 { 354 auto lambda1 = [](){}; 355 auto lambda2 = lambda1; 356 lambda1(); 357 lambda2(); 358 } 359 360 int 361 test2() 362 { 363 auto a = [](int i, int j){ return i + j; }(1, 2); 364 auto b = []() -> int { return '0'; }(); 365 auto c = [=](){ return a + b; }(); 366 auto d = [&](){ return c; }(); 367 auto e = [a, &b](int x) mutable { 368 const auto identity = [](int y){ return y; }; 369 for (auto i = 0; i < a; ++i) 370 a += b--; 371 return x + identity(a + b); 372 }(0); 373 return a + b + c + d + e; 374 } 375 376 int 377 test3() 378 { 379 const auto nullary = [](){ return 0; }; 380 const auto unary = [](int x){ return x; }; 381 using nullary_t = decltype(nullary); 382 using unary_t = decltype(unary); 383 const auto higher1st = [](nullary_t f){ return f(); }; 384 const auto higher2nd = [unary](nullary_t f1){ 385 return [unary, f1](unary_t f2){ return f2(unary(f1())); }; 386 }; 387 return higher1st(nullary) + higher2nd(nullary)(unary); 388 } 389 390 } 391 392 namespace test_variadic_templates 393 { 394 395 template <int...> 396 struct sum; 397 398 template <int N0, int... N1toN> 399 struct sum<N0, N1toN...> 400 { 401 static constexpr auto value = N0 + sum<N1toN...>::value; 402 }; 403 404 template <> 405 struct sum<> 406 { 407 static constexpr auto value = 0; 408 }; 409 410 static_assert(sum<>::value == 0, ""); 411 static_assert(sum<1>::value == 1, ""); 412 static_assert(sum<23>::value == 23, ""); 413 static_assert(sum<1, 2>::value == 3, ""); 414 static_assert(sum<5, 5, 11>::value == 21, ""); 415 static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); 416 417 } 418 419 // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae 420 // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function 421 // because of this. 422 namespace test_template_alias_sfinae 423 { 424 425 struct foo {}; 426 427 template<typename T> 428 using member = typename T::member_type; 429 430 template<typename T> 431 void func(...) {} 432 433 template<typename T> 434 void func(member<T>*) {} 435 436 void test(); 437 438 void test() { func<foo>(0); } 439 440 } 441 442} // namespace cxx11 443 444#endif // __cplusplus >= 201103L 445 446]]) 447 448 449dnl Tests for new features in C++14 450 451m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ 452 453// If the compiler admits that it is not ready for C++14, why torture it? 454// Hopefully, this will speed up the test. 455 456#ifndef __cplusplus 457 458#error "This is not a C++ compiler" 459 460#elif __cplusplus < 201402L 461 462#error "This is not a C++14 compiler" 463 464#else 465 466namespace cxx14 467{ 468 469 namespace test_polymorphic_lambdas 470 { 471 472 int 473 test() 474 { 475 const auto lambda = [](auto&&... args){ 476 const auto istiny = [](auto x){ 477 return (sizeof(x) == 1UL) ? 1 : 0; 478 }; 479 const int aretiny[] = { istiny(args)... }; 480 return aretiny[0]; 481 }; 482 return lambda(1, 1L, 1.0f, '1'); 483 } 484 485 } 486 487 namespace test_binary_literals 488 { 489 490 constexpr auto ivii = 0b0000000000101010; 491 static_assert(ivii == 42, "wrong value"); 492 493 } 494 495 namespace test_generalized_constexpr 496 { 497 498 template < typename CharT > 499 constexpr unsigned long 500 strlen_c(const CharT *const s) noexcept 501 { 502 auto length = 0UL; 503 for (auto p = s; *p; ++p) 504 ++length; 505 return length; 506 } 507 508 static_assert(strlen_c("") == 0UL, ""); 509 static_assert(strlen_c("x") == 1UL, ""); 510 static_assert(strlen_c("test") == 4UL, ""); 511 static_assert(strlen_c("another\0test") == 7UL, ""); 512 513 } 514 515 namespace test_lambda_init_capture 516 { 517 518 int 519 test() 520 { 521 auto x = 0; 522 const auto lambda1 = [a = x](int b){ return a + b; }; 523 const auto lambda2 = [a = lambda1(x)](){ return a; }; 524 return lambda2(); 525 } 526 527 } 528 529 namespace test_digit_separators 530 { 531 532 constexpr auto ten_million = 100'000'000; 533 static_assert(ten_million == 100000000, ""); 534 535 } 536 537 namespace test_return_type_deduction 538 { 539 540 auto f(int& x) { return x; } 541 decltype(auto) g(int& x) { return x; } 542 543 template < typename T1, typename T2 > 544 struct is_same 545 { 546 static constexpr auto value = false; 547 }; 548 549 template < typename T > 550 struct is_same<T, T> 551 { 552 static constexpr auto value = true; 553 }; 554 555 int 556 test() 557 { 558 auto x = 0; 559 static_assert(is_same<int, decltype(f(x))>::value, ""); 560 static_assert(is_same<int&, decltype(g(x))>::value, ""); 561 return x; 562 } 563 564 } 565 566} // namespace cxx14 567 568#endif // __cplusplus >= 201402L 569 570]]) 571 572 573dnl Tests for new features in C++17 574 575m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ 576 577// If the compiler admits that it is not ready for C++17, why torture it? 578// Hopefully, this will speed up the test. 579 580#ifndef __cplusplus 581 582#error "This is not a C++ compiler" 583 584#elif __cplusplus < 201703L 585 586#error "This is not a C++17 compiler" 587 588#else 589 590#include <initializer_list> 591#include <utility> 592#include <type_traits> 593 594namespace cxx17 595{ 596 597 namespace test_constexpr_lambdas 598 { 599 600 constexpr int foo = [](){return 42;}(); 601 602 } 603 604 namespace test::nested_namespace::definitions 605 { 606 607 } 608 609 namespace test_fold_expression 610 { 611 612 template<typename... Args> 613 int multiply(Args... args) 614 { 615 return (args * ... * 1); 616 } 617 618 template<typename... Args> 619 bool all(Args... args) 620 { 621 return (args && ...); 622 } 623 624 } 625 626 namespace test_extended_static_assert 627 { 628 629 static_assert (true); 630 631 } 632 633 namespace test_auto_brace_init_list 634 { 635 636 auto foo = {5}; 637 auto bar {5}; 638 639 static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value); 640 static_assert(std::is_same<int, decltype(bar)>::value); 641 } 642 643 namespace test_typename_in_template_template_parameter 644 { 645 646 template<template<typename> typename X> struct D; 647 648 } 649 650 namespace test_fallthrough_nodiscard_maybe_unused_attributes 651 { 652 653 int f1() 654 { 655 return 42; 656 } 657 658 [[nodiscard]] int f2() 659 { 660 [[maybe_unused]] auto unused = f1(); 661 662 switch (f1()) 663 { 664 case 17: 665 f1(); 666 [[fallthrough]]; 667 case 42: 668 f1(); 669 } 670 return f1(); 671 } 672 673 } 674 675 namespace test_extended_aggregate_initialization 676 { 677 678 struct base1 679 { 680 int b1, b2 = 42; 681 }; 682 683 struct base2 684 { 685 base2() { 686 b3 = 42; 687 } 688 int b3; 689 }; 690 691 struct derived : base1, base2 692 { 693 int d; 694 }; 695 696 derived d1 {{1, 2}, {}, 4}; // full initialization 697 derived d2 {{}, {}, 4}; // value-initialized bases 698 699 } 700 701 namespace test_general_range_based_for_loop 702 { 703 704 struct iter 705 { 706 int i; 707 708 int& operator* () 709 { 710 return i; 711 } 712 713 const int& operator* () const 714 { 715 return i; 716 } 717 718 iter& operator++() 719 { 720 ++i; 721 return *this; 722 } 723 }; 724 725 struct sentinel 726 { 727 int i; 728 }; 729 730 bool operator== (const iter& i, const sentinel& s) 731 { 732 return i.i == s.i; 733 } 734 735 bool operator!= (const iter& i, const sentinel& s) 736 { 737 return !(i == s); 738 } 739 740 struct range 741 { 742 iter begin() const 743 { 744 return {0}; 745 } 746 747 sentinel end() const 748 { 749 return {5}; 750 } 751 }; 752 753 void f() 754 { 755 range r {}; 756 757 for (auto i : r) 758 { 759 [[maybe_unused]] auto v = i; 760 } 761 } 762 763 } 764 765 namespace test_lambda_capture_asterisk_this_by_value 766 { 767 768 struct t 769 { 770 int i; 771 int foo() 772 { 773 return [*this]() 774 { 775 return i; 776 }(); 777 } 778 }; 779 780 } 781 782 namespace test_enum_class_construction 783 { 784 785 enum class byte : unsigned char 786 {}; 787 788 byte foo {42}; 789 790 } 791 792 namespace test_constexpr_if 793 { 794 795 template <bool cond> 796 int f () 797 { 798 if constexpr(cond) 799 { 800 return 13; 801 } 802 else 803 { 804 return 42; 805 } 806 } 807 808 } 809 810 namespace test_selection_statement_with_initializer 811 { 812 813 int f() 814 { 815 return 13; 816 } 817 818 int f2() 819 { 820 if (auto i = f(); i > 0) 821 { 822 return 3; 823 } 824 825 switch (auto i = f(); i + 4) 826 { 827 case 17: 828 return 2; 829 830 default: 831 return 1; 832 } 833 } 834 835 } 836 837 namespace test_template_argument_deduction_for_class_templates 838 { 839 840 template <typename T1, typename T2> 841 struct pair 842 { 843 pair (T1 p1, T2 p2) 844 : m1 {p1}, 845 m2 {p2} 846 {} 847 848 T1 m1; 849 T2 m2; 850 }; 851 852 void f() 853 { 854 [[maybe_unused]] auto p = pair{13, 42u}; 855 } 856 857 } 858 859 namespace test_non_type_auto_template_parameters 860 { 861 862 template <auto n> 863 struct B 864 {}; 865 866 B<5> b1; 867 B<'a'> b2; 868 869 } 870 871 namespace test_structured_bindings 872 { 873 874 int arr[2] = { 1, 2 }; 875 std::pair<int, int> pr = { 1, 2 }; 876 877 auto f1() -> int(&)[2] 878 { 879 return arr; 880 } 881 882 auto f2() -> std::pair<int, int>& 883 { 884 return pr; 885 } 886 887 struct S 888 { 889 int x1 : 2; 890 volatile double y1; 891 }; 892 893 S f3() 894 { 895 return {}; 896 } 897 898 auto [ x1, y1 ] = f1(); 899 auto& [ xr1, yr1 ] = f1(); 900 auto [ x2, y2 ] = f2(); 901 auto& [ xr2, yr2 ] = f2(); 902 const auto [ x3, y3 ] = f3(); 903 904 } 905 906 namespace test_exception_spec_type_system 907 { 908 909 struct Good {}; 910 struct Bad {}; 911 912 void g1() noexcept; 913 void g2(); 914 915 template<typename T> 916 Bad 917 f(T*, T*); 918 919 template<typename T1, typename T2> 920 Good 921 f(T1*, T2*); 922 923 static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); 924 925 } 926 927 namespace test_inline_variables 928 { 929 930 template<class T> void f(T) 931 {} 932 933 template<class T> inline T g(T) 934 { 935 return T{}; 936 } 937 938 template<> inline void f<>(int) 939 {} 940 941 template<> int g<>(int) 942 { 943 return 5; 944 } 945 946 } 947 948} // namespace cxx17 949 950#endif // __cplusplus < 201703L 951 952]]) 953||||||| dec341af7695 954======= 955# =========================================================================== 956# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html 957# =========================================================================== 958# 959# SYNOPSIS 960# 961# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) 962# 963# DESCRIPTION 964# 965# Check for baseline language coverage in the compiler for the specified 966# version of the C++ standard. If necessary, add switches to CXX and 967# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) 968# or '14' (for the C++14 standard). 969# 970# The second argument, if specified, indicates whether you insist on an 971# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. 972# -std=c++11). If neither is specified, you get whatever works, with 973# preference for an extended mode. 974# 975# The third argument, if specified 'mandatory' or if left unspecified, 976# indicates that baseline support for the specified C++ standard is 977# required and that the macro should error out if no mode with that 978# support is found. If specified 'optional', then configuration proceeds 979# regardless, after defining HAVE_CXX${VERSION} if and only if a 980# supporting mode is found. 981# 982# LICENSE 983# 984# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> 985# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> 986# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> 987# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> 988# Copyright (c) 2015 Paul Norman <penorman@mac.com> 989# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> 990# 991# Copying and distribution of this file, with or without modification, are 992# permitted in any medium without royalty provided the copyright notice 993# and this notice are preserved. This file is offered as-is, without any 994# warranty. 995 996#serial 4 997 998dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro 999dnl (serial version number 13). 1000 1001AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl 1002 m4_if([$1], [11], [], 1003 [$1], [14], [], 1004 [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], 1005 [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl 1006 m4_if([$2], [], [], 1007 [$2], [ext], [], 1008 [$2], [noext], [], 1009 [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl 1010 m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], 1011 [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], 1012 [$3], [optional], [ax_cxx_compile_cxx$1_required=false], 1013 [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) 1014 AC_LANG_PUSH([C++])dnl 1015 ac_success=no 1016 AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, 1017 ax_cv_cxx_compile_cxx$1, 1018 [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 1019 [ax_cv_cxx_compile_cxx$1=yes], 1020 [ax_cv_cxx_compile_cxx$1=no])]) 1021 if test x$ax_cv_cxx_compile_cxx$1 = xyes; then 1022 ac_success=yes 1023 fi 1024 1025 m4_if([$2], [noext], [], [dnl 1026 if test x$ac_success = xno; then 1027 for switch in -std=gnu++$1 -std=gnu++0x; do 1028 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 1029 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 1030 $cachevar, 1031 [ac_save_CXX="$CXX" 1032 CXX="$CXX $switch" 1033 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 1034 [eval $cachevar=yes], 1035 [eval $cachevar=no]) 1036 CXX="$ac_save_CXX"]) 1037 if eval test x\$$cachevar = xyes; then 1038 CXX="$CXX $switch" 1039 if test -n "$CXXCPP" ; then 1040 CXXCPP="$CXXCPP $switch" 1041 fi 1042 ac_success=yes 1043 break 1044 fi 1045 done 1046 fi]) 1047 1048 m4_if([$2], [ext], [], [dnl 1049 if test x$ac_success = xno; then 1050 dnl HP's aCC needs +std=c++11 according to: 1051 dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf 1052 dnl Cray's crayCC needs "-h std=c++11" 1053 for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do 1054 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 1055 AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 1056 $cachevar, 1057 [ac_save_CXX="$CXX" 1058 CXX="$CXX $switch" 1059 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 1060 [eval $cachevar=yes], 1061 [eval $cachevar=no]) 1062 CXX="$ac_save_CXX"]) 1063 if eval test x\$$cachevar = xyes; then 1064 CXX="$CXX $switch" 1065 if test -n "$CXXCPP" ; then 1066 CXXCPP="$CXXCPP $switch" 1067 fi 1068 ac_success=yes 1069 break 1070 fi 1071 done 1072 fi]) 1073 AC_LANG_POP([C++]) 1074 if test x$ax_cxx_compile_cxx$1_required = xtrue; then 1075 if test x$ac_success = xno; then 1076 AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) 1077 fi 1078 fi 1079 if test x$ac_success = xno; then 1080 HAVE_CXX$1=0 1081 AC_MSG_NOTICE([No compiler with C++$1 support was found]) 1082 else 1083 HAVE_CXX$1=1 1084 AC_DEFINE(HAVE_CXX$1,1, 1085 [define if the compiler supports basic C++$1 syntax]) 1086 fi 1087 AC_SUBST(HAVE_CXX$1) 1088]) 1089 1090 1091dnl Test body for checking C++11 support 1092 1093m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], 1094 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1095) 1096 1097 1098dnl Test body for checking C++14 support 1099 1100m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], 1101 _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1102 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 1103) 1104 1105 1106dnl Tests for new features in C++11 1107 1108m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ 1109 1110// If the compiler admits that it is not ready for C++11, why torture it? 1111// Hopefully, this will speed up the test. 1112 1113#ifndef __cplusplus 1114 1115#error "This is not a C++ compiler" 1116 1117#elif __cplusplus < 201103L 1118 1119#error "This is not a C++11 compiler" 1120 1121#else 1122 1123namespace cxx11 1124{ 1125 1126 namespace test_static_assert 1127 { 1128 1129 template <typename T> 1130 struct check 1131 { 1132 static_assert(sizeof(int) <= sizeof(T), "not big enough"); 1133 }; 1134 1135 } 1136 1137 namespace test_final_override 1138 { 1139 1140 struct Base 1141 { 1142 virtual void f() {} 1143 }; 1144 1145 struct Derived : public Base 1146 { 1147 virtual void f() override {} 1148 }; 1149 1150 } 1151 1152 namespace test_double_right_angle_brackets 1153 { 1154 1155 template < typename T > 1156 struct check {}; 1157 1158 typedef check<void> single_type; 1159 typedef check<check<void>> double_type; 1160 typedef check<check<check<void>>> triple_type; 1161 typedef check<check<check<check<void>>>> quadruple_type; 1162 1163 } 1164 1165 namespace test_decltype 1166 { 1167 1168 int 1169 f() 1170 { 1171 int a = 1; 1172 decltype(a) b = 2; 1173 return a + b; 1174 } 1175 1176 } 1177 1178 namespace test_type_deduction 1179 { 1180 1181 template < typename T1, typename T2 > 1182 struct is_same 1183 { 1184 static const bool value = false; 1185 }; 1186 1187 template < typename T > 1188 struct is_same<T, T> 1189 { 1190 static const bool value = true; 1191 }; 1192 1193 template < typename T1, typename T2 > 1194 auto 1195 add(T1 a1, T2 a2) -> decltype(a1 + a2) 1196 { 1197 return a1 + a2; 1198 } 1199 1200 int 1201 test(const int c, volatile int v) 1202 { 1203 static_assert(is_same<int, decltype(0)>::value == true, ""); 1204 static_assert(is_same<int, decltype(c)>::value == false, ""); 1205 static_assert(is_same<int, decltype(v)>::value == false, ""); 1206 auto ac = c; 1207 auto av = v; 1208 auto sumi = ac + av + 'x'; 1209 auto sumf = ac + av + 1.0; 1210 static_assert(is_same<int, decltype(ac)>::value == true, ""); 1211 static_assert(is_same<int, decltype(av)>::value == true, ""); 1212 static_assert(is_same<int, decltype(sumi)>::value == true, ""); 1213 static_assert(is_same<int, decltype(sumf)>::value == false, ""); 1214 static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); 1215 return (sumf > 0.0) ? sumi : add(c, v); 1216 } 1217 1218 } 1219 1220 namespace test_noexcept 1221 { 1222 1223 int f() { return 0; } 1224 int g() noexcept { return 0; } 1225 1226 static_assert(noexcept(f()) == false, ""); 1227 static_assert(noexcept(g()) == true, ""); 1228 1229 } 1230 1231 namespace test_constexpr 1232 { 1233 1234 template < typename CharT > 1235 unsigned long constexpr 1236 strlen_c_r(const CharT *const s, const unsigned long acc) noexcept 1237 { 1238 return *s ? strlen_c_r(s + 1, acc + 1) : acc; 1239 } 1240 1241 template < typename CharT > 1242 unsigned long constexpr 1243 strlen_c(const CharT *const s) noexcept 1244 { 1245 return strlen_c_r(s, 0UL); 1246 } 1247 1248 static_assert(strlen_c("") == 0UL, ""); 1249 static_assert(strlen_c("1") == 1UL, ""); 1250 static_assert(strlen_c("example") == 7UL, ""); 1251 static_assert(strlen_c("another\0example") == 7UL, ""); 1252 1253 } 1254 1255 namespace test_rvalue_references 1256 { 1257 1258 template < int N > 1259 struct answer 1260 { 1261 static constexpr int value = N; 1262 }; 1263 1264 answer<1> f(int&) { return answer<1>(); } 1265 answer<2> f(const int&) { return answer<2>(); } 1266 answer<3> f(int&&) { return answer<3>(); } 1267 1268 void 1269 test() 1270 { 1271 int i = 0; 1272 const int c = 0; 1273 static_assert(decltype(f(i))::value == 1, ""); 1274 static_assert(decltype(f(c))::value == 2, ""); 1275 static_assert(decltype(f(0))::value == 3, ""); 1276 } 1277 1278 } 1279 1280 namespace test_uniform_initialization 1281 { 1282 1283 struct test 1284 { 1285 static const int zero {}; 1286 static const int one {1}; 1287 }; 1288 1289 static_assert(test::zero == 0, ""); 1290 static_assert(test::one == 1, ""); 1291 1292 } 1293 1294 namespace test_lambdas 1295 { 1296 1297 void 1298 test1() 1299 { 1300 auto lambda1 = [](){}; 1301 auto lambda2 = lambda1; 1302 lambda1(); 1303 lambda2(); 1304 } 1305 1306 int 1307 test2() 1308 { 1309 auto a = [](int i, int j){ return i + j; }(1, 2); 1310 auto b = []() -> int { return '0'; }(); 1311 auto c = [=](){ return a + b; }(); 1312 auto d = [&](){ return c; }(); 1313 auto e = [a, &b](int x) mutable { 1314 const auto identity = [](int y){ return y; }; 1315 for (auto i = 0; i < a; ++i) 1316 a += b--; 1317 return x + identity(a + b); 1318 }(0); 1319 return a + b + c + d + e; 1320 } 1321 1322 int 1323 test3() 1324 { 1325 const auto nullary = [](){ return 0; }; 1326 const auto unary = [](int x){ return x; }; 1327 using nullary_t = decltype(nullary); 1328 using unary_t = decltype(unary); 1329 const auto higher1st = [](nullary_t f){ return f(); }; 1330 const auto higher2nd = [unary](nullary_t f1){ 1331 return [unary, f1](unary_t f2){ return f2(unary(f1())); }; 1332 }; 1333 return higher1st(nullary) + higher2nd(nullary)(unary); 1334 } 1335 1336 } 1337 1338 namespace test_variadic_templates 1339 { 1340 1341 template <int...> 1342 struct sum; 1343 1344 template <int N0, int... N1toN> 1345 struct sum<N0, N1toN...> 1346 { 1347 static constexpr auto value = N0 + sum<N1toN...>::value; 1348 }; 1349 1350 template <> 1351 struct sum<> 1352 { 1353 static constexpr auto value = 0; 1354 }; 1355 1356 static_assert(sum<>::value == 0, ""); 1357 static_assert(sum<1>::value == 1, ""); 1358 static_assert(sum<23>::value == 23, ""); 1359 static_assert(sum<1, 2>::value == 3, ""); 1360 static_assert(sum<5, 5, 11>::value == 21, ""); 1361 static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); 1362 1363 } 1364 1365 // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae 1366 // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function 1367 // because of this. 1368 namespace test_template_alias_sfinae 1369 { 1370 1371 struct foo {}; 1372 1373 template<typename T> 1374 using member = typename T::member_type; 1375 1376 template<typename T> 1377 void func(...) {} 1378 1379 template<typename T> 1380 void func(member<T>*) {} 1381 1382 void test(); 1383 1384 void test() { func<foo>(0); } 1385 1386 } 1387 1388} // namespace cxx11 1389 1390#endif // __cplusplus >= 201103L 1391 1392]]) 1393 1394 1395dnl Tests for new features in C++14 1396 1397m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ 1398 1399// If the compiler admits that it is not ready for C++14, why torture it? 1400// Hopefully, this will speed up the test. 1401 1402#ifndef __cplusplus 1403 1404#error "This is not a C++ compiler" 1405 1406#elif __cplusplus < 201402L 1407 1408#error "This is not a C++14 compiler" 1409 1410#else 1411 1412namespace cxx14 1413{ 1414 1415 namespace test_polymorphic_lambdas 1416 { 1417 1418 int 1419 test() 1420 { 1421 const auto lambda = [](auto&&... args){ 1422 const auto istiny = [](auto x){ 1423 return (sizeof(x) == 1UL) ? 1 : 0; 1424 }; 1425 const int aretiny[] = { istiny(args)... }; 1426 return aretiny[0]; 1427 }; 1428 return lambda(1, 1L, 1.0f, '1'); 1429 } 1430 1431 } 1432 1433 namespace test_binary_literals 1434 { 1435 1436 constexpr auto ivii = 0b0000000000101010; 1437 static_assert(ivii == 42, "wrong value"); 1438 1439 } 1440 1441 namespace test_generalized_constexpr 1442 { 1443 1444 template < typename CharT > 1445 constexpr unsigned long 1446 strlen_c(const CharT *const s) noexcept 1447 { 1448 auto length = 0UL; 1449 for (auto p = s; *p; ++p) 1450 ++length; 1451 return length; 1452 } 1453 1454 static_assert(strlen_c("") == 0UL, ""); 1455 static_assert(strlen_c("x") == 1UL, ""); 1456 static_assert(strlen_c("test") == 4UL, ""); 1457 static_assert(strlen_c("another\0test") == 7UL, ""); 1458 1459 } 1460 1461 namespace test_lambda_init_capture 1462 { 1463 1464 int 1465 test() 1466 { 1467 auto x = 0; 1468 const auto lambda1 = [a = x](int b){ return a + b; }; 1469 const auto lambda2 = [a = lambda1(x)](){ return a; }; 1470 return lambda2(); 1471 } 1472 1473 } 1474 1475 namespace test_digit_seperators 1476 { 1477 1478 constexpr auto ten_million = 100'000'000; 1479 static_assert(ten_million == 100000000, ""); 1480 1481 } 1482 1483 namespace test_return_type_deduction 1484 { 1485 1486 auto f(int& x) { return x; } 1487 decltype(auto) g(int& x) { return x; } 1488 1489 template < typename T1, typename T2 > 1490 struct is_same 1491 { 1492 static constexpr auto value = false; 1493 }; 1494 1495 template < typename T > 1496 struct is_same<T, T> 1497 { 1498 static constexpr auto value = true; 1499 }; 1500 1501 int 1502 test() 1503 { 1504 auto x = 0; 1505 static_assert(is_same<int, decltype(f(x))>::value, ""); 1506 static_assert(is_same<int&, decltype(g(x))>::value, ""); 1507 return x; 1508 } 1509 1510 } 1511 1512} // namespace cxx14 1513 1514#endif // __cplusplus >= 201402L 1515 1516]]) 1517>>>>>>> main 1518