Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

983 lines
20KB

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