12c593315Sopenharmony_ci# ===========================================================================
22c593315Sopenharmony_ci#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
32c593315Sopenharmony_ci# ===========================================================================
42c593315Sopenharmony_ci#
52c593315Sopenharmony_ci# SYNOPSIS
62c593315Sopenharmony_ci#
72c593315Sopenharmony_ci#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
82c593315Sopenharmony_ci#
92c593315Sopenharmony_ci# DESCRIPTION
102c593315Sopenharmony_ci#
112c593315Sopenharmony_ci#   Check for baseline language coverage in the compiler for the specified
122c593315Sopenharmony_ci#   version of the C++ standard.  If necessary, add switches to CXX and
132c593315Sopenharmony_ci#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard)
142c593315Sopenharmony_ci#   or '14' (for the C++14 standard).
152c593315Sopenharmony_ci#
162c593315Sopenharmony_ci#   The second argument, if specified, indicates whether you insist on an
172c593315Sopenharmony_ci#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
182c593315Sopenharmony_ci#   -std=c++11).  If neither is specified, you get whatever works, with
192c593315Sopenharmony_ci#   preference for an extended mode.
202c593315Sopenharmony_ci#
212c593315Sopenharmony_ci#   The third argument, if specified 'mandatory' or if left unspecified,
222c593315Sopenharmony_ci#   indicates that baseline support for the specified C++ standard is
232c593315Sopenharmony_ci#   required and that the macro should error out if no mode with that
242c593315Sopenharmony_ci#   support is found.  If specified 'optional', then configuration proceeds
252c593315Sopenharmony_ci#   regardless, after defining HAVE_CXX${VERSION} if and only if a
262c593315Sopenharmony_ci#   supporting mode is found.
272c593315Sopenharmony_ci#
282c593315Sopenharmony_ci# LICENSE
292c593315Sopenharmony_ci#
302c593315Sopenharmony_ci#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
312c593315Sopenharmony_ci#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
322c593315Sopenharmony_ci#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
332c593315Sopenharmony_ci#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
342c593315Sopenharmony_ci#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
352c593315Sopenharmony_ci#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
362c593315Sopenharmony_ci#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
372c593315Sopenharmony_ci#
382c593315Sopenharmony_ci#   Copying and distribution of this file, with or without modification, are
392c593315Sopenharmony_ci#   permitted in any medium without royalty provided the copyright notice
402c593315Sopenharmony_ci#   and this notice are preserved.  This file is offered as-is, without any
412c593315Sopenharmony_ci#   warranty.
422c593315Sopenharmony_ci
432c593315Sopenharmony_ci#serial 10
442c593315Sopenharmony_ci
452c593315Sopenharmony_cidnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
462c593315Sopenharmony_cidnl  (serial version number 13).
472c593315Sopenharmony_ci
482c593315Sopenharmony_ciAC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
492c593315Sopenharmony_ci  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
502c593315Sopenharmony_ci        [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
512c593315Sopenharmony_ci        [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
522c593315Sopenharmony_ci        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
532c593315Sopenharmony_ci  m4_if([$2], [], [],
542c593315Sopenharmony_ci        [$2], [ext], [],
552c593315Sopenharmony_ci        [$2], [noext], [],
562c593315Sopenharmony_ci        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
572c593315Sopenharmony_ci  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
582c593315Sopenharmony_ci        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
592c593315Sopenharmony_ci        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
602c593315Sopenharmony_ci        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
612c593315Sopenharmony_ci  AC_LANG_PUSH([C++])dnl
622c593315Sopenharmony_ci  ac_success=no
632c593315Sopenharmony_ci
642c593315Sopenharmony_ci  m4_if([$2], [noext], [], [dnl
652c593315Sopenharmony_ci  if test x$ac_success = xno; then
662c593315Sopenharmony_ci    for alternative in ${ax_cxx_compile_alternatives}; do
672c593315Sopenharmony_ci      switch="-std=gnu++${alternative}"
682c593315Sopenharmony_ci      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
692c593315Sopenharmony_ci      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
702c593315Sopenharmony_ci                     $cachevar,
712c593315Sopenharmony_ci        [ac_save_CXX="$CXX"
722c593315Sopenharmony_ci         CXX="$CXX $switch"
732c593315Sopenharmony_ci         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
742c593315Sopenharmony_ci          [eval $cachevar=yes],
752c593315Sopenharmony_ci          [eval $cachevar=no])
762c593315Sopenharmony_ci         CXX="$ac_save_CXX"])
772c593315Sopenharmony_ci      if eval test x\$$cachevar = xyes; then
782c593315Sopenharmony_ci        CXX="$CXX $switch"
792c593315Sopenharmony_ci        if test -n "$CXXCPP" ; then
802c593315Sopenharmony_ci          CXXCPP="$CXXCPP $switch"
812c593315Sopenharmony_ci        fi
822c593315Sopenharmony_ci        ac_success=yes
832c593315Sopenharmony_ci        break
842c593315Sopenharmony_ci      fi
852c593315Sopenharmony_ci    done
862c593315Sopenharmony_ci  fi])
872c593315Sopenharmony_ci
882c593315Sopenharmony_ci  m4_if([$2], [ext], [], [dnl
892c593315Sopenharmony_ci  if test x$ac_success = xno; then
902c593315Sopenharmony_ci    dnl HP's aCC needs +std=c++11 according to:
912c593315Sopenharmony_ci    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
922c593315Sopenharmony_ci    dnl Cray's crayCC needs "-h std=c++11"
932c593315Sopenharmony_ci    for alternative in ${ax_cxx_compile_alternatives}; do
942c593315Sopenharmony_ci      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
952c593315Sopenharmony_ci        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
962c593315Sopenharmony_ci        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
972c593315Sopenharmony_ci                       $cachevar,
982c593315Sopenharmony_ci          [ac_save_CXX="$CXX"
992c593315Sopenharmony_ci           CXX="$CXX $switch"
1002c593315Sopenharmony_ci           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
1012c593315Sopenharmony_ci            [eval $cachevar=yes],
1022c593315Sopenharmony_ci            [eval $cachevar=no])
1032c593315Sopenharmony_ci           CXX="$ac_save_CXX"])
1042c593315Sopenharmony_ci        if eval test x\$$cachevar = xyes; then
1052c593315Sopenharmony_ci          CXX="$CXX $switch"
1062c593315Sopenharmony_ci          if test -n "$CXXCPP" ; then
1072c593315Sopenharmony_ci            CXXCPP="$CXXCPP $switch"
1082c593315Sopenharmony_ci          fi
1092c593315Sopenharmony_ci          ac_success=yes
1102c593315Sopenharmony_ci          break
1112c593315Sopenharmony_ci        fi
1122c593315Sopenharmony_ci      done
1132c593315Sopenharmony_ci      if test x$ac_success = xyes; then
1142c593315Sopenharmony_ci        break
1152c593315Sopenharmony_ci      fi
1162c593315Sopenharmony_ci    done
1172c593315Sopenharmony_ci  fi])
1182c593315Sopenharmony_ci  AC_LANG_POP([C++])
1192c593315Sopenharmony_ci  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
1202c593315Sopenharmony_ci    if test x$ac_success = xno; then
1212c593315Sopenharmony_ci      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
1222c593315Sopenharmony_ci    fi
1232c593315Sopenharmony_ci  fi
1242c593315Sopenharmony_ci  if test x$ac_success = xno; then
1252c593315Sopenharmony_ci    HAVE_CXX$1=0
1262c593315Sopenharmony_ci    AC_MSG_NOTICE([No compiler with C++$1 support was found])
1272c593315Sopenharmony_ci  else
1282c593315Sopenharmony_ci    HAVE_CXX$1=1
1292c593315Sopenharmony_ci    AC_DEFINE(HAVE_CXX$1,1,
1302c593315Sopenharmony_ci              [define if the compiler supports basic C++$1 syntax])
1312c593315Sopenharmony_ci  fi
1322c593315Sopenharmony_ci  AC_SUBST(HAVE_CXX$1)
1332c593315Sopenharmony_ci])
1342c593315Sopenharmony_ci
1352c593315Sopenharmony_ci
1362c593315Sopenharmony_cidnl  Test body for checking C++11 support
1372c593315Sopenharmony_ci
1382c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
1392c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
1402c593315Sopenharmony_ci)
1412c593315Sopenharmony_ci
1422c593315Sopenharmony_ci
1432c593315Sopenharmony_cidnl  Test body for checking C++14 support
1442c593315Sopenharmony_ci
1452c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
1462c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
1472c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
1482c593315Sopenharmony_ci)
1492c593315Sopenharmony_ci
1502c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
1512c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
1522c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
1532c593315Sopenharmony_ci  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
1542c593315Sopenharmony_ci)
1552c593315Sopenharmony_ci
1562c593315Sopenharmony_cidnl  Tests for new features in C++11
1572c593315Sopenharmony_ci
1582c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
1592c593315Sopenharmony_ci
1602c593315Sopenharmony_ci// If the compiler admits that it is not ready for C++11, why torture it?
1612c593315Sopenharmony_ci// Hopefully, this will speed up the test.
1622c593315Sopenharmony_ci
1632c593315Sopenharmony_ci#ifndef __cplusplus
1642c593315Sopenharmony_ci
1652c593315Sopenharmony_ci#error "This is not a C++ compiler"
1662c593315Sopenharmony_ci
1672c593315Sopenharmony_ci#elif __cplusplus < 201103L
1682c593315Sopenharmony_ci
1692c593315Sopenharmony_ci#error "This is not a C++11 compiler"
1702c593315Sopenharmony_ci
1712c593315Sopenharmony_ci#else
1722c593315Sopenharmony_ci
1732c593315Sopenharmony_cinamespace cxx11
1742c593315Sopenharmony_ci{
1752c593315Sopenharmony_ci
1762c593315Sopenharmony_ci  namespace test_static_assert
1772c593315Sopenharmony_ci  {
1782c593315Sopenharmony_ci
1792c593315Sopenharmony_ci    template <typename T>
1802c593315Sopenharmony_ci    struct check
1812c593315Sopenharmony_ci    {
1822c593315Sopenharmony_ci      static_assert(sizeof(int) <= sizeof(T), "not big enough");
1832c593315Sopenharmony_ci    };
1842c593315Sopenharmony_ci
1852c593315Sopenharmony_ci  }
1862c593315Sopenharmony_ci
1872c593315Sopenharmony_ci  namespace test_final_override
1882c593315Sopenharmony_ci  {
1892c593315Sopenharmony_ci
1902c593315Sopenharmony_ci    struct Base
1912c593315Sopenharmony_ci    {
1922c593315Sopenharmony_ci      virtual void f() {}
1932c593315Sopenharmony_ci    };
1942c593315Sopenharmony_ci
1952c593315Sopenharmony_ci    struct Derived : public Base
1962c593315Sopenharmony_ci    {
1972c593315Sopenharmony_ci      virtual void f() override {}
1982c593315Sopenharmony_ci    };
1992c593315Sopenharmony_ci
2002c593315Sopenharmony_ci  }
2012c593315Sopenharmony_ci
2022c593315Sopenharmony_ci  namespace test_double_right_angle_brackets
2032c593315Sopenharmony_ci  {
2042c593315Sopenharmony_ci
2052c593315Sopenharmony_ci    template < typename T >
2062c593315Sopenharmony_ci    struct check {};
2072c593315Sopenharmony_ci
2082c593315Sopenharmony_ci    typedef check<void> single_type;
2092c593315Sopenharmony_ci    typedef check<check<void>> double_type;
2102c593315Sopenharmony_ci    typedef check<check<check<void>>> triple_type;
2112c593315Sopenharmony_ci    typedef check<check<check<check<void>>>> quadruple_type;
2122c593315Sopenharmony_ci
2132c593315Sopenharmony_ci  }
2142c593315Sopenharmony_ci
2152c593315Sopenharmony_ci  namespace test_decltype
2162c593315Sopenharmony_ci  {
2172c593315Sopenharmony_ci
2182c593315Sopenharmony_ci    int
2192c593315Sopenharmony_ci    f()
2202c593315Sopenharmony_ci    {
2212c593315Sopenharmony_ci      int a = 1;
2222c593315Sopenharmony_ci      decltype(a) b = 2;
2232c593315Sopenharmony_ci      return a + b;
2242c593315Sopenharmony_ci    }
2252c593315Sopenharmony_ci
2262c593315Sopenharmony_ci  }
2272c593315Sopenharmony_ci
2282c593315Sopenharmony_ci  namespace test_type_deduction
2292c593315Sopenharmony_ci  {
2302c593315Sopenharmony_ci
2312c593315Sopenharmony_ci    template < typename T1, typename T2 >
2322c593315Sopenharmony_ci    struct is_same
2332c593315Sopenharmony_ci    {
2342c593315Sopenharmony_ci      static const bool value = false;
2352c593315Sopenharmony_ci    };
2362c593315Sopenharmony_ci
2372c593315Sopenharmony_ci    template < typename T >
2382c593315Sopenharmony_ci    struct is_same<T, T>
2392c593315Sopenharmony_ci    {
2402c593315Sopenharmony_ci      static const bool value = true;
2412c593315Sopenharmony_ci    };
2422c593315Sopenharmony_ci
2432c593315Sopenharmony_ci    template < typename T1, typename T2 >
2442c593315Sopenharmony_ci    auto
2452c593315Sopenharmony_ci    add(T1 a1, T2 a2) -> decltype(a1 + a2)
2462c593315Sopenharmony_ci    {
2472c593315Sopenharmony_ci      return a1 + a2;
2482c593315Sopenharmony_ci    }
2492c593315Sopenharmony_ci
2502c593315Sopenharmony_ci    int
2512c593315Sopenharmony_ci    test(const int c, volatile int v)
2522c593315Sopenharmony_ci    {
2532c593315Sopenharmony_ci      static_assert(is_same<int, decltype(0)>::value == true, "");
2542c593315Sopenharmony_ci      static_assert(is_same<int, decltype(c)>::value == false, "");
2552c593315Sopenharmony_ci      static_assert(is_same<int, decltype(v)>::value == false, "");
2562c593315Sopenharmony_ci      auto ac = c;
2572c593315Sopenharmony_ci      auto av = v;
2582c593315Sopenharmony_ci      auto sumi = ac + av + 'x';
2592c593315Sopenharmony_ci      auto sumf = ac + av + 1.0;
2602c593315Sopenharmony_ci      static_assert(is_same<int, decltype(ac)>::value == true, "");
2612c593315Sopenharmony_ci      static_assert(is_same<int, decltype(av)>::value == true, "");
2622c593315Sopenharmony_ci      static_assert(is_same<int, decltype(sumi)>::value == true, "");
2632c593315Sopenharmony_ci      static_assert(is_same<int, decltype(sumf)>::value == false, "");
2642c593315Sopenharmony_ci      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
2652c593315Sopenharmony_ci      return (sumf > 0.0) ? sumi : add(c, v);
2662c593315Sopenharmony_ci    }
2672c593315Sopenharmony_ci
2682c593315Sopenharmony_ci  }
2692c593315Sopenharmony_ci
2702c593315Sopenharmony_ci  namespace test_noexcept
2712c593315Sopenharmony_ci  {
2722c593315Sopenharmony_ci
2732c593315Sopenharmony_ci    int f() { return 0; }
2742c593315Sopenharmony_ci    int g() noexcept { return 0; }
2752c593315Sopenharmony_ci
2762c593315Sopenharmony_ci    static_assert(noexcept(f()) == false, "");
2772c593315Sopenharmony_ci    static_assert(noexcept(g()) == true, "");
2782c593315Sopenharmony_ci
2792c593315Sopenharmony_ci  }
2802c593315Sopenharmony_ci
2812c593315Sopenharmony_ci  namespace test_constexpr
2822c593315Sopenharmony_ci  {
2832c593315Sopenharmony_ci
2842c593315Sopenharmony_ci    template < typename CharT >
2852c593315Sopenharmony_ci    unsigned long constexpr
2862c593315Sopenharmony_ci    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
2872c593315Sopenharmony_ci    {
2882c593315Sopenharmony_ci      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
2892c593315Sopenharmony_ci    }
2902c593315Sopenharmony_ci
2912c593315Sopenharmony_ci    template < typename CharT >
2922c593315Sopenharmony_ci    unsigned long constexpr
2932c593315Sopenharmony_ci    strlen_c(const CharT *const s) noexcept
2942c593315Sopenharmony_ci    {
2952c593315Sopenharmony_ci      return strlen_c_r(s, 0UL);
2962c593315Sopenharmony_ci    }
2972c593315Sopenharmony_ci
2982c593315Sopenharmony_ci    static_assert(strlen_c("") == 0UL, "");
2992c593315Sopenharmony_ci    static_assert(strlen_c("1") == 1UL, "");
3002c593315Sopenharmony_ci    static_assert(strlen_c("example") == 7UL, "");
3012c593315Sopenharmony_ci    static_assert(strlen_c("another\0example") == 7UL, "");
3022c593315Sopenharmony_ci
3032c593315Sopenharmony_ci  }
3042c593315Sopenharmony_ci
3052c593315Sopenharmony_ci  namespace test_rvalue_references
3062c593315Sopenharmony_ci  {
3072c593315Sopenharmony_ci
3082c593315Sopenharmony_ci    template < int N >
3092c593315Sopenharmony_ci    struct answer
3102c593315Sopenharmony_ci    {
3112c593315Sopenharmony_ci      static constexpr int value = N;
3122c593315Sopenharmony_ci    };
3132c593315Sopenharmony_ci
3142c593315Sopenharmony_ci    answer<1> f(int&)       { return answer<1>(); }
3152c593315Sopenharmony_ci    answer<2> f(const int&) { return answer<2>(); }
3162c593315Sopenharmony_ci    answer<3> f(int&&)      { return answer<3>(); }
3172c593315Sopenharmony_ci
3182c593315Sopenharmony_ci    void
3192c593315Sopenharmony_ci    test()
3202c593315Sopenharmony_ci    {
3212c593315Sopenharmony_ci      int i = 0;
3222c593315Sopenharmony_ci      const int c = 0;
3232c593315Sopenharmony_ci      static_assert(decltype(f(i))::value == 1, "");
3242c593315Sopenharmony_ci      static_assert(decltype(f(c))::value == 2, "");
3252c593315Sopenharmony_ci      static_assert(decltype(f(0))::value == 3, "");
3262c593315Sopenharmony_ci    }
3272c593315Sopenharmony_ci
3282c593315Sopenharmony_ci  }
3292c593315Sopenharmony_ci
3302c593315Sopenharmony_ci  namespace test_uniform_initialization
3312c593315Sopenharmony_ci  {
3322c593315Sopenharmony_ci
3332c593315Sopenharmony_ci    struct test
3342c593315Sopenharmony_ci    {
3352c593315Sopenharmony_ci      static const int zero {};
3362c593315Sopenharmony_ci      static const int one {1};
3372c593315Sopenharmony_ci    };
3382c593315Sopenharmony_ci
3392c593315Sopenharmony_ci    static_assert(test::zero == 0, "");
3402c593315Sopenharmony_ci    static_assert(test::one == 1, "");
3412c593315Sopenharmony_ci
3422c593315Sopenharmony_ci  }
3432c593315Sopenharmony_ci
3442c593315Sopenharmony_ci  namespace test_lambdas
3452c593315Sopenharmony_ci  {
3462c593315Sopenharmony_ci
3472c593315Sopenharmony_ci    void
3482c593315Sopenharmony_ci    test1()
3492c593315Sopenharmony_ci    {
3502c593315Sopenharmony_ci      auto lambda1 = [](){};
3512c593315Sopenharmony_ci      auto lambda2 = lambda1;
3522c593315Sopenharmony_ci      lambda1();
3532c593315Sopenharmony_ci      lambda2();
3542c593315Sopenharmony_ci    }
3552c593315Sopenharmony_ci
3562c593315Sopenharmony_ci    int
3572c593315Sopenharmony_ci    test2()
3582c593315Sopenharmony_ci    {
3592c593315Sopenharmony_ci      auto a = [](int i, int j){ return i + j; }(1, 2);
3602c593315Sopenharmony_ci      auto b = []() -> int { return '0'; }();
3612c593315Sopenharmony_ci      auto c = [=](){ return a + b; }();
3622c593315Sopenharmony_ci      auto d = [&](){ return c; }();
3632c593315Sopenharmony_ci      auto e = [a, &b](int x) mutable {
3642c593315Sopenharmony_ci        const auto identity = [](int y){ return y; };
3652c593315Sopenharmony_ci        for (auto i = 0; i < a; ++i)
3662c593315Sopenharmony_ci          a += b--;
3672c593315Sopenharmony_ci        return x + identity(a + b);
3682c593315Sopenharmony_ci      }(0);
3692c593315Sopenharmony_ci      return a + b + c + d + e;
3702c593315Sopenharmony_ci    }
3712c593315Sopenharmony_ci
3722c593315Sopenharmony_ci    int
3732c593315Sopenharmony_ci    test3()
3742c593315Sopenharmony_ci    {
3752c593315Sopenharmony_ci      const auto nullary = [](){ return 0; };
3762c593315Sopenharmony_ci      const auto unary = [](int x){ return x; };
3772c593315Sopenharmony_ci      using nullary_t = decltype(nullary);
3782c593315Sopenharmony_ci      using unary_t = decltype(unary);
3792c593315Sopenharmony_ci      const auto higher1st = [](nullary_t f){ return f(); };
3802c593315Sopenharmony_ci      const auto higher2nd = [unary](nullary_t f1){
3812c593315Sopenharmony_ci        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
3822c593315Sopenharmony_ci      };
3832c593315Sopenharmony_ci      return higher1st(nullary) + higher2nd(nullary)(unary);
3842c593315Sopenharmony_ci    }
3852c593315Sopenharmony_ci
3862c593315Sopenharmony_ci  }
3872c593315Sopenharmony_ci
3882c593315Sopenharmony_ci  namespace test_variadic_templates
3892c593315Sopenharmony_ci  {
3902c593315Sopenharmony_ci
3912c593315Sopenharmony_ci    template <int...>
3922c593315Sopenharmony_ci    struct sum;
3932c593315Sopenharmony_ci
3942c593315Sopenharmony_ci    template <int N0, int... N1toN>
3952c593315Sopenharmony_ci    struct sum<N0, N1toN...>
3962c593315Sopenharmony_ci    {
3972c593315Sopenharmony_ci      static constexpr auto value = N0 + sum<N1toN...>::value;
3982c593315Sopenharmony_ci    };
3992c593315Sopenharmony_ci
4002c593315Sopenharmony_ci    template <>
4012c593315Sopenharmony_ci    struct sum<>
4022c593315Sopenharmony_ci    {
4032c593315Sopenharmony_ci      static constexpr auto value = 0;
4042c593315Sopenharmony_ci    };
4052c593315Sopenharmony_ci
4062c593315Sopenharmony_ci    static_assert(sum<>::value == 0, "");
4072c593315Sopenharmony_ci    static_assert(sum<1>::value == 1, "");
4082c593315Sopenharmony_ci    static_assert(sum<23>::value == 23, "");
4092c593315Sopenharmony_ci    static_assert(sum<1, 2>::value == 3, "");
4102c593315Sopenharmony_ci    static_assert(sum<5, 5, 11>::value == 21, "");
4112c593315Sopenharmony_ci    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
4122c593315Sopenharmony_ci
4132c593315Sopenharmony_ci  }
4142c593315Sopenharmony_ci
4152c593315Sopenharmony_ci  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
4162c593315Sopenharmony_ci  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
4172c593315Sopenharmony_ci  // because of this.
4182c593315Sopenharmony_ci  namespace test_template_alias_sfinae
4192c593315Sopenharmony_ci  {
4202c593315Sopenharmony_ci
4212c593315Sopenharmony_ci    struct foo {};
4222c593315Sopenharmony_ci
4232c593315Sopenharmony_ci    template<typename T>
4242c593315Sopenharmony_ci    using member = typename T::member_type;
4252c593315Sopenharmony_ci
4262c593315Sopenharmony_ci    template<typename T>
4272c593315Sopenharmony_ci    void func(...) {}
4282c593315Sopenharmony_ci
4292c593315Sopenharmony_ci    template<typename T>
4302c593315Sopenharmony_ci    void func(member<T>*) {}
4312c593315Sopenharmony_ci
4322c593315Sopenharmony_ci    void test();
4332c593315Sopenharmony_ci
4342c593315Sopenharmony_ci    void test() { func<foo>(0); }
4352c593315Sopenharmony_ci
4362c593315Sopenharmony_ci  }
4372c593315Sopenharmony_ci
4382c593315Sopenharmony_ci}  // namespace cxx11
4392c593315Sopenharmony_ci
4402c593315Sopenharmony_ci#endif  // __cplusplus >= 201103L
4412c593315Sopenharmony_ci
4422c593315Sopenharmony_ci]])
4432c593315Sopenharmony_ci
4442c593315Sopenharmony_ci
4452c593315Sopenharmony_cidnl  Tests for new features in C++14
4462c593315Sopenharmony_ci
4472c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
4482c593315Sopenharmony_ci
4492c593315Sopenharmony_ci// If the compiler admits that it is not ready for C++14, why torture it?
4502c593315Sopenharmony_ci// Hopefully, this will speed up the test.
4512c593315Sopenharmony_ci
4522c593315Sopenharmony_ci#ifndef __cplusplus
4532c593315Sopenharmony_ci
4542c593315Sopenharmony_ci#error "This is not a C++ compiler"
4552c593315Sopenharmony_ci
4562c593315Sopenharmony_ci#elif __cplusplus < 201402L
4572c593315Sopenharmony_ci
4582c593315Sopenharmony_ci#error "This is not a C++14 compiler"
4592c593315Sopenharmony_ci
4602c593315Sopenharmony_ci#else
4612c593315Sopenharmony_ci
4622c593315Sopenharmony_cinamespace cxx14
4632c593315Sopenharmony_ci{
4642c593315Sopenharmony_ci
4652c593315Sopenharmony_ci  namespace test_polymorphic_lambdas
4662c593315Sopenharmony_ci  {
4672c593315Sopenharmony_ci
4682c593315Sopenharmony_ci    int
4692c593315Sopenharmony_ci    test()
4702c593315Sopenharmony_ci    {
4712c593315Sopenharmony_ci      const auto lambda = [](auto&&... args){
4722c593315Sopenharmony_ci        const auto istiny = [](auto x){
4732c593315Sopenharmony_ci          return (sizeof(x) == 1UL) ? 1 : 0;
4742c593315Sopenharmony_ci        };
4752c593315Sopenharmony_ci        const int aretiny[] = { istiny(args)... };
4762c593315Sopenharmony_ci        return aretiny[0];
4772c593315Sopenharmony_ci      };
4782c593315Sopenharmony_ci      return lambda(1, 1L, 1.0f, '1');
4792c593315Sopenharmony_ci    }
4802c593315Sopenharmony_ci
4812c593315Sopenharmony_ci  }
4822c593315Sopenharmony_ci
4832c593315Sopenharmony_ci  namespace test_binary_literals
4842c593315Sopenharmony_ci  {
4852c593315Sopenharmony_ci
4862c593315Sopenharmony_ci    constexpr auto ivii = 0b0000000000101010;
4872c593315Sopenharmony_ci    static_assert(ivii == 42, "wrong value");
4882c593315Sopenharmony_ci
4892c593315Sopenharmony_ci  }
4902c593315Sopenharmony_ci
4912c593315Sopenharmony_ci  namespace test_generalized_constexpr
4922c593315Sopenharmony_ci  {
4932c593315Sopenharmony_ci
4942c593315Sopenharmony_ci    template < typename CharT >
4952c593315Sopenharmony_ci    constexpr unsigned long
4962c593315Sopenharmony_ci    strlen_c(const CharT *const s) noexcept
4972c593315Sopenharmony_ci    {
4982c593315Sopenharmony_ci      auto length = 0UL;
4992c593315Sopenharmony_ci      for (auto p = s; *p; ++p)
5002c593315Sopenharmony_ci        ++length;
5012c593315Sopenharmony_ci      return length;
5022c593315Sopenharmony_ci    }
5032c593315Sopenharmony_ci
5042c593315Sopenharmony_ci    static_assert(strlen_c("") == 0UL, "");
5052c593315Sopenharmony_ci    static_assert(strlen_c("x") == 1UL, "");
5062c593315Sopenharmony_ci    static_assert(strlen_c("test") == 4UL, "");
5072c593315Sopenharmony_ci    static_assert(strlen_c("another\0test") == 7UL, "");
5082c593315Sopenharmony_ci
5092c593315Sopenharmony_ci  }
5102c593315Sopenharmony_ci
5112c593315Sopenharmony_ci  namespace test_lambda_init_capture
5122c593315Sopenharmony_ci  {
5132c593315Sopenharmony_ci
5142c593315Sopenharmony_ci    int
5152c593315Sopenharmony_ci    test()
5162c593315Sopenharmony_ci    {
5172c593315Sopenharmony_ci      auto x = 0;
5182c593315Sopenharmony_ci      const auto lambda1 = [a = x](int b){ return a + b; };
5192c593315Sopenharmony_ci      const auto lambda2 = [a = lambda1(x)](){ return a; };
5202c593315Sopenharmony_ci      return lambda2();
5212c593315Sopenharmony_ci    }
5222c593315Sopenharmony_ci
5232c593315Sopenharmony_ci  }
5242c593315Sopenharmony_ci
5252c593315Sopenharmony_ci  namespace test_digit_separators
5262c593315Sopenharmony_ci  {
5272c593315Sopenharmony_ci
5282c593315Sopenharmony_ci    constexpr auto ten_million = 100'000'000;
5292c593315Sopenharmony_ci    static_assert(ten_million == 100000000, "");
5302c593315Sopenharmony_ci
5312c593315Sopenharmony_ci  }
5322c593315Sopenharmony_ci
5332c593315Sopenharmony_ci  namespace test_return_type_deduction
5342c593315Sopenharmony_ci  {
5352c593315Sopenharmony_ci
5362c593315Sopenharmony_ci    auto f(int& x) { return x; }
5372c593315Sopenharmony_ci    decltype(auto) g(int& x) { return x; }
5382c593315Sopenharmony_ci
5392c593315Sopenharmony_ci    template < typename T1, typename T2 >
5402c593315Sopenharmony_ci    struct is_same
5412c593315Sopenharmony_ci    {
5422c593315Sopenharmony_ci      static constexpr auto value = false;
5432c593315Sopenharmony_ci    };
5442c593315Sopenharmony_ci
5452c593315Sopenharmony_ci    template < typename T >
5462c593315Sopenharmony_ci    struct is_same<T, T>
5472c593315Sopenharmony_ci    {
5482c593315Sopenharmony_ci      static constexpr auto value = true;
5492c593315Sopenharmony_ci    };
5502c593315Sopenharmony_ci
5512c593315Sopenharmony_ci    int
5522c593315Sopenharmony_ci    test()
5532c593315Sopenharmony_ci    {
5542c593315Sopenharmony_ci      auto x = 0;
5552c593315Sopenharmony_ci      static_assert(is_same<int, decltype(f(x))>::value, "");
5562c593315Sopenharmony_ci      static_assert(is_same<int&, decltype(g(x))>::value, "");
5572c593315Sopenharmony_ci      return x;
5582c593315Sopenharmony_ci    }
5592c593315Sopenharmony_ci
5602c593315Sopenharmony_ci  }
5612c593315Sopenharmony_ci
5622c593315Sopenharmony_ci}  // namespace cxx14
5632c593315Sopenharmony_ci
5642c593315Sopenharmony_ci#endif  // __cplusplus >= 201402L
5652c593315Sopenharmony_ci
5662c593315Sopenharmony_ci]])
5672c593315Sopenharmony_ci
5682c593315Sopenharmony_ci
5692c593315Sopenharmony_cidnl  Tests for new features in C++17
5702c593315Sopenharmony_ci
5712c593315Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
5722c593315Sopenharmony_ci
5732c593315Sopenharmony_ci// If the compiler admits that it is not ready for C++17, why torture it?
5742c593315Sopenharmony_ci// Hopefully, this will speed up the test.
5752c593315Sopenharmony_ci
5762c593315Sopenharmony_ci#ifndef __cplusplus
5772c593315Sopenharmony_ci
5782c593315Sopenharmony_ci#error "This is not a C++ compiler"
5792c593315Sopenharmony_ci
5802c593315Sopenharmony_ci#elif __cplusplus < 201703L
5812c593315Sopenharmony_ci
5822c593315Sopenharmony_ci#error "This is not a C++17 compiler"
5832c593315Sopenharmony_ci
5842c593315Sopenharmony_ci#else
5852c593315Sopenharmony_ci
5862c593315Sopenharmony_ci#include <initializer_list>
5872c593315Sopenharmony_ci#include <utility>
5882c593315Sopenharmony_ci#include <type_traits>
5892c593315Sopenharmony_ci
5902c593315Sopenharmony_cinamespace cxx17
5912c593315Sopenharmony_ci{
5922c593315Sopenharmony_ci
5932c593315Sopenharmony_ci  namespace test_constexpr_lambdas
5942c593315Sopenharmony_ci  {
5952c593315Sopenharmony_ci
5962c593315Sopenharmony_ci    constexpr int foo = [](){return 42;}();
5972c593315Sopenharmony_ci
5982c593315Sopenharmony_ci  }
5992c593315Sopenharmony_ci
6002c593315Sopenharmony_ci  namespace test::nested_namespace::definitions
6012c593315Sopenharmony_ci  {
6022c593315Sopenharmony_ci
6032c593315Sopenharmony_ci  }
6042c593315Sopenharmony_ci
6052c593315Sopenharmony_ci  namespace test_fold_expression
6062c593315Sopenharmony_ci  {
6072c593315Sopenharmony_ci
6082c593315Sopenharmony_ci    template<typename... Args>
6092c593315Sopenharmony_ci    int multiply(Args... args)
6102c593315Sopenharmony_ci    {
6112c593315Sopenharmony_ci      return (args * ... * 1);
6122c593315Sopenharmony_ci    }
6132c593315Sopenharmony_ci
6142c593315Sopenharmony_ci    template<typename... Args>
6152c593315Sopenharmony_ci    bool all(Args... args)
6162c593315Sopenharmony_ci    {
6172c593315Sopenharmony_ci      return (args && ...);
6182c593315Sopenharmony_ci    }
6192c593315Sopenharmony_ci
6202c593315Sopenharmony_ci  }
6212c593315Sopenharmony_ci
6222c593315Sopenharmony_ci  namespace test_extended_static_assert
6232c593315Sopenharmony_ci  {
6242c593315Sopenharmony_ci
6252c593315Sopenharmony_ci    static_assert (true);
6262c593315Sopenharmony_ci
6272c593315Sopenharmony_ci  }
6282c593315Sopenharmony_ci
6292c593315Sopenharmony_ci  namespace test_auto_brace_init_list
6302c593315Sopenharmony_ci  {
6312c593315Sopenharmony_ci
6322c593315Sopenharmony_ci    auto foo = {5};
6332c593315Sopenharmony_ci    auto bar {5};
6342c593315Sopenharmony_ci
6352c593315Sopenharmony_ci    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
6362c593315Sopenharmony_ci    static_assert(std::is_same<int, decltype(bar)>::value);
6372c593315Sopenharmony_ci  }
6382c593315Sopenharmony_ci
6392c593315Sopenharmony_ci  namespace test_typename_in_template_template_parameter
6402c593315Sopenharmony_ci  {
6412c593315Sopenharmony_ci
6422c593315Sopenharmony_ci    template<template<typename> typename X> struct D;
6432c593315Sopenharmony_ci
6442c593315Sopenharmony_ci  }
6452c593315Sopenharmony_ci
6462c593315Sopenharmony_ci  namespace test_fallthrough_nodiscard_maybe_unused_attributes
6472c593315Sopenharmony_ci  {
6482c593315Sopenharmony_ci
6492c593315Sopenharmony_ci    int f1()
6502c593315Sopenharmony_ci    {
6512c593315Sopenharmony_ci      return 42;
6522c593315Sopenharmony_ci    }
6532c593315Sopenharmony_ci
6542c593315Sopenharmony_ci    [[nodiscard]] int f2()
6552c593315Sopenharmony_ci    {
6562c593315Sopenharmony_ci      [[maybe_unused]] auto unused = f1();
6572c593315Sopenharmony_ci
6582c593315Sopenharmony_ci      switch (f1())
6592c593315Sopenharmony_ci      {
6602c593315Sopenharmony_ci      case 17:
6612c593315Sopenharmony_ci        f1();
6622c593315Sopenharmony_ci        [[fallthrough]];
6632c593315Sopenharmony_ci      case 42:
6642c593315Sopenharmony_ci        f1();
6652c593315Sopenharmony_ci      }
6662c593315Sopenharmony_ci      return f1();
6672c593315Sopenharmony_ci    }
6682c593315Sopenharmony_ci
6692c593315Sopenharmony_ci  }
6702c593315Sopenharmony_ci
6712c593315Sopenharmony_ci  namespace test_extended_aggregate_initialization
6722c593315Sopenharmony_ci  {
6732c593315Sopenharmony_ci
6742c593315Sopenharmony_ci    struct base1
6752c593315Sopenharmony_ci    {
6762c593315Sopenharmony_ci      int b1, b2 = 42;
6772c593315Sopenharmony_ci    };
6782c593315Sopenharmony_ci
6792c593315Sopenharmony_ci    struct base2
6802c593315Sopenharmony_ci    {
6812c593315Sopenharmony_ci      base2() {
6822c593315Sopenharmony_ci        b3 = 42;
6832c593315Sopenharmony_ci      }
6842c593315Sopenharmony_ci      int b3;
6852c593315Sopenharmony_ci    };
6862c593315Sopenharmony_ci
6872c593315Sopenharmony_ci    struct derived : base1, base2
6882c593315Sopenharmony_ci    {
6892c593315Sopenharmony_ci        int d;
6902c593315Sopenharmony_ci    };
6912c593315Sopenharmony_ci
6922c593315Sopenharmony_ci    derived d1 {{1, 2}, {}, 4};  // full initialization
6932c593315Sopenharmony_ci    derived d2 {{}, {}, 4};      // value-initialized bases
6942c593315Sopenharmony_ci
6952c593315Sopenharmony_ci  }
6962c593315Sopenharmony_ci
6972c593315Sopenharmony_ci  namespace test_general_range_based_for_loop
6982c593315Sopenharmony_ci  {
6992c593315Sopenharmony_ci
7002c593315Sopenharmony_ci    struct iter
7012c593315Sopenharmony_ci    {
7022c593315Sopenharmony_ci      int i;
7032c593315Sopenharmony_ci
7042c593315Sopenharmony_ci      int& operator* ()
7052c593315Sopenharmony_ci      {
7062c593315Sopenharmony_ci        return i;
7072c593315Sopenharmony_ci      }
7082c593315Sopenharmony_ci
7092c593315Sopenharmony_ci      const int& operator* () const
7102c593315Sopenharmony_ci      {
7112c593315Sopenharmony_ci        return i;
7122c593315Sopenharmony_ci      }
7132c593315Sopenharmony_ci
7142c593315Sopenharmony_ci      iter& operator++()
7152c593315Sopenharmony_ci      {
7162c593315Sopenharmony_ci        ++i;
7172c593315Sopenharmony_ci        return *this;
7182c593315Sopenharmony_ci      }
7192c593315Sopenharmony_ci    };
7202c593315Sopenharmony_ci
7212c593315Sopenharmony_ci    struct sentinel
7222c593315Sopenharmony_ci    {
7232c593315Sopenharmony_ci      int i;
7242c593315Sopenharmony_ci    };
7252c593315Sopenharmony_ci
7262c593315Sopenharmony_ci    bool operator== (const iter& i, const sentinel& s)
7272c593315Sopenharmony_ci    {
7282c593315Sopenharmony_ci      return i.i == s.i;
7292c593315Sopenharmony_ci    }
7302c593315Sopenharmony_ci
7312c593315Sopenharmony_ci    bool operator!= (const iter& i, const sentinel& s)
7322c593315Sopenharmony_ci    {
7332c593315Sopenharmony_ci      return !(i == s);
7342c593315Sopenharmony_ci    }
7352c593315Sopenharmony_ci
7362c593315Sopenharmony_ci    struct range
7372c593315Sopenharmony_ci    {
7382c593315Sopenharmony_ci      iter begin() const
7392c593315Sopenharmony_ci      {
7402c593315Sopenharmony_ci        return {0};
7412c593315Sopenharmony_ci      }
7422c593315Sopenharmony_ci
7432c593315Sopenharmony_ci      sentinel end() const
7442c593315Sopenharmony_ci      {
7452c593315Sopenharmony_ci        return {5};
7462c593315Sopenharmony_ci      }
7472c593315Sopenharmony_ci    };
7482c593315Sopenharmony_ci
7492c593315Sopenharmony_ci    void f()
7502c593315Sopenharmony_ci    {
7512c593315Sopenharmony_ci      range r {};
7522c593315Sopenharmony_ci
7532c593315Sopenharmony_ci      for (auto i : r)
7542c593315Sopenharmony_ci      {
7552c593315Sopenharmony_ci        [[maybe_unused]] auto v = i;
7562c593315Sopenharmony_ci      }
7572c593315Sopenharmony_ci    }
7582c593315Sopenharmony_ci
7592c593315Sopenharmony_ci  }
7602c593315Sopenharmony_ci
7612c593315Sopenharmony_ci  namespace test_lambda_capture_asterisk_this_by_value
7622c593315Sopenharmony_ci  {
7632c593315Sopenharmony_ci
7642c593315Sopenharmony_ci    struct t
7652c593315Sopenharmony_ci    {
7662c593315Sopenharmony_ci      int i;
7672c593315Sopenharmony_ci      int foo()
7682c593315Sopenharmony_ci      {
7692c593315Sopenharmony_ci        return [*this]()
7702c593315Sopenharmony_ci        {
7712c593315Sopenharmony_ci          return i;
7722c593315Sopenharmony_ci        }();
7732c593315Sopenharmony_ci      }
7742c593315Sopenharmony_ci    };
7752c593315Sopenharmony_ci
7762c593315Sopenharmony_ci  }
7772c593315Sopenharmony_ci
7782c593315Sopenharmony_ci  namespace test_enum_class_construction
7792c593315Sopenharmony_ci  {
7802c593315Sopenharmony_ci
7812c593315Sopenharmony_ci    enum class byte : unsigned char
7822c593315Sopenharmony_ci    {};
7832c593315Sopenharmony_ci
7842c593315Sopenharmony_ci    byte foo {42};
7852c593315Sopenharmony_ci
7862c593315Sopenharmony_ci  }
7872c593315Sopenharmony_ci
7882c593315Sopenharmony_ci  namespace test_constexpr_if
7892c593315Sopenharmony_ci  {
7902c593315Sopenharmony_ci
7912c593315Sopenharmony_ci    template <bool cond>
7922c593315Sopenharmony_ci    int f ()
7932c593315Sopenharmony_ci    {
7942c593315Sopenharmony_ci      if constexpr(cond)
7952c593315Sopenharmony_ci      {
7962c593315Sopenharmony_ci        return 13;
7972c593315Sopenharmony_ci      }
7982c593315Sopenharmony_ci      else
7992c593315Sopenharmony_ci      {
8002c593315Sopenharmony_ci        return 42;
8012c593315Sopenharmony_ci      }
8022c593315Sopenharmony_ci    }
8032c593315Sopenharmony_ci
8042c593315Sopenharmony_ci  }
8052c593315Sopenharmony_ci
8062c593315Sopenharmony_ci  namespace test_selection_statement_with_initializer
8072c593315Sopenharmony_ci  {
8082c593315Sopenharmony_ci
8092c593315Sopenharmony_ci    int f()
8102c593315Sopenharmony_ci    {
8112c593315Sopenharmony_ci      return 13;
8122c593315Sopenharmony_ci    }
8132c593315Sopenharmony_ci
8142c593315Sopenharmony_ci    int f2()
8152c593315Sopenharmony_ci    {
8162c593315Sopenharmony_ci      if (auto i = f(); i > 0)
8172c593315Sopenharmony_ci      {
8182c593315Sopenharmony_ci        return 3;
8192c593315Sopenharmony_ci      }
8202c593315Sopenharmony_ci
8212c593315Sopenharmony_ci      switch (auto i = f(); i + 4)
8222c593315Sopenharmony_ci      {
8232c593315Sopenharmony_ci      case 17:
8242c593315Sopenharmony_ci        return 2;
8252c593315Sopenharmony_ci
8262c593315Sopenharmony_ci      default:
8272c593315Sopenharmony_ci        return 1;
8282c593315Sopenharmony_ci      }
8292c593315Sopenharmony_ci    }
8302c593315Sopenharmony_ci
8312c593315Sopenharmony_ci  }
8322c593315Sopenharmony_ci
8332c593315Sopenharmony_ci  namespace test_template_argument_deduction_for_class_templates
8342c593315Sopenharmony_ci  {
8352c593315Sopenharmony_ci
8362c593315Sopenharmony_ci    template <typename T1, typename T2>
8372c593315Sopenharmony_ci    struct pair
8382c593315Sopenharmony_ci    {
8392c593315Sopenharmony_ci      pair (T1 p1, T2 p2)
8402c593315Sopenharmony_ci        : m1 {p1},
8412c593315Sopenharmony_ci          m2 {p2}
8422c593315Sopenharmony_ci      {}
8432c593315Sopenharmony_ci
8442c593315Sopenharmony_ci      T1 m1;
8452c593315Sopenharmony_ci      T2 m2;
8462c593315Sopenharmony_ci    };
8472c593315Sopenharmony_ci
8482c593315Sopenharmony_ci    void f()
8492c593315Sopenharmony_ci    {
8502c593315Sopenharmony_ci      [[maybe_unused]] auto p = pair{13, 42u};
8512c593315Sopenharmony_ci    }
8522c593315Sopenharmony_ci
8532c593315Sopenharmony_ci  }
8542c593315Sopenharmony_ci
8552c593315Sopenharmony_ci  namespace test_non_type_auto_template_parameters
8562c593315Sopenharmony_ci  {
8572c593315Sopenharmony_ci
8582c593315Sopenharmony_ci    template <auto n>
8592c593315Sopenharmony_ci    struct B
8602c593315Sopenharmony_ci    {};
8612c593315Sopenharmony_ci
8622c593315Sopenharmony_ci    B<5> b1;
8632c593315Sopenharmony_ci    B<'a'> b2;
8642c593315Sopenharmony_ci
8652c593315Sopenharmony_ci  }
8662c593315Sopenharmony_ci
8672c593315Sopenharmony_ci  namespace test_structured_bindings
8682c593315Sopenharmony_ci  {
8692c593315Sopenharmony_ci
8702c593315Sopenharmony_ci    int arr[2] = { 1, 2 };
8712c593315Sopenharmony_ci    std::pair<int, int> pr = { 1, 2 };
8722c593315Sopenharmony_ci
8732c593315Sopenharmony_ci    auto f1() -> int(&)[2]
8742c593315Sopenharmony_ci    {
8752c593315Sopenharmony_ci      return arr;
8762c593315Sopenharmony_ci    }
8772c593315Sopenharmony_ci
8782c593315Sopenharmony_ci    auto f2() -> std::pair<int, int>&
8792c593315Sopenharmony_ci    {
8802c593315Sopenharmony_ci      return pr;
8812c593315Sopenharmony_ci    }
8822c593315Sopenharmony_ci
8832c593315Sopenharmony_ci    struct S
8842c593315Sopenharmony_ci    {
8852c593315Sopenharmony_ci      int x1 : 2;
8862c593315Sopenharmony_ci      volatile double y1;
8872c593315Sopenharmony_ci    };
8882c593315Sopenharmony_ci
8892c593315Sopenharmony_ci    S f3()
8902c593315Sopenharmony_ci    {
8912c593315Sopenharmony_ci      return {};
8922c593315Sopenharmony_ci    }
8932c593315Sopenharmony_ci
8942c593315Sopenharmony_ci    auto [ x1, y1 ] = f1();
8952c593315Sopenharmony_ci    auto& [ xr1, yr1 ] = f1();
8962c593315Sopenharmony_ci    auto [ x2, y2 ] = f2();
8972c593315Sopenharmony_ci    auto& [ xr2, yr2 ] = f2();
8982c593315Sopenharmony_ci    const auto [ x3, y3 ] = f3();
8992c593315Sopenharmony_ci
9002c593315Sopenharmony_ci  }
9012c593315Sopenharmony_ci
9022c593315Sopenharmony_ci  namespace test_exception_spec_type_system
9032c593315Sopenharmony_ci  {
9042c593315Sopenharmony_ci
9052c593315Sopenharmony_ci    struct Good {};
9062c593315Sopenharmony_ci    struct Bad {};
9072c593315Sopenharmony_ci
9082c593315Sopenharmony_ci    void g1() noexcept;
9092c593315Sopenharmony_ci    void g2();
9102c593315Sopenharmony_ci
9112c593315Sopenharmony_ci    template<typename T>
9122c593315Sopenharmony_ci    Bad
9132c593315Sopenharmony_ci    f(T*, T*);
9142c593315Sopenharmony_ci
9152c593315Sopenharmony_ci    template<typename T1, typename T2>
9162c593315Sopenharmony_ci    Good
9172c593315Sopenharmony_ci    f(T1*, T2*);
9182c593315Sopenharmony_ci
9192c593315Sopenharmony_ci    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
9202c593315Sopenharmony_ci
9212c593315Sopenharmony_ci  }
9222c593315Sopenharmony_ci
9232c593315Sopenharmony_ci  namespace test_inline_variables
9242c593315Sopenharmony_ci  {
9252c593315Sopenharmony_ci
9262c593315Sopenharmony_ci    template<class T> void f(T)
9272c593315Sopenharmony_ci    {}
9282c593315Sopenharmony_ci
9292c593315Sopenharmony_ci    template<class T> inline T g(T)
9302c593315Sopenharmony_ci    {
9312c593315Sopenharmony_ci      return T{};
9322c593315Sopenharmony_ci    }
9332c593315Sopenharmony_ci
9342c593315Sopenharmony_ci    template<> inline void f<>(int)
9352c593315Sopenharmony_ci    {}
9362c593315Sopenharmony_ci
9372c593315Sopenharmony_ci    template<> int g<>(int)
9382c593315Sopenharmony_ci    {
9392c593315Sopenharmony_ci      return 5;
9402c593315Sopenharmony_ci    }
9412c593315Sopenharmony_ci
9422c593315Sopenharmony_ci  }
9432c593315Sopenharmony_ci
9442c593315Sopenharmony_ci}  // namespace cxx17
9452c593315Sopenharmony_ci
9462c593315Sopenharmony_ci#endif  // __cplusplus < 201703L
9472c593315Sopenharmony_ci
9482c593315Sopenharmony_ci]])
949