ax_cxx_compile_stdcxx.m4 19 KB

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