Home | History | Annotate | Line # | Download | only in m4
      1 # Prefer GNU C11 and C++11 to earlier versions.  -*- coding: utf-8 -*-
      2 
      3 # This implementation is taken from GNU Autoconf lib/autoconf/c.m4
      4 # commit 017d5ddd82854911f0119691d91ea8a1438824d6
      5 # dated Sun Apr 3 13:57:17 2016 -0700
      6 # This implementation will be obsolete once we can assume Autoconf 2.70
      7 # or later is installed everywhere a Gnulib program might be developed.
      8 
      9 m4_version_prereq([2.70], [], [
     10 
     11 
     12 # Copyright (C) 2001-2022 Free Software Foundation, Inc.
     13 
     14 # This program is free software; you can redistribute it and/or modify
     15 # it under the terms of the GNU General Public License as published by
     16 # the Free Software Foundation, either version 3 of the License, or
     17 # (at your option) any later version.
     18 #
     19 # This program is distributed in the hope that it will be useful,
     20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22 # GNU General Public License for more details.
     23 #
     24 # You should have received a copy of the GNU General Public License
     25 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
     26 
     27 # Written by David MacKenzie, with help from
     28 # Akim Demaille, Paul Eggert,
     29 # Franois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
     30 # Roland McGrath, Noah Friedman, david d zuhn, and many others.
     31 
     32 
     33 # AC_PROG_CC([COMPILER ...])
     34 # --------------------------
     35 # COMPILER ... is a space separated list of C compilers to search for.
     36 # This just gives the user an opportunity to specify an alternative
     37 # search list for the C compiler.
     38 AC_DEFUN_ONCE([AC_PROG_CC],
     39 [AC_LANG_PUSH(C)dnl
     40 AC_ARG_VAR([CC],     [C compiler command])dnl
     41 AC_ARG_VAR([CFLAGS], [C compiler flags])dnl
     42 _AC_ARG_VAR_LDFLAGS()dnl
     43 _AC_ARG_VAR_LIBS()dnl
     44 _AC_ARG_VAR_CPPFLAGS()dnl
     45 m4_ifval([$1],
     46       [AC_CHECK_TOOLS(CC, [$1])],
     47 [AC_CHECK_TOOL(CC, gcc)
     48 if test -z "$CC"; then
     49   dnl Here we want:
     50   dnl	AC_CHECK_TOOL(CC, cc)
     51   dnl but without the check for a tool without the prefix.
     52   dnl Until the check is removed from there, copy the code:
     53   if test -n "$ac_tool_prefix"; then
     54     AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc])
     55   fi
     56 fi
     57 if test -z "$CC"; then
     58   AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
     59 fi
     60 if test -z "$CC"; then
     61   AC_CHECK_TOOLS(CC, cl.exe)
     62 fi
     63 if test -z "$CC"; then
     64   AC_CHECK_TOOL(CC, clang)
     65 fi
     66 ])
     67 
     68 test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH])
     69 
     70 # Provide some information about the compiler.
     71 _AS_ECHO_LOG([checking for _AC_LANG compiler version])
     72 set X $ac_compile
     73 ac_compiler=$[2]
     74 for ac_option in --version -v -V -qversion -version; do
     75   _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
     76 done
     77 
     78 m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
     79 m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
     80 _AC_LANG_COMPILER_GNU
     81 if test $ac_compiler_gnu = yes; then
     82   GCC=yes
     83 else
     84   GCC=
     85 fi
     86 _AC_PROG_CC_G
     87 dnl
     88 dnl Set ac_prog_cc_stdc to the supported C version.
     89 dnl Also set the documented variable ac_cv_prog_cc_stdc;
     90 dnl its name was chosen when it was cached, but it is no longer cached.
     91 _AC_PROG_CC_C11([ac_prog_cc_stdc=c11
     92 		 ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11],
     93   [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99
     94 		    ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99],
     95      [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89
     96 		       ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89],
     97 		      [ac_prog_cc_stdc=no
     98 		       ac_cv_prog_cc_stdc=no])])])
     99 dnl
    100 AC_LANG_POP(C)dnl
    101 ])# AC_PROG_CC
    102 
    103 
    104 
    105 # AC_PROG_CXX([LIST-OF-COMPILERS])
    106 # --------------------------------
    107 # LIST-OF-COMPILERS is a space separated list of C++ compilers to search
    108 # for (if not specified, a default list is used).  This just gives the
    109 # user an opportunity to specify an alternative search list for the C++
    110 # compiler.
    111 # aCC	HP-UX C++ compiler much better than `CC', so test before.
    112 # FCC   Fujitsu C++ compiler
    113 # KCC	KAI C++ compiler
    114 # RCC	Rational C++
    115 # xlC_r	AIX C Set++ (with support for reentrant code)
    116 # xlC	AIX C Set++
    117 AC_DEFUN([AC_PROG_CXX],
    118 [AC_LANG_PUSH(C++)dnl
    119 AC_ARG_VAR([CXX],      [C++ compiler command])dnl
    120 AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl
    121 _AC_ARG_VAR_LDFLAGS()dnl
    122 _AC_ARG_VAR_LIBS()dnl
    123 _AC_ARG_VAR_CPPFLAGS()dnl
    124 _AC_ARG_VAR_PRECIOUS([CCC])dnl
    125 if test -z "$CXX"; then
    126   if test -n "$CCC"; then
    127     CXX=$CCC
    128   else
    129     AC_CHECK_TOOLS(CXX,
    130 		   [m4_default([$1],
    131 			       [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])],
    132 		   g++)
    133   fi
    134 fi
    135 # Provide some information about the compiler.
    136 _AS_ECHO_LOG([checking for _AC_LANG compiler version])
    137 set X $ac_compile
    138 ac_compiler=$[2]
    139 for ac_option in --version -v -V -qversion; do
    140   _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
    141 done
    142 
    143 m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
    144 m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
    145 _AC_LANG_COMPILER_GNU
    146 if test $ac_compiler_gnu = yes; then
    147   GXX=yes
    148 else
    149   GXX=
    150 fi
    151 _AC_PROG_CXX_G
    152 _AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11
    153 		    ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
    154 		    ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11],
    155    [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98
    156 		        ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98],
    157 		       [ac_prog_cxx_stdcxx=no
    158 		        ac_cv_prog_cxx_stdcxx=no])])
    159 AC_LANG_POP(C++)dnl
    160 ])# AC_PROG_CXX
    161 
    162 
    163 # _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
    164 #		ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
    165 # --------------------------------------------------------------
    166 # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')
    167 # by trying to compile a program of TEST-PROLOGUE and TEST-BODY.  If this fails,
    168 # try again with each compiler option in the space-separated OPTION-LIST; if one
    169 # helps, append it to CC.  If eventually successful, run ACTION-IF-AVAILABLE,
    170 # else ACTION-IF-UNAVAILABLE.
    171 AC_DEFUN([_AC_C_STD_TRY],
    172 [AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])
    173 AC_CACHE_VAL(ac_cv_prog_cc_$1,
    174 [ac_cv_prog_cc_$1=no
    175 ac_save_CC=$CC
    176 AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
    177 for ac_arg in '' $4
    178 do
    179   CC="$ac_save_CC $ac_arg"
    180   _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])
    181   test "x$ac_cv_prog_cc_$1" != "xno" && break
    182 done
    183 rm -f conftest.$ac_ext
    184 CC=$ac_save_CC
    185 ])# AC_CACHE_VAL
    186 ac_prog_cc_stdc_options=
    187 case "x$ac_cv_prog_cc_$1" in
    188   x)
    189     AC_MSG_RESULT([none needed]) ;;
    190   xno)
    191     AC_MSG_RESULT([unsupported]) ;;
    192   *)
    193     ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1"
    194     CC=$CC$ac_prog_cc_stdc_options
    195     AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;
    196 esac
    197 AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6])
    198 ])# _AC_C_STD_TRY
    199 
    200 # _AC_C_C99_TEST_HEADER
    201 # ---------------------
    202 # A C header suitable for testing for C99.
    203 AC_DEFUN([_AC_C_C99_TEST_HEADER],
    204 [[#include <stdarg.h>
    205 #include <stdbool.h>
    206 #include <stddef.h>
    207 #include <stdlib.h>
    208 #include <wchar.h>
    209 #include <stdio.h>
    210 
    211 // Check varargs macros.  These examples are taken from C99 6.10.3.5.
    212 #define debug(...) fprintf (stderr, __VA_ARGS__)
    213 #define showlist(...) puts (#__VA_ARGS__)
    214 #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
    215 static void
    216 test_varargs_macros (void)
    217 {
    218   int x = 1234;
    219   int y = 5678;
    220   debug ("Flag");
    221   debug ("X = %d\n", x);
    222   showlist (The first, second, and third items.);
    223   report (x>y, "x is %d but y is %d", x, y);
    224 }
    225 
    226 // Check long long types.
    227 #define BIG64 18446744073709551615ull
    228 #define BIG32 4294967295ul
    229 #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
    230 #if !BIG_OK
    231   your preprocessor is broken;
    232 #endif
    233 #if BIG_OK
    234 #else
    235   your preprocessor is broken;
    236 #endif
    237 static long long int bignum = -9223372036854775807LL;
    238 static unsigned long long int ubignum = BIG64;
    239 
    240 struct incomplete_array
    241 {
    242   int datasize;
    243   double data[];
    244 };
    245 
    246 struct named_init {
    247   int number;
    248   const wchar_t *name;
    249   double average;
    250 };
    251 
    252 typedef const char *ccp;
    253 
    254 static inline int
    255 test_restrict (ccp restrict text)
    256 {
    257   // See if C++-style comments work.
    258   // Iterate through items via the restricted pointer.
    259   // Also check for declarations in for loops.
    260   for (unsigned int i = 0; *(text+i) != '\0'; ++i)
    261     continue;
    262   return 0;
    263 }
    264 
    265 // Check varargs and va_copy.
    266 static bool
    267 test_varargs (const char *format, ...)
    268 {
    269   va_list args;
    270   va_start (args, format);
    271   va_list args_copy;
    272   va_copy (args_copy, args);
    273 
    274   const char *str = "";
    275   int number = 0;
    276   float fnumber = 0;
    277 
    278   while (*format)
    279     {
    280       switch (*format++)
    281 	{
    282 	case 's': // string
    283 	  str = va_arg (args_copy, const char *);
    284 	  break;
    285 	case 'd': // int
    286 	  number = va_arg (args_copy, int);
    287 	  break;
    288 	case 'f': // float
    289 	  fnumber = va_arg (args_copy, double);
    290 	  break;
    291 	default:
    292 	  break;
    293 	}
    294     }
    295   va_end (args_copy);
    296   va_end (args);
    297 
    298   return *str && number && fnumber;
    299 }]])# _AC_C_C99_TEST_HEADER
    300 
    301 # _AC_C_C99_TEST_BODY
    302 # -------------------
    303 # A C body suitable for testing for C99, assuming the corresponding header.
    304 AC_DEFUN([_AC_C_C99_TEST_BODY],
    305 [[
    306   // Check bool.
    307   _Bool success = false;
    308 
    309   // Check restrict.
    310   if (test_restrict ("String literal") == 0)
    311     success = true;
    312   char *restrict newvar = "Another string";
    313 
    314   // Check varargs.
    315   success &= test_varargs ("s, d' f .", "string", 65, 34.234);
    316   test_varargs_macros ();
    317 
    318   // Check flexible array members.
    319   struct incomplete_array *ia =
    320     malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
    321   ia->datasize = 10;
    322   for (int i = 0; i < ia->datasize; ++i)
    323     ia->data[i] = i * 1.234;
    324 
    325   // Check named initializers.
    326   struct named_init ni = {
    327     .number = 34,
    328     .name = L"Test wide string",
    329     .average = 543.34343,
    330   };
    331 
    332   ni.number = 58;
    333 
    334   int dynamic_array[ni.number];
    335   dynamic_array[ni.number - 1] = 543;
    336 
    337   // work around unused variable warnings
    338   return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
    339 	  || dynamic_array[ni.number - 1] != 543);
    340 ]])
    341 
    342 # _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
    343 # ----------------------------------------------------------------
    344 # If the C compiler is not in ISO C99 mode by default, try to add an
    345 # option to output variable CC to make it so.  This macro tries
    346 # various options that select ISO C99 on some system or another.  It
    347 # considers the compiler to be in ISO C99 mode if it handles _Bool,
    348 # // comments, flexible array members, inline, long long int, mixed
    349 # code and declarations, named initialization of structs, restrict,
    350 # va_copy, varargs macros, variable declarations in for loops and
    351 # variable length arrays.
    352 AC_DEFUN([_AC_PROG_CC_C99],
    353 [_AC_C_STD_TRY([c99],
    354 [_AC_C_C99_TEST_HEADER],
    355 [_AC_C_C99_TEST_BODY],
    356 dnl Try
    357 dnl GCC		-std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)
    358 dnl IBM XL C	-qlanglvl=extc1x (V12.1; does not pass C11 test)
    359 dnl IBM XL C	-qlanglvl=extc99
    360 dnl		(pre-V12.1; unused restrictive mode: -qlanglvl=stdc99)
    361 dnl HP cc	-AC99
    362 dnl Intel ICC	-std=c99, -c99 (deprecated)
    363 dnl IRIX	-c99
    364 dnl Solaris	-D_STDC_C99=
    365 dnl		cc's -xc99 option uses linker magic to define the external
    366 dnl		symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99
    367 dnl		behavior for C library functions.  This is not wanted here,
    368 dnl		because it means that a single module compiled with -xc99
    369 dnl		alters C runtime behavior for the entire program, not for
    370 dnl		just the module.  Instead, define the (private) symbol
    371 dnl		_STDC_C99, which suppresses a bogus failure in <stdbool.h>.
    372 dnl		The resulting compiler passes the test case here, and that's
    373 dnl		good enough.  For more, please see the thread starting at:
    374 dnl            https://lists.gnu.org/r/autoconf/2010-12/msg00059.html
    375 dnl Tru64	-c99
    376 dnl with extended modes being tried first.
    377 [[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl
    378 ])# _AC_PROG_CC_C99
    379 
    380 
    381 # _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
    382 # ----------------------------------------------------------------
    383 # If the C compiler is not in ISO C11 mode by default, try to add an
    384 # option to output variable CC to make it so.  This macro tries
    385 # various options that select ISO C11 on some system or another.  It
    386 # considers the compiler to be in ISO C11 mode if it handles _Alignas,
    387 # _Alignof, _Noreturn, _Static_assert, UTF-8 string literals,
    388 # duplicate typedefs, and anonymous structures and unions.
    389 AC_DEFUN([_AC_PROG_CC_C11],
    390 [_AC_C_STD_TRY([c11],
    391 [_AC_C_C99_TEST_HEADER[
    392 // Check _Alignas.
    393 char _Alignas (double) aligned_as_double;
    394 char _Alignas (0) no_special_alignment;
    395 extern char aligned_as_int;
    396 char _Alignas (0) _Alignas (int) aligned_as_int;
    397 
    398 // Check _Alignof.
    399 enum
    400 {
    401   int_alignment = _Alignof (int),
    402   int_array_alignment = _Alignof (int[100]),
    403   char_alignment = _Alignof (char)
    404 };
    405 _Static_assert (0 < -_Alignof (int), "_Alignof is signed");
    406 
    407 // Check _Noreturn.
    408 int _Noreturn does_not_return (void) { for (;;) continue; }
    409 
    410 // Check _Static_assert.
    411 struct test_static_assert
    412 {
    413   int x;
    414   _Static_assert (sizeof (int) <= sizeof (long int),
    415                   "_Static_assert does not work in struct");
    416   long int y;
    417 };
    418 
    419 // Check UTF-8 literals.
    420 #define u8 syntax error!
    421 char const utf8_literal[] = u8"happens to be ASCII" "another string";
    422 
    423 // Check duplicate typedefs.
    424 typedef long *long_ptr;
    425 typedef long int *long_ptr;
    426 typedef long_ptr long_ptr;
    427 
    428 // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
    429 struct anonymous
    430 {
    431   union {
    432     struct { int i; int j; };
    433     struct { int k; long int l; } w;
    434   };
    435   int m;
    436 } v1;
    437 ]],
    438 [_AC_C_C99_TEST_BODY[
    439   v1.i = 2;
    440   v1.w.k = 5;
    441   _Static_assert ((offsetof (struct anonymous, i)
    442 		   == offsetof (struct anonymous, w.k)),
    443 		  "Anonymous union alignment botch");
    444 ]],
    445 dnl Try
    446 dnl GCC		-std=gnu11 (unused restrictive mode: -std=c11)
    447 dnl with extended modes being tried first.
    448 dnl
    449 dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as
    450 dnl of September 2012) does not pass the C11 test.  For now, try extc1x when
    451 dnl compiling the C99 test instead, since it enables _Static_assert and
    452 dnl _Noreturn, which is a win.  If -qlanglvl=extc11 or -qlanglvl=extc1x passes
    453 dnl the C11 test in some future version of IBM XL C, we'll add it here,
    454 dnl preferably extc11.
    455 [[-std=gnu11]], [$1], [$2])[]dnl
    456 ])# _AC_PROG_CC_C11
    457 
    458 
    459 # AC_PROG_CC_C89
    460 # --------------
    461 # Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC,
    462 # as that'd be incompatible with how Automake redefines AC_PROG_CC.  See
    463 # <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>.
    464 AU_DEFUN([AC_PROG_CC_C89],
    465   [AC_REQUIRE([AC_PROG_CC])],
    466   [$0 is obsolete; use AC_PROG_CC]
    467 )
    468 
    469 # AC_PROG_CC_C99
    470 # --------------
    471 AU_DEFUN([AC_PROG_CC_C99],
    472   [AC_REQUIRE([AC_PROG_CC])],
    473   [$0 is obsolete; use AC_PROG_CC]
    474 )
    475 
    476 # AC_PROG_CC_STDC
    477 # ---------------
    478 AU_DEFUN([AC_PROG_CC_STDC],
    479   [AC_REQUIRE([AC_PROG_CC])],
    480   [$0 is obsolete; use AC_PROG_CC]
    481 )
    482 
    483 
    484 # AC_C_PROTOTYPES
    485 # ---------------
    486 # Check if the C compiler supports prototypes, included if it needs
    487 # options.
    488 AC_DEFUN([AC_C_PROTOTYPES],
    489 [AC_REQUIRE([AC_PROG_CC])dnl
    490 if test "$ac_prog_cc_stdc" != no; then
    491   AC_DEFINE(PROTOTYPES, 1,
    492 	    [Define to 1 if the C compiler supports function prototypes.])
    493   AC_DEFINE(__PROTOTYPES, 1,
    494 	    [Define like PROTOTYPES; this can be used by system headers.])
    495 fi
    496 ])# AC_C_PROTOTYPES
    497 
    498 
    499 # _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
    500 #		  ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
    501 # ----------------------------------------------------------------
    502 # Check whether the C++ compiler accepts features of STANDARD (e.g
    503 # `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE
    504 # and TEST-BODY.  If this fails, try again with each compiler option
    505 # in the space-separated OPTION-LIST; if one helps, append it to CXX.
    506 # If eventually successful, run ACTION-IF-AVAILABLE, else
    507 # ACTION-IF-UNAVAILABLE.
    508 AC_DEFUN([_AC_CXX_STD_TRY],
    509 [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
    510 AC_LANG_PUSH(C++)dnl
    511 AC_CACHE_VAL(ac_cv_prog_cxx_$1,
    512 [ac_cv_prog_cxx_$1=no
    513 ac_save_CXX=$CXX
    514 AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
    515 for ac_arg in '' $4
    516 do
    517   CXX="$ac_save_CXX $ac_arg"
    518   _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg])
    519   test "x$ac_cv_prog_cxx_$1" != "xno" && break
    520 done
    521 rm -f conftest.$ac_ext
    522 CXX=$ac_save_CXX
    523 ])# AC_CACHE_VAL
    524 ac_prog_cxx_stdcxx_options=
    525 case "x$ac_cv_prog_cxx_$1" in
    526   x)
    527     AC_MSG_RESULT([none needed]) ;;
    528   xno)
    529     AC_MSG_RESULT([unsupported]) ;;
    530   *)
    531     ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1"
    532     CXX=$CXX$ac_prog_cxx_stdcxx_options
    533     AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;;
    534 esac
    535 AC_LANG_POP(C++)dnl
    536 AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6])
    537 ])# _AC_CXX_STD_TRY
    538 
    539 # _AC_CXX_CXX98_TEST_HEADER
    540 # -------------------------
    541 # A C++ header suitable for testing for CXX98.
    542 AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER],
    543 [[
    544 #include <algorithm>
    545 #include <cstdlib>
    546 #include <fstream>
    547 #include <iomanip>
    548 #include <iostream>
    549 #include <list>
    550 #include <map>
    551 #include <set>
    552 #include <sstream>
    553 #include <stdexcept>
    554 #include <string>
    555 #include <utility>
    556 #include <vector>
    557 
    558 namespace test {
    559   typedef std::vector<std::string> string_vec;
    560   typedef std::pair<int,bool> map_value;
    561   typedef std::map<std::string,map_value> map_type;
    562   typedef std::set<int> set_type;
    563 
    564   template<typename T>
    565   class printer {
    566   public:
    567     printer(std::ostringstream& os): os(os) {}
    568     void operator() (T elem) { os << elem << std::endl; }
    569   private:
    570     std::ostringstream& os;
    571   };
    572 }
    573 ]])# _AC_CXX_CXX98_TEST_HEADER
    574 
    575 # _AC_CXX_CXX98_TEST_BODY
    576 # -----------------------
    577 # A C++ body suitable for testing for CXX98, assuming the corresponding header.
    578 AC_DEFUN([_AC_CXX_CXX98_TEST_BODY],
    579 [[
    580 
    581 try {
    582   // Basic string.
    583   std::string teststr("ASCII text");
    584   teststr += " string";
    585 
    586   // Simple vector.
    587   test::string_vec testvec;
    588   testvec.push_back(teststr);
    589   testvec.push_back("foo");
    590   testvec.push_back("bar");
    591   if (testvec.size() != 3) {
    592     throw std::runtime_error("vector size is not 1");
    593   }
    594 
    595   // Dump vector into stringstream and obtain string.
    596   std::ostringstream os;
    597   for (test::string_vec::const_iterator i = testvec.begin();
    598        i != testvec.end(); ++i) {
    599     if (i + 1 != testvec.end()) {
    600       os << teststr << '\n';
    601     }
    602   }
    603   // Check algorithms work.
    604   std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os));
    605   std::string os_out = os.str();
    606 
    607   // Test pair and map.
    608   test::map_type testmap;
    609   testmap.insert(std::make_pair(std::string("key"),
    610                                 std::make_pair(53,false)));
    611 
    612   // Test set.
    613   int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
    614   test::set_type testset(values, values + sizeof(values)/sizeof(values[0]));
    615   std::list<int> testlist(testset.begin(), testset.end());
    616   std::copy(testset.begin(), testset.end(), std::back_inserter(testlist));
    617 } catch (const std::exception& e) {
    618   std::cerr << "Caught exception: " << e.what() << std::endl;
    619 
    620   // Test fstream
    621   std::ofstream of("test.txt");
    622   of << "Test ASCII text\n" << std::flush;
    623   of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl;
    624   of.close();
    625 }
    626 std::exit(0);
    627 ]])
    628 
    629 # _AC_CXX_CXX11_TEST_HEADER
    630 # -------------------------
    631 # A C++ header suitable for testing for CXX11.
    632 AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER],
    633 [[
    634 #include <deque>
    635 #include <functional>
    636 #include <memory>
    637 #include <tuple>
    638 #include <array>
    639 #include <regex>
    640 #include <iostream>
    641 
    642 namespace cxx11test
    643 {
    644   typedef std::shared_ptr<std::string> sptr;
    645   typedef std::weak_ptr<std::string> wptr;
    646 
    647   typedef std::tuple<std::string,int,double> tp;
    648   typedef std::array<int, 20> int_array;
    649 
    650   constexpr int get_val() { return 20; }
    651 
    652   struct testinit
    653   {
    654     int i;
    655     double d;
    656   };
    657 
    658   class delegate  {
    659   public:
    660     delegate(int n) : n(n) {}
    661     delegate(): delegate(2354) {}
    662 
    663     virtual int getval() { return this->n; };
    664   protected:
    665     int n;
    666   };
    667 
    668   class overridden : public delegate {
    669   public:
    670     overridden(int n): delegate(n) {}
    671     virtual int getval() override final { return this->n * 2; }
    672   };
    673 
    674   class nocopy {
    675   public:
    676     nocopy(int i): i(i) {}
    677     nocopy() = default;
    678     nocopy(const nocopy&) = delete;
    679     nocopy & operator=(const nocopy&) = delete;
    680   private:
    681     int i;
    682   };
    683 }
    684 ]])# _AC_CXX_CXX11_TEST_HEADER
    685 
    686 # _AC_CXX_CXX11_TEST_BODY
    687 # -----------------------
    688 # A C++ body suitable for testing for CXX11, assuming the corresponding header.
    689 AC_DEFUN([_AC_CXX_CXX11_TEST_BODY],
    690 [[
    691 {
    692   // Test auto and decltype
    693   std::deque<int> d;
    694   d.push_front(43);
    695   d.push_front(484);
    696   d.push_front(3);
    697   d.push_front(844);
    698   int total = 0;
    699   for (auto i = d.begin(); i != d.end(); ++i) { total += *i; }
    700 
    701   auto a1 = 6538;
    702   auto a2 = 48573953.4;
    703   auto a3 = "String literal";
    704 
    705   decltype(a2) a4 = 34895.034;
    706 }
    707 {
    708   // Test constexpr
    709   short sa[cxx11test::get_val()] = { 0 };
    710 }
    711 {
    712   // Test initializer lists
    713   cxx11test::testinit il = { 4323, 435234.23544 };
    714 }
    715 {
    716   // Test range-based for and lambda
    717   cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
    718   for (int &x : array) { x += 23; }
    719   std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; });
    720 }
    721 {
    722   using cxx11test::sptr;
    723   using cxx11test::wptr;
    724 
    725   sptr sp(new std::string("ASCII string"));
    726   wptr wp(sp);
    727   sptr sp2(wp);
    728 }
    729 {
    730   cxx11test::tp tuple("test", 54, 45.53434);
    731   double d = std::get<2>(tuple);
    732   std::string s;
    733   int i;
    734   std::tie(s,i,d) = tuple;
    735 }
    736 {
    737   static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$");
    738   std::string testmatch("Test if this string matches");
    739   bool match = std::regex_search(testmatch, filename_regex);
    740 }
    741 {
    742   cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
    743   cxx11test::int_array::size_type size = array.size();
    744 }
    745 {
    746   // Test constructor delegation
    747   cxx11test::delegate d1;
    748   cxx11test::delegate d2();
    749   cxx11test::delegate d3(45);
    750 }
    751 {
    752   // Test override and final
    753   cxx11test::overridden o1(55464);
    754 }
    755 {
    756   // Test nullptr
    757   char *c = nullptr;
    758 }
    759 {
    760   // Test template brackets
    761   std::vector<std::pair<int,char*>> v1;
    762 }
    763 {
    764   // Unicode literals
    765   char const *utf8 = u8"UTF-8 string \u2500";
    766   char16_t const *utf16 = u"UTF-8 string \u2500";
    767   char32_t const *utf32 = U"UTF-32 string \u2500";
    768 }
    769 ]])
    770 
    771 # _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
    772 # -------------------------------------------------------------------
    773 
    774 # If the C++ compiler is not in ISO C++98 mode by default, try to add
    775 # an option to output variable CXX to make it so.  This macro tries
    776 # various options that select ISO C++98 on some system or another.  It
    777 # considers the compiler to be in ISO C++98 mode if it handles basic
    778 # features of the std namespace including: string, containers (list,
    779 # map, set, vector), streams (fstreams, iostreams, stringstreams,
    780 # iomanip), pair, exceptions and algorithms.
    781 
    782 
    783 AC_DEFUN([_AC_PROG_CXX_CXX98],
    784 [_AC_CXX_STD_TRY([cxx98],
    785 [_AC_CXX_CXX98_TEST_HEADER],
    786 [_AC_CXX_CXX98_TEST_BODY],
    787 dnl Try
    788 dnl GCC		-std=gnu++98 (unused restrictive mode: -std=c++98)
    789 dnl IBM XL C	-qlanglvl=extended
    790 dnl HP aC++	-AA
    791 dnl Intel ICC	-std=gnu++98
    792 dnl Solaris	N/A (default)
    793 dnl Tru64	N/A (default, but -std gnu could be used)
    794 dnl with extended modes being tried first.
    795 [[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl
    796 ])# _AC_PROG_CXX_CXX98
    797 
    798 # _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
    799 # -------------------------------------------------------------------
    800 # If the C++ compiler is not in ISO CXX11 mode by default, try to add
    801 # an option to output variable CXX to make it so.  This macro tries
    802 # various options that select ISO C++11 on some system or another.  It
    803 # considers the compiler to be in ISO C++11 mode if it handles all the
    804 # tests from the C++98 checks, plus the following: Language features
    805 # (auto, constexpr, decltype, default/deleted constructors, delegate
    806 # constructors, final, initializer lists, lambda functions, nullptr,
    807 # override, range-based for loops, template brackets without spaces,
    808 # unicode literals) and library features (array, memory (shared_ptr,
    809 # weak_ptr), regex and tuple types).
    810 AC_DEFUN([_AC_PROG_CXX_CXX11],
    811 [_AC_CXX_STD_TRY([cxx11],
    812 [_AC_CXX_CXX11_TEST_HEADER
    813 _AC_CXX_CXX98_TEST_HEADER],
    814 [_AC_CXX_CXX11_TEST_BODY
    815 _AC_CXX_CXX98_TEST_BODY],
    816 dnl Try
    817 dnl GCC		-std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants]
    818 dnl IBM XL C	-qlanglvl=extended0x
    819 dnl		(pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11)
    820 dnl HP aC++	-AA
    821 dnl Intel ICC	-std=c++11 -std=c++0x
    822 dnl Solaris	N/A (no support)
    823 dnl Tru64	N/A (no support)
    824 dnl with extended modes being tried first.
    825 [[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl
    826 ])# _AC_PROG_CXX_CXX11
    827 
    828 
    829 ])# m4_version_prereq
    830