11cb0ef41Sopenharmony_ci# =========================================================================== 21cb0ef41Sopenharmony_ci# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html 31cb0ef41Sopenharmony_ci# =========================================================================== 41cb0ef41Sopenharmony_ci# 51cb0ef41Sopenharmony_ci# SYNOPSIS 61cb0ef41Sopenharmony_ci# 71cb0ef41Sopenharmony_ci# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) 81cb0ef41Sopenharmony_ci# 91cb0ef41Sopenharmony_ci# DESCRIPTION 101cb0ef41Sopenharmony_ci# 111cb0ef41Sopenharmony_ci# Check for baseline language coverage in the compiler for the specified 121cb0ef41Sopenharmony_ci# version of the C++ standard. If necessary, add switches to CXX and 131cb0ef41Sopenharmony_ci# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for 141cb0ef41Sopenharmony_ci# the respective C++ standard version. 151cb0ef41Sopenharmony_ci# 161cb0ef41Sopenharmony_ci# The second argument, if specified, indicates whether you insist on an 171cb0ef41Sopenharmony_ci# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. 181cb0ef41Sopenharmony_ci# -std=c++11). If neither is specified, you get whatever works, with 191cb0ef41Sopenharmony_ci# preference for no added switch, and then for an extended mode. 201cb0ef41Sopenharmony_ci# 211cb0ef41Sopenharmony_ci# The third argument, if specified 'mandatory' or if left unspecified, 221cb0ef41Sopenharmony_ci# indicates that baseline support for the specified C++ standard is 231cb0ef41Sopenharmony_ci# required and that the macro should error out if no mode with that 241cb0ef41Sopenharmony_ci# support is found. If specified 'optional', then configuration proceeds 251cb0ef41Sopenharmony_ci# regardless, after defining HAVE_CXX${VERSION} if and only if a 261cb0ef41Sopenharmony_ci# supporting mode is found. 271cb0ef41Sopenharmony_ci# 281cb0ef41Sopenharmony_ci# LICENSE 291cb0ef41Sopenharmony_ci# 301cb0ef41Sopenharmony_ci# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> 311cb0ef41Sopenharmony_ci# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> 321cb0ef41Sopenharmony_ci# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> 331cb0ef41Sopenharmony_ci# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> 341cb0ef41Sopenharmony_ci# Copyright (c) 2015 Paul Norman <penorman@mac.com> 351cb0ef41Sopenharmony_ci# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> 361cb0ef41Sopenharmony_ci# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> 371cb0ef41Sopenharmony_ci# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com> 381cb0ef41Sopenharmony_ci# Copyright (c) 2020 Jason Merrill <jason@redhat.com> 391cb0ef41Sopenharmony_ci# Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de> 401cb0ef41Sopenharmony_ci# 411cb0ef41Sopenharmony_ci# Copying and distribution of this file, with or without modification, are 421cb0ef41Sopenharmony_ci# permitted in any medium without royalty provided the copyright notice 431cb0ef41Sopenharmony_ci# and this notice are preserved. This file is offered as-is, without any 441cb0ef41Sopenharmony_ci# warranty. 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci#serial 18 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_cidnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro 491cb0ef41Sopenharmony_cidnl (serial version number 13). 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ciAC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl 521cb0ef41Sopenharmony_ci m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], 531cb0ef41Sopenharmony_ci [$1], [14], [ax_cxx_compile_alternatives="14 1y"], 541cb0ef41Sopenharmony_ci [$1], [17], [ax_cxx_compile_alternatives="17 1z"], 551cb0ef41Sopenharmony_ci [$1], [20], [ax_cxx_compile_alternatives="20"], 561cb0ef41Sopenharmony_ci [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl 571cb0ef41Sopenharmony_ci m4_if([$2], [], [], 581cb0ef41Sopenharmony_ci [$2], [ext], [], 591cb0ef41Sopenharmony_ci [$2], [noext], [], 601cb0ef41Sopenharmony_ci [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl 611cb0ef41Sopenharmony_ci m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], 621cb0ef41Sopenharmony_ci [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], 631cb0ef41Sopenharmony_ci [$3], [optional], [ax_cxx_compile_cxx$1_required=false], 641cb0ef41Sopenharmony_ci [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) 651cb0ef41Sopenharmony_ci AC_LANG_PUSH([C++])dnl 661cb0ef41Sopenharmony_ci ac_success=no 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci m4_if([$2], [], [dnl 691cb0ef41Sopenharmony_ci AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, 701cb0ef41Sopenharmony_ci ax_cv_cxx_compile_cxx$1, 711cb0ef41Sopenharmony_ci [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 721cb0ef41Sopenharmony_ci [ax_cv_cxx_compile_cxx$1=yes], 731cb0ef41Sopenharmony_ci [ax_cv_cxx_compile_cxx$1=no])]) 741cb0ef41Sopenharmony_ci if test x$ax_cv_cxx_compile_cxx$1 = xyes; then 751cb0ef41Sopenharmony_ci ac_success=yes 761cb0ef41Sopenharmony_ci fi]) 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci m4_if([$2], [noext], [], [dnl 791cb0ef41Sopenharmony_ci if test x$ac_success = xno; then 801cb0ef41Sopenharmony_ci for alternative in ${ax_cxx_compile_alternatives}; do 811cb0ef41Sopenharmony_ci switch="-std=gnu++${alternative}" 821cb0ef41Sopenharmony_ci cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 831cb0ef41Sopenharmony_ci AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 841cb0ef41Sopenharmony_ci $cachevar, 851cb0ef41Sopenharmony_ci [ac_save_CXX="$CXX" 861cb0ef41Sopenharmony_ci CXX="$CXX $switch" 871cb0ef41Sopenharmony_ci AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 881cb0ef41Sopenharmony_ci [eval $cachevar=yes], 891cb0ef41Sopenharmony_ci [eval $cachevar=no]) 901cb0ef41Sopenharmony_ci CXX="$ac_save_CXX"]) 911cb0ef41Sopenharmony_ci if eval test x\$$cachevar = xyes; then 921cb0ef41Sopenharmony_ci CXX="$CXX $switch" 931cb0ef41Sopenharmony_ci if test -n "$CXXCPP" ; then 941cb0ef41Sopenharmony_ci CXXCPP="$CXXCPP $switch" 951cb0ef41Sopenharmony_ci fi 961cb0ef41Sopenharmony_ci ac_success=yes 971cb0ef41Sopenharmony_ci break 981cb0ef41Sopenharmony_ci fi 991cb0ef41Sopenharmony_ci done 1001cb0ef41Sopenharmony_ci fi]) 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci m4_if([$2], [ext], [], [dnl 1031cb0ef41Sopenharmony_ci if test x$ac_success = xno; then 1041cb0ef41Sopenharmony_ci dnl HP's aCC needs +std=c++11 according to: 1051cb0ef41Sopenharmony_ci dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf 1061cb0ef41Sopenharmony_ci dnl Cray's crayCC needs "-h std=c++11" 1071cb0ef41Sopenharmony_ci dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) 1081cb0ef41Sopenharmony_ci for alternative in ${ax_cxx_compile_alternatives}; do 1091cb0ef41Sopenharmony_ci for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do 1101cb0ef41Sopenharmony_ci if test x"$switch" = xMSVC; then 1111cb0ef41Sopenharmony_ci dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide 1121cb0ef41Sopenharmony_ci dnl with -std=c++17. We suffix the cache variable name with _MSVC to 1131cb0ef41Sopenharmony_ci dnl avoid this. 1141cb0ef41Sopenharmony_ci switch=-std:c++${alternative} 1151cb0ef41Sopenharmony_ci cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) 1161cb0ef41Sopenharmony_ci else 1171cb0ef41Sopenharmony_ci cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) 1181cb0ef41Sopenharmony_ci fi 1191cb0ef41Sopenharmony_ci AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, 1201cb0ef41Sopenharmony_ci $cachevar, 1211cb0ef41Sopenharmony_ci [ac_save_CXX="$CXX" 1221cb0ef41Sopenharmony_ci CXX="$CXX $switch" 1231cb0ef41Sopenharmony_ci AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], 1241cb0ef41Sopenharmony_ci [eval $cachevar=yes], 1251cb0ef41Sopenharmony_ci [eval $cachevar=no]) 1261cb0ef41Sopenharmony_ci CXX="$ac_save_CXX"]) 1271cb0ef41Sopenharmony_ci if eval test x\$$cachevar = xyes; then 1281cb0ef41Sopenharmony_ci CXX="$CXX $switch" 1291cb0ef41Sopenharmony_ci if test -n "$CXXCPP" ; then 1301cb0ef41Sopenharmony_ci CXXCPP="$CXXCPP $switch" 1311cb0ef41Sopenharmony_ci fi 1321cb0ef41Sopenharmony_ci ac_success=yes 1331cb0ef41Sopenharmony_ci break 1341cb0ef41Sopenharmony_ci fi 1351cb0ef41Sopenharmony_ci done 1361cb0ef41Sopenharmony_ci if test x$ac_success = xyes; then 1371cb0ef41Sopenharmony_ci break 1381cb0ef41Sopenharmony_ci fi 1391cb0ef41Sopenharmony_ci done 1401cb0ef41Sopenharmony_ci fi]) 1411cb0ef41Sopenharmony_ci AC_LANG_POP([C++]) 1421cb0ef41Sopenharmony_ci if test x$ax_cxx_compile_cxx$1_required = xtrue; then 1431cb0ef41Sopenharmony_ci if test x$ac_success = xno; then 1441cb0ef41Sopenharmony_ci AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) 1451cb0ef41Sopenharmony_ci fi 1461cb0ef41Sopenharmony_ci fi 1471cb0ef41Sopenharmony_ci if test x$ac_success = xno; then 1481cb0ef41Sopenharmony_ci HAVE_CXX$1=0 1491cb0ef41Sopenharmony_ci AC_MSG_NOTICE([No compiler with C++$1 support was found]) 1501cb0ef41Sopenharmony_ci else 1511cb0ef41Sopenharmony_ci HAVE_CXX$1=1 1521cb0ef41Sopenharmony_ci AC_DEFINE(HAVE_CXX$1,1, 1531cb0ef41Sopenharmony_ci [define if the compiler supports basic C++$1 syntax]) 1541cb0ef41Sopenharmony_ci fi 1551cb0ef41Sopenharmony_ci AC_SUBST(HAVE_CXX$1) 1561cb0ef41Sopenharmony_ci]) 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_cidnl Test body for checking C++11 support 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], 1621cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1631cb0ef41Sopenharmony_ci) 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_cidnl Test body for checking C++14 support 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], 1681cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1691cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 1701cb0ef41Sopenharmony_ci) 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_cidnl Test body for checking C++17 support 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], 1751cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1761cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 1771cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 1781cb0ef41Sopenharmony_ci) 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_cidnl Test body for checking C++20 support 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], 1831cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 1841cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 1851cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 1861cb0ef41Sopenharmony_ci _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 1871cb0ef41Sopenharmony_ci) 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_cidnl Tests for new features in C++11 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci// If the compiler admits that it is not ready for C++11, why torture it? 1951cb0ef41Sopenharmony_ci// Hopefully, this will speed up the test. 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci#ifndef __cplusplus 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci#error "This is not a C++ compiler" 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci// MSVC always sets __cplusplus to 199711L in older versions; newer versions 2021cb0ef41Sopenharmony_ci// only set it correctly if /Zc:__cplusplus is specified as well as a 2031cb0ef41Sopenharmony_ci// /std:c++NN switch: 2041cb0ef41Sopenharmony_ci// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ 2051cb0ef41Sopenharmony_ci#elif __cplusplus < 201103L && !defined _MSC_VER 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci#error "This is not a C++11 compiler" 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci#else 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_cinamespace cxx11 2121cb0ef41Sopenharmony_ci{ 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci namespace test_static_assert 2151cb0ef41Sopenharmony_ci { 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci template <typename T> 2181cb0ef41Sopenharmony_ci struct check 2191cb0ef41Sopenharmony_ci { 2201cb0ef41Sopenharmony_ci static_assert(sizeof(int) <= sizeof(T), "not big enough"); 2211cb0ef41Sopenharmony_ci }; 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci } 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci namespace test_final_override 2261cb0ef41Sopenharmony_ci { 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci struct Base 2291cb0ef41Sopenharmony_ci { 2301cb0ef41Sopenharmony_ci virtual ~Base() {} 2311cb0ef41Sopenharmony_ci virtual void f() {} 2321cb0ef41Sopenharmony_ci }; 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci struct Derived : public Base 2351cb0ef41Sopenharmony_ci { 2361cb0ef41Sopenharmony_ci virtual ~Derived() override {} 2371cb0ef41Sopenharmony_ci virtual void f() override {} 2381cb0ef41Sopenharmony_ci }; 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci } 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci namespace test_double_right_angle_brackets 2431cb0ef41Sopenharmony_ci { 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci template < typename T > 2461cb0ef41Sopenharmony_ci struct check {}; 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci typedef check<void> single_type; 2491cb0ef41Sopenharmony_ci typedef check<check<void>> double_type; 2501cb0ef41Sopenharmony_ci typedef check<check<check<void>>> triple_type; 2511cb0ef41Sopenharmony_ci typedef check<check<check<check<void>>>> quadruple_type; 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci namespace test_decltype 2561cb0ef41Sopenharmony_ci { 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci int 2591cb0ef41Sopenharmony_ci f() 2601cb0ef41Sopenharmony_ci { 2611cb0ef41Sopenharmony_ci int a = 1; 2621cb0ef41Sopenharmony_ci decltype(a) b = 2; 2631cb0ef41Sopenharmony_ci return a + b; 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci namespace test_type_deduction 2691cb0ef41Sopenharmony_ci { 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci template < typename T1, typename T2 > 2721cb0ef41Sopenharmony_ci struct is_same 2731cb0ef41Sopenharmony_ci { 2741cb0ef41Sopenharmony_ci static const bool value = false; 2751cb0ef41Sopenharmony_ci }; 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci template < typename T > 2781cb0ef41Sopenharmony_ci struct is_same<T, T> 2791cb0ef41Sopenharmony_ci { 2801cb0ef41Sopenharmony_ci static const bool value = true; 2811cb0ef41Sopenharmony_ci }; 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci template < typename T1, typename T2 > 2841cb0ef41Sopenharmony_ci auto 2851cb0ef41Sopenharmony_ci add(T1 a1, T2 a2) -> decltype(a1 + a2) 2861cb0ef41Sopenharmony_ci { 2871cb0ef41Sopenharmony_ci return a1 + a2; 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci int 2911cb0ef41Sopenharmony_ci test(const int c, volatile int v) 2921cb0ef41Sopenharmony_ci { 2931cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(0)>::value == true, ""); 2941cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(c)>::value == false, ""); 2951cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(v)>::value == false, ""); 2961cb0ef41Sopenharmony_ci auto ac = c; 2971cb0ef41Sopenharmony_ci auto av = v; 2981cb0ef41Sopenharmony_ci auto sumi = ac + av + 'x'; 2991cb0ef41Sopenharmony_ci auto sumf = ac + av + 1.0; 3001cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(ac)>::value == true, ""); 3011cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(av)>::value == true, ""); 3021cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(sumi)>::value == true, ""); 3031cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(sumf)>::value == false, ""); 3041cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); 3051cb0ef41Sopenharmony_ci return (sumf > 0.0) ? sumi : add(c, v); 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci } 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci namespace test_noexcept 3111cb0ef41Sopenharmony_ci { 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci int f() { return 0; } 3141cb0ef41Sopenharmony_ci int g() noexcept { return 0; } 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci static_assert(noexcept(f()) == false, ""); 3171cb0ef41Sopenharmony_ci static_assert(noexcept(g()) == true, ""); 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci namespace test_constexpr 3221cb0ef41Sopenharmony_ci { 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci template < typename CharT > 3251cb0ef41Sopenharmony_ci unsigned long constexpr 3261cb0ef41Sopenharmony_ci strlen_c_r(const CharT *const s, const unsigned long acc) noexcept 3271cb0ef41Sopenharmony_ci { 3281cb0ef41Sopenharmony_ci return *s ? strlen_c_r(s + 1, acc + 1) : acc; 3291cb0ef41Sopenharmony_ci } 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci template < typename CharT > 3321cb0ef41Sopenharmony_ci unsigned long constexpr 3331cb0ef41Sopenharmony_ci strlen_c(const CharT *const s) noexcept 3341cb0ef41Sopenharmony_ci { 3351cb0ef41Sopenharmony_ci return strlen_c_r(s, 0UL); 3361cb0ef41Sopenharmony_ci } 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci static_assert(strlen_c("") == 0UL, ""); 3391cb0ef41Sopenharmony_ci static_assert(strlen_c("1") == 1UL, ""); 3401cb0ef41Sopenharmony_ci static_assert(strlen_c("example") == 7UL, ""); 3411cb0ef41Sopenharmony_ci static_assert(strlen_c("another\0example") == 7UL, ""); 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci } 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci namespace test_rvalue_references 3461cb0ef41Sopenharmony_ci { 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci template < int N > 3491cb0ef41Sopenharmony_ci struct answer 3501cb0ef41Sopenharmony_ci { 3511cb0ef41Sopenharmony_ci static constexpr int value = N; 3521cb0ef41Sopenharmony_ci }; 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci answer<1> f(int&) { return answer<1>(); } 3551cb0ef41Sopenharmony_ci answer<2> f(const int&) { return answer<2>(); } 3561cb0ef41Sopenharmony_ci answer<3> f(int&&) { return answer<3>(); } 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci void 3591cb0ef41Sopenharmony_ci test() 3601cb0ef41Sopenharmony_ci { 3611cb0ef41Sopenharmony_ci int i = 0; 3621cb0ef41Sopenharmony_ci const int c = 0; 3631cb0ef41Sopenharmony_ci static_assert(decltype(f(i))::value == 1, ""); 3641cb0ef41Sopenharmony_ci static_assert(decltype(f(c))::value == 2, ""); 3651cb0ef41Sopenharmony_ci static_assert(decltype(f(0))::value == 3, ""); 3661cb0ef41Sopenharmony_ci } 3671cb0ef41Sopenharmony_ci 3681cb0ef41Sopenharmony_ci } 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci namespace test_uniform_initialization 3711cb0ef41Sopenharmony_ci { 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci struct test 3741cb0ef41Sopenharmony_ci { 3751cb0ef41Sopenharmony_ci static const int zero {}; 3761cb0ef41Sopenharmony_ci static const int one {1}; 3771cb0ef41Sopenharmony_ci }; 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci static_assert(test::zero == 0, ""); 3801cb0ef41Sopenharmony_ci static_assert(test::one == 1, ""); 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci namespace test_lambdas 3851cb0ef41Sopenharmony_ci { 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ci void 3881cb0ef41Sopenharmony_ci test1() 3891cb0ef41Sopenharmony_ci { 3901cb0ef41Sopenharmony_ci auto lambda1 = [](){}; 3911cb0ef41Sopenharmony_ci auto lambda2 = lambda1; 3921cb0ef41Sopenharmony_ci lambda1(); 3931cb0ef41Sopenharmony_ci lambda2(); 3941cb0ef41Sopenharmony_ci } 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci int 3971cb0ef41Sopenharmony_ci test2() 3981cb0ef41Sopenharmony_ci { 3991cb0ef41Sopenharmony_ci auto a = [](int i, int j){ return i + j; }(1, 2); 4001cb0ef41Sopenharmony_ci auto b = []() -> int { return '0'; }(); 4011cb0ef41Sopenharmony_ci auto c = [=](){ return a + b; }(); 4021cb0ef41Sopenharmony_ci auto d = [&](){ return c; }(); 4031cb0ef41Sopenharmony_ci auto e = [a, &b](int x) mutable { 4041cb0ef41Sopenharmony_ci const auto identity = [](int y){ return y; }; 4051cb0ef41Sopenharmony_ci for (auto i = 0; i < a; ++i) 4061cb0ef41Sopenharmony_ci a += b--; 4071cb0ef41Sopenharmony_ci return x + identity(a + b); 4081cb0ef41Sopenharmony_ci }(0); 4091cb0ef41Sopenharmony_ci return a + b + c + d + e; 4101cb0ef41Sopenharmony_ci } 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci int 4131cb0ef41Sopenharmony_ci test3() 4141cb0ef41Sopenharmony_ci { 4151cb0ef41Sopenharmony_ci const auto nullary = [](){ return 0; }; 4161cb0ef41Sopenharmony_ci const auto unary = [](int x){ return x; }; 4171cb0ef41Sopenharmony_ci using nullary_t = decltype(nullary); 4181cb0ef41Sopenharmony_ci using unary_t = decltype(unary); 4191cb0ef41Sopenharmony_ci const auto higher1st = [](nullary_t f){ return f(); }; 4201cb0ef41Sopenharmony_ci const auto higher2nd = [unary](nullary_t f1){ 4211cb0ef41Sopenharmony_ci return [unary, f1](unary_t f2){ return f2(unary(f1())); }; 4221cb0ef41Sopenharmony_ci }; 4231cb0ef41Sopenharmony_ci return higher1st(nullary) + higher2nd(nullary)(unary); 4241cb0ef41Sopenharmony_ci } 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci } 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci namespace test_variadic_templates 4291cb0ef41Sopenharmony_ci { 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci template <int...> 4321cb0ef41Sopenharmony_ci struct sum; 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci template <int N0, int... N1toN> 4351cb0ef41Sopenharmony_ci struct sum<N0, N1toN...> 4361cb0ef41Sopenharmony_ci { 4371cb0ef41Sopenharmony_ci static constexpr auto value = N0 + sum<N1toN...>::value; 4381cb0ef41Sopenharmony_ci }; 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci template <> 4411cb0ef41Sopenharmony_ci struct sum<> 4421cb0ef41Sopenharmony_ci { 4431cb0ef41Sopenharmony_ci static constexpr auto value = 0; 4441cb0ef41Sopenharmony_ci }; 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci static_assert(sum<>::value == 0, ""); 4471cb0ef41Sopenharmony_ci static_assert(sum<1>::value == 1, ""); 4481cb0ef41Sopenharmony_ci static_assert(sum<23>::value == 23, ""); 4491cb0ef41Sopenharmony_ci static_assert(sum<1, 2>::value == 3, ""); 4501cb0ef41Sopenharmony_ci static_assert(sum<5, 5, 11>::value == 21, ""); 4511cb0ef41Sopenharmony_ci static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); 4521cb0ef41Sopenharmony_ci 4531cb0ef41Sopenharmony_ci } 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae 4561cb0ef41Sopenharmony_ci // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function 4571cb0ef41Sopenharmony_ci // because of this. 4581cb0ef41Sopenharmony_ci namespace test_template_alias_sfinae 4591cb0ef41Sopenharmony_ci { 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci struct foo {}; 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci template<typename T> 4641cb0ef41Sopenharmony_ci using member = typename T::member_type; 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci template<typename T> 4671cb0ef41Sopenharmony_ci void func(...) {} 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci template<typename T> 4701cb0ef41Sopenharmony_ci void func(member<T>*) {} 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci void test(); 4731cb0ef41Sopenharmony_ci 4741cb0ef41Sopenharmony_ci void test() { func<foo>(0); } 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci } 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci} // namespace cxx11 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci#endif // __cplusplus >= 201103L 4811cb0ef41Sopenharmony_ci 4821cb0ef41Sopenharmony_ci]]) 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_cidnl Tests for new features in C++14 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci// If the compiler admits that it is not ready for C++14, why torture it? 4901cb0ef41Sopenharmony_ci// Hopefully, this will speed up the test. 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci#ifndef __cplusplus 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci#error "This is not a C++ compiler" 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci#elif __cplusplus < 201402L && !defined _MSC_VER 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ci#error "This is not a C++14 compiler" 4991cb0ef41Sopenharmony_ci 5001cb0ef41Sopenharmony_ci#else 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_cinamespace cxx14 5031cb0ef41Sopenharmony_ci{ 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_ci namespace test_polymorphic_lambdas 5061cb0ef41Sopenharmony_ci { 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_ci int 5091cb0ef41Sopenharmony_ci test() 5101cb0ef41Sopenharmony_ci { 5111cb0ef41Sopenharmony_ci const auto lambda = [](auto&&... args){ 5121cb0ef41Sopenharmony_ci const auto istiny = [](auto x){ 5131cb0ef41Sopenharmony_ci return (sizeof(x) == 1UL) ? 1 : 0; 5141cb0ef41Sopenharmony_ci }; 5151cb0ef41Sopenharmony_ci const int aretiny[] = { istiny(args)... }; 5161cb0ef41Sopenharmony_ci return aretiny[0]; 5171cb0ef41Sopenharmony_ci }; 5181cb0ef41Sopenharmony_ci return lambda(1, 1L, 1.0f, '1'); 5191cb0ef41Sopenharmony_ci } 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci } 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_ci namespace test_binary_literals 5241cb0ef41Sopenharmony_ci { 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_ci constexpr auto ivii = 0b0000000000101010; 5271cb0ef41Sopenharmony_ci static_assert(ivii == 42, "wrong value"); 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_ci } 5301cb0ef41Sopenharmony_ci 5311cb0ef41Sopenharmony_ci namespace test_generalized_constexpr 5321cb0ef41Sopenharmony_ci { 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci template < typename CharT > 5351cb0ef41Sopenharmony_ci constexpr unsigned long 5361cb0ef41Sopenharmony_ci strlen_c(const CharT *const s) noexcept 5371cb0ef41Sopenharmony_ci { 5381cb0ef41Sopenharmony_ci auto length = 0UL; 5391cb0ef41Sopenharmony_ci for (auto p = s; *p; ++p) 5401cb0ef41Sopenharmony_ci ++length; 5411cb0ef41Sopenharmony_ci return length; 5421cb0ef41Sopenharmony_ci } 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ci static_assert(strlen_c("") == 0UL, ""); 5451cb0ef41Sopenharmony_ci static_assert(strlen_c("x") == 1UL, ""); 5461cb0ef41Sopenharmony_ci static_assert(strlen_c("test") == 4UL, ""); 5471cb0ef41Sopenharmony_ci static_assert(strlen_c("another\0test") == 7UL, ""); 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci } 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_ci namespace test_lambda_init_capture 5521cb0ef41Sopenharmony_ci { 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci int 5551cb0ef41Sopenharmony_ci test() 5561cb0ef41Sopenharmony_ci { 5571cb0ef41Sopenharmony_ci auto x = 0; 5581cb0ef41Sopenharmony_ci const auto lambda1 = [a = x](int b){ return a + b; }; 5591cb0ef41Sopenharmony_ci const auto lambda2 = [a = lambda1(x)](){ return a; }; 5601cb0ef41Sopenharmony_ci return lambda2(); 5611cb0ef41Sopenharmony_ci } 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci } 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci namespace test_digit_separators 5661cb0ef41Sopenharmony_ci { 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ci constexpr auto ten_million = 100'000'000; 5691cb0ef41Sopenharmony_ci static_assert(ten_million == 100000000, ""); 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ci namespace test_return_type_deduction 5741cb0ef41Sopenharmony_ci { 5751cb0ef41Sopenharmony_ci 5761cb0ef41Sopenharmony_ci auto f(int& x) { return x; } 5771cb0ef41Sopenharmony_ci decltype(auto) g(int& x) { return x; } 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ci template < typename T1, typename T2 > 5801cb0ef41Sopenharmony_ci struct is_same 5811cb0ef41Sopenharmony_ci { 5821cb0ef41Sopenharmony_ci static constexpr auto value = false; 5831cb0ef41Sopenharmony_ci }; 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_ci template < typename T > 5861cb0ef41Sopenharmony_ci struct is_same<T, T> 5871cb0ef41Sopenharmony_ci { 5881cb0ef41Sopenharmony_ci static constexpr auto value = true; 5891cb0ef41Sopenharmony_ci }; 5901cb0ef41Sopenharmony_ci 5911cb0ef41Sopenharmony_ci int 5921cb0ef41Sopenharmony_ci test() 5931cb0ef41Sopenharmony_ci { 5941cb0ef41Sopenharmony_ci auto x = 0; 5951cb0ef41Sopenharmony_ci static_assert(is_same<int, decltype(f(x))>::value, ""); 5961cb0ef41Sopenharmony_ci static_assert(is_same<int&, decltype(g(x))>::value, ""); 5971cb0ef41Sopenharmony_ci return x; 5981cb0ef41Sopenharmony_ci } 5991cb0ef41Sopenharmony_ci 6001cb0ef41Sopenharmony_ci } 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_ci} // namespace cxx14 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci#endif // __cplusplus >= 201402L 6051cb0ef41Sopenharmony_ci 6061cb0ef41Sopenharmony_ci]]) 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_ci 6091cb0ef41Sopenharmony_cidnl Tests for new features in C++17 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ 6121cb0ef41Sopenharmony_ci 6131cb0ef41Sopenharmony_ci// If the compiler admits that it is not ready for C++17, why torture it? 6141cb0ef41Sopenharmony_ci// Hopefully, this will speed up the test. 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci#ifndef __cplusplus 6171cb0ef41Sopenharmony_ci 6181cb0ef41Sopenharmony_ci#error "This is not a C++ compiler" 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_ci#elif __cplusplus < 201703L && !defined _MSC_VER 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ci#error "This is not a C++17 compiler" 6231cb0ef41Sopenharmony_ci 6241cb0ef41Sopenharmony_ci#else 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci#include <initializer_list> 6271cb0ef41Sopenharmony_ci#include <utility> 6281cb0ef41Sopenharmony_ci#include <type_traits> 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_cinamespace cxx17 6311cb0ef41Sopenharmony_ci{ 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_ci namespace test_constexpr_lambdas 6341cb0ef41Sopenharmony_ci { 6351cb0ef41Sopenharmony_ci 6361cb0ef41Sopenharmony_ci constexpr int foo = [](){return 42;}(); 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci } 6391cb0ef41Sopenharmony_ci 6401cb0ef41Sopenharmony_ci namespace test::nested_namespace::definitions 6411cb0ef41Sopenharmony_ci { 6421cb0ef41Sopenharmony_ci 6431cb0ef41Sopenharmony_ci } 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci namespace test_fold_expression 6461cb0ef41Sopenharmony_ci { 6471cb0ef41Sopenharmony_ci 6481cb0ef41Sopenharmony_ci template<typename... Args> 6491cb0ef41Sopenharmony_ci int multiply(Args... args) 6501cb0ef41Sopenharmony_ci { 6511cb0ef41Sopenharmony_ci return (args * ... * 1); 6521cb0ef41Sopenharmony_ci } 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci template<typename... Args> 6551cb0ef41Sopenharmony_ci bool all(Args... args) 6561cb0ef41Sopenharmony_ci { 6571cb0ef41Sopenharmony_ci return (args && ...); 6581cb0ef41Sopenharmony_ci } 6591cb0ef41Sopenharmony_ci 6601cb0ef41Sopenharmony_ci } 6611cb0ef41Sopenharmony_ci 6621cb0ef41Sopenharmony_ci namespace test_extended_static_assert 6631cb0ef41Sopenharmony_ci { 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci static_assert (true); 6661cb0ef41Sopenharmony_ci 6671cb0ef41Sopenharmony_ci } 6681cb0ef41Sopenharmony_ci 6691cb0ef41Sopenharmony_ci namespace test_auto_brace_init_list 6701cb0ef41Sopenharmony_ci { 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci auto foo = {5}; 6731cb0ef41Sopenharmony_ci auto bar {5}; 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value); 6761cb0ef41Sopenharmony_ci static_assert(std::is_same<int, decltype(bar)>::value); 6771cb0ef41Sopenharmony_ci } 6781cb0ef41Sopenharmony_ci 6791cb0ef41Sopenharmony_ci namespace test_typename_in_template_template_parameter 6801cb0ef41Sopenharmony_ci { 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci template<template<typename> typename X> struct D; 6831cb0ef41Sopenharmony_ci 6841cb0ef41Sopenharmony_ci } 6851cb0ef41Sopenharmony_ci 6861cb0ef41Sopenharmony_ci namespace test_fallthrough_nodiscard_maybe_unused_attributes 6871cb0ef41Sopenharmony_ci { 6881cb0ef41Sopenharmony_ci 6891cb0ef41Sopenharmony_ci int f1() 6901cb0ef41Sopenharmony_ci { 6911cb0ef41Sopenharmony_ci return 42; 6921cb0ef41Sopenharmony_ci } 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ci [[nodiscard]] int f2() 6951cb0ef41Sopenharmony_ci { 6961cb0ef41Sopenharmony_ci [[maybe_unused]] auto unused = f1(); 6971cb0ef41Sopenharmony_ci 6981cb0ef41Sopenharmony_ci switch (f1()) 6991cb0ef41Sopenharmony_ci { 7001cb0ef41Sopenharmony_ci case 17: 7011cb0ef41Sopenharmony_ci f1(); 7021cb0ef41Sopenharmony_ci [[fallthrough]]; 7031cb0ef41Sopenharmony_ci case 42: 7041cb0ef41Sopenharmony_ci f1(); 7051cb0ef41Sopenharmony_ci } 7061cb0ef41Sopenharmony_ci return f1(); 7071cb0ef41Sopenharmony_ci } 7081cb0ef41Sopenharmony_ci 7091cb0ef41Sopenharmony_ci } 7101cb0ef41Sopenharmony_ci 7111cb0ef41Sopenharmony_ci namespace test_extended_aggregate_initialization 7121cb0ef41Sopenharmony_ci { 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_ci struct base1 7151cb0ef41Sopenharmony_ci { 7161cb0ef41Sopenharmony_ci int b1, b2 = 42; 7171cb0ef41Sopenharmony_ci }; 7181cb0ef41Sopenharmony_ci 7191cb0ef41Sopenharmony_ci struct base2 7201cb0ef41Sopenharmony_ci { 7211cb0ef41Sopenharmony_ci base2() { 7221cb0ef41Sopenharmony_ci b3 = 42; 7231cb0ef41Sopenharmony_ci } 7241cb0ef41Sopenharmony_ci int b3; 7251cb0ef41Sopenharmony_ci }; 7261cb0ef41Sopenharmony_ci 7271cb0ef41Sopenharmony_ci struct derived : base1, base2 7281cb0ef41Sopenharmony_ci { 7291cb0ef41Sopenharmony_ci int d; 7301cb0ef41Sopenharmony_ci }; 7311cb0ef41Sopenharmony_ci 7321cb0ef41Sopenharmony_ci derived d1 {{1, 2}, {}, 4}; // full initialization 7331cb0ef41Sopenharmony_ci derived d2 {{}, {}, 4}; // value-initialized bases 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci } 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_ci namespace test_general_range_based_for_loop 7381cb0ef41Sopenharmony_ci { 7391cb0ef41Sopenharmony_ci 7401cb0ef41Sopenharmony_ci struct iter 7411cb0ef41Sopenharmony_ci { 7421cb0ef41Sopenharmony_ci int i; 7431cb0ef41Sopenharmony_ci 7441cb0ef41Sopenharmony_ci int& operator* () 7451cb0ef41Sopenharmony_ci { 7461cb0ef41Sopenharmony_ci return i; 7471cb0ef41Sopenharmony_ci } 7481cb0ef41Sopenharmony_ci 7491cb0ef41Sopenharmony_ci const int& operator* () const 7501cb0ef41Sopenharmony_ci { 7511cb0ef41Sopenharmony_ci return i; 7521cb0ef41Sopenharmony_ci } 7531cb0ef41Sopenharmony_ci 7541cb0ef41Sopenharmony_ci iter& operator++() 7551cb0ef41Sopenharmony_ci { 7561cb0ef41Sopenharmony_ci ++i; 7571cb0ef41Sopenharmony_ci return *this; 7581cb0ef41Sopenharmony_ci } 7591cb0ef41Sopenharmony_ci }; 7601cb0ef41Sopenharmony_ci 7611cb0ef41Sopenharmony_ci struct sentinel 7621cb0ef41Sopenharmony_ci { 7631cb0ef41Sopenharmony_ci int i; 7641cb0ef41Sopenharmony_ci }; 7651cb0ef41Sopenharmony_ci 7661cb0ef41Sopenharmony_ci bool operator== (const iter& i, const sentinel& s) 7671cb0ef41Sopenharmony_ci { 7681cb0ef41Sopenharmony_ci return i.i == s.i; 7691cb0ef41Sopenharmony_ci } 7701cb0ef41Sopenharmony_ci 7711cb0ef41Sopenharmony_ci bool operator!= (const iter& i, const sentinel& s) 7721cb0ef41Sopenharmony_ci { 7731cb0ef41Sopenharmony_ci return !(i == s); 7741cb0ef41Sopenharmony_ci } 7751cb0ef41Sopenharmony_ci 7761cb0ef41Sopenharmony_ci struct range 7771cb0ef41Sopenharmony_ci { 7781cb0ef41Sopenharmony_ci iter begin() const 7791cb0ef41Sopenharmony_ci { 7801cb0ef41Sopenharmony_ci return {0}; 7811cb0ef41Sopenharmony_ci } 7821cb0ef41Sopenharmony_ci 7831cb0ef41Sopenharmony_ci sentinel end() const 7841cb0ef41Sopenharmony_ci { 7851cb0ef41Sopenharmony_ci return {5}; 7861cb0ef41Sopenharmony_ci } 7871cb0ef41Sopenharmony_ci }; 7881cb0ef41Sopenharmony_ci 7891cb0ef41Sopenharmony_ci void f() 7901cb0ef41Sopenharmony_ci { 7911cb0ef41Sopenharmony_ci range r {}; 7921cb0ef41Sopenharmony_ci 7931cb0ef41Sopenharmony_ci for (auto i : r) 7941cb0ef41Sopenharmony_ci { 7951cb0ef41Sopenharmony_ci [[maybe_unused]] auto v = i; 7961cb0ef41Sopenharmony_ci } 7971cb0ef41Sopenharmony_ci } 7981cb0ef41Sopenharmony_ci 7991cb0ef41Sopenharmony_ci } 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ci namespace test_lambda_capture_asterisk_this_by_value 8021cb0ef41Sopenharmony_ci { 8031cb0ef41Sopenharmony_ci 8041cb0ef41Sopenharmony_ci struct t 8051cb0ef41Sopenharmony_ci { 8061cb0ef41Sopenharmony_ci int i; 8071cb0ef41Sopenharmony_ci int foo() 8081cb0ef41Sopenharmony_ci { 8091cb0ef41Sopenharmony_ci return [*this]() 8101cb0ef41Sopenharmony_ci { 8111cb0ef41Sopenharmony_ci return i; 8121cb0ef41Sopenharmony_ci }(); 8131cb0ef41Sopenharmony_ci } 8141cb0ef41Sopenharmony_ci }; 8151cb0ef41Sopenharmony_ci 8161cb0ef41Sopenharmony_ci } 8171cb0ef41Sopenharmony_ci 8181cb0ef41Sopenharmony_ci namespace test_enum_class_construction 8191cb0ef41Sopenharmony_ci { 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci enum class byte : unsigned char 8221cb0ef41Sopenharmony_ci {}; 8231cb0ef41Sopenharmony_ci 8241cb0ef41Sopenharmony_ci byte foo {42}; 8251cb0ef41Sopenharmony_ci 8261cb0ef41Sopenharmony_ci } 8271cb0ef41Sopenharmony_ci 8281cb0ef41Sopenharmony_ci namespace test_constexpr_if 8291cb0ef41Sopenharmony_ci { 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ci template <bool cond> 8321cb0ef41Sopenharmony_ci int f () 8331cb0ef41Sopenharmony_ci { 8341cb0ef41Sopenharmony_ci if constexpr(cond) 8351cb0ef41Sopenharmony_ci { 8361cb0ef41Sopenharmony_ci return 13; 8371cb0ef41Sopenharmony_ci } 8381cb0ef41Sopenharmony_ci else 8391cb0ef41Sopenharmony_ci { 8401cb0ef41Sopenharmony_ci return 42; 8411cb0ef41Sopenharmony_ci } 8421cb0ef41Sopenharmony_ci } 8431cb0ef41Sopenharmony_ci 8441cb0ef41Sopenharmony_ci } 8451cb0ef41Sopenharmony_ci 8461cb0ef41Sopenharmony_ci namespace test_selection_statement_with_initializer 8471cb0ef41Sopenharmony_ci { 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci int f() 8501cb0ef41Sopenharmony_ci { 8511cb0ef41Sopenharmony_ci return 13; 8521cb0ef41Sopenharmony_ci } 8531cb0ef41Sopenharmony_ci 8541cb0ef41Sopenharmony_ci int f2() 8551cb0ef41Sopenharmony_ci { 8561cb0ef41Sopenharmony_ci if (auto i = f(); i > 0) 8571cb0ef41Sopenharmony_ci { 8581cb0ef41Sopenharmony_ci return 3; 8591cb0ef41Sopenharmony_ci } 8601cb0ef41Sopenharmony_ci 8611cb0ef41Sopenharmony_ci switch (auto i = f(); i + 4) 8621cb0ef41Sopenharmony_ci { 8631cb0ef41Sopenharmony_ci case 17: 8641cb0ef41Sopenharmony_ci return 2; 8651cb0ef41Sopenharmony_ci 8661cb0ef41Sopenharmony_ci default: 8671cb0ef41Sopenharmony_ci return 1; 8681cb0ef41Sopenharmony_ci } 8691cb0ef41Sopenharmony_ci } 8701cb0ef41Sopenharmony_ci 8711cb0ef41Sopenharmony_ci } 8721cb0ef41Sopenharmony_ci 8731cb0ef41Sopenharmony_ci namespace test_template_argument_deduction_for_class_templates 8741cb0ef41Sopenharmony_ci { 8751cb0ef41Sopenharmony_ci 8761cb0ef41Sopenharmony_ci template <typename T1, typename T2> 8771cb0ef41Sopenharmony_ci struct pair 8781cb0ef41Sopenharmony_ci { 8791cb0ef41Sopenharmony_ci pair (T1 p1, T2 p2) 8801cb0ef41Sopenharmony_ci : m1 {p1}, 8811cb0ef41Sopenharmony_ci m2 {p2} 8821cb0ef41Sopenharmony_ci {} 8831cb0ef41Sopenharmony_ci 8841cb0ef41Sopenharmony_ci T1 m1; 8851cb0ef41Sopenharmony_ci T2 m2; 8861cb0ef41Sopenharmony_ci }; 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_ci void f() 8891cb0ef41Sopenharmony_ci { 8901cb0ef41Sopenharmony_ci [[maybe_unused]] auto p = pair{13, 42u}; 8911cb0ef41Sopenharmony_ci } 8921cb0ef41Sopenharmony_ci 8931cb0ef41Sopenharmony_ci } 8941cb0ef41Sopenharmony_ci 8951cb0ef41Sopenharmony_ci namespace test_non_type_auto_template_parameters 8961cb0ef41Sopenharmony_ci { 8971cb0ef41Sopenharmony_ci 8981cb0ef41Sopenharmony_ci template <auto n> 8991cb0ef41Sopenharmony_ci struct B 9001cb0ef41Sopenharmony_ci {}; 9011cb0ef41Sopenharmony_ci 9021cb0ef41Sopenharmony_ci B<5> b1; 9031cb0ef41Sopenharmony_ci B<'a'> b2; 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci } 9061cb0ef41Sopenharmony_ci 9071cb0ef41Sopenharmony_ci namespace test_structured_bindings 9081cb0ef41Sopenharmony_ci { 9091cb0ef41Sopenharmony_ci 9101cb0ef41Sopenharmony_ci int arr[2] = { 1, 2 }; 9111cb0ef41Sopenharmony_ci std::pair<int, int> pr = { 1, 2 }; 9121cb0ef41Sopenharmony_ci 9131cb0ef41Sopenharmony_ci auto f1() -> int(&)[2] 9141cb0ef41Sopenharmony_ci { 9151cb0ef41Sopenharmony_ci return arr; 9161cb0ef41Sopenharmony_ci } 9171cb0ef41Sopenharmony_ci 9181cb0ef41Sopenharmony_ci auto f2() -> std::pair<int, int>& 9191cb0ef41Sopenharmony_ci { 9201cb0ef41Sopenharmony_ci return pr; 9211cb0ef41Sopenharmony_ci } 9221cb0ef41Sopenharmony_ci 9231cb0ef41Sopenharmony_ci struct S 9241cb0ef41Sopenharmony_ci { 9251cb0ef41Sopenharmony_ci int x1 : 2; 9261cb0ef41Sopenharmony_ci volatile double y1; 9271cb0ef41Sopenharmony_ci }; 9281cb0ef41Sopenharmony_ci 9291cb0ef41Sopenharmony_ci S f3() 9301cb0ef41Sopenharmony_ci { 9311cb0ef41Sopenharmony_ci return {}; 9321cb0ef41Sopenharmony_ci } 9331cb0ef41Sopenharmony_ci 9341cb0ef41Sopenharmony_ci auto [ x1, y1 ] = f1(); 9351cb0ef41Sopenharmony_ci auto& [ xr1, yr1 ] = f1(); 9361cb0ef41Sopenharmony_ci auto [ x2, y2 ] = f2(); 9371cb0ef41Sopenharmony_ci auto& [ xr2, yr2 ] = f2(); 9381cb0ef41Sopenharmony_ci const auto [ x3, y3 ] = f3(); 9391cb0ef41Sopenharmony_ci 9401cb0ef41Sopenharmony_ci } 9411cb0ef41Sopenharmony_ci 9421cb0ef41Sopenharmony_ci namespace test_exception_spec_type_system 9431cb0ef41Sopenharmony_ci { 9441cb0ef41Sopenharmony_ci 9451cb0ef41Sopenharmony_ci struct Good {}; 9461cb0ef41Sopenharmony_ci struct Bad {}; 9471cb0ef41Sopenharmony_ci 9481cb0ef41Sopenharmony_ci void g1() noexcept; 9491cb0ef41Sopenharmony_ci void g2(); 9501cb0ef41Sopenharmony_ci 9511cb0ef41Sopenharmony_ci template<typename T> 9521cb0ef41Sopenharmony_ci Bad 9531cb0ef41Sopenharmony_ci f(T*, T*); 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci template<typename T1, typename T2> 9561cb0ef41Sopenharmony_ci Good 9571cb0ef41Sopenharmony_ci f(T1*, T2*); 9581cb0ef41Sopenharmony_ci 9591cb0ef41Sopenharmony_ci static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); 9601cb0ef41Sopenharmony_ci 9611cb0ef41Sopenharmony_ci } 9621cb0ef41Sopenharmony_ci 9631cb0ef41Sopenharmony_ci namespace test_inline_variables 9641cb0ef41Sopenharmony_ci { 9651cb0ef41Sopenharmony_ci 9661cb0ef41Sopenharmony_ci template<class T> void f(T) 9671cb0ef41Sopenharmony_ci {} 9681cb0ef41Sopenharmony_ci 9691cb0ef41Sopenharmony_ci template<class T> inline T g(T) 9701cb0ef41Sopenharmony_ci { 9711cb0ef41Sopenharmony_ci return T{}; 9721cb0ef41Sopenharmony_ci } 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci template<> inline void f<>(int) 9751cb0ef41Sopenharmony_ci {} 9761cb0ef41Sopenharmony_ci 9771cb0ef41Sopenharmony_ci template<> int g<>(int) 9781cb0ef41Sopenharmony_ci { 9791cb0ef41Sopenharmony_ci return 5; 9801cb0ef41Sopenharmony_ci } 9811cb0ef41Sopenharmony_ci 9821cb0ef41Sopenharmony_ci } 9831cb0ef41Sopenharmony_ci 9841cb0ef41Sopenharmony_ci} // namespace cxx17 9851cb0ef41Sopenharmony_ci 9861cb0ef41Sopenharmony_ci#endif // __cplusplus < 201703L && !defined _MSC_VER 9871cb0ef41Sopenharmony_ci 9881cb0ef41Sopenharmony_ci]]) 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci 9911cb0ef41Sopenharmony_cidnl Tests for new features in C++20 9921cb0ef41Sopenharmony_ci 9931cb0ef41Sopenharmony_cim4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ 9941cb0ef41Sopenharmony_ci 9951cb0ef41Sopenharmony_ci#ifndef __cplusplus 9961cb0ef41Sopenharmony_ci 9971cb0ef41Sopenharmony_ci#error "This is not a C++ compiler" 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ci#elif __cplusplus < 202002L && !defined _MSC_VER 10001cb0ef41Sopenharmony_ci 10011cb0ef41Sopenharmony_ci#error "This is not a C++20 compiler" 10021cb0ef41Sopenharmony_ci 10031cb0ef41Sopenharmony_ci#else 10041cb0ef41Sopenharmony_ci 10051cb0ef41Sopenharmony_ci#include <version> 10061cb0ef41Sopenharmony_ci 10071cb0ef41Sopenharmony_cinamespace cxx20 10081cb0ef41Sopenharmony_ci{ 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci// As C++20 supports feature test macros in the standard, there is no 10111cb0ef41Sopenharmony_ci// immediate need to actually test for feature availability on the 10121cb0ef41Sopenharmony_ci// Autoconf side. 10131cb0ef41Sopenharmony_ci 10141cb0ef41Sopenharmony_ci} // namespace cxx20 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_ci#endif // __cplusplus < 202002L && !defined _MSC_VER 10171cb0ef41Sopenharmony_ci 10181cb0ef41Sopenharmony_ci]]) 1019