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