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