| # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- |
| |
| # This implementation is taken from GNU Autoconf lib/autoconf/c.m4 |
| # commit 017d5ddd82854911f0119691d91ea8a1438824d6 |
| # dated Sun Apr 3 13:57:17 2016 -0700 |
| # This implementation will be obsolete once we can assume Autoconf 2.70 |
| # or later is installed everywhere a Gnulib program might be developed. |
| |
| m4_version_prereq([2.70], [], [ |
| |
| |
| # Copyright (C) 2001-2021 Free Software Foundation, Inc. |
| |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation, either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <https://www.gnu.org/licenses/>. |
| |
| # Written by David MacKenzie, with help from |
| # Akim Demaille, Paul Eggert, |
| # François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, |
| # Roland McGrath, Noah Friedman, david d zuhn, and many others. |
| |
| |
| # AC_PROG_CC([COMPILER ...]) |
| # -------------------------- |
| # COMPILER ... is a space separated list of C compilers to search for. |
| # This just gives the user an opportunity to specify an alternative |
| # search list for the C compiler. |
| AC_DEFUN_ONCE([AC_PROG_CC], |
| [AC_LANG_PUSH(C)dnl |
| AC_ARG_VAR([CC], [C compiler command])dnl |
| AC_ARG_VAR([CFLAGS], [C compiler flags])dnl |
| _AC_ARG_VAR_LDFLAGS()dnl |
| _AC_ARG_VAR_LIBS()dnl |
| _AC_ARG_VAR_CPPFLAGS()dnl |
| m4_ifval([$1], |
| [AC_CHECK_TOOLS(CC, [$1])], |
| [AC_CHECK_TOOL(CC, gcc) |
| if test -z "$CC"; then |
| dnl Here we want: |
| dnl AC_CHECK_TOOL(CC, cc) |
| dnl but without the check for a tool without the prefix. |
| dnl Until the check is removed from there, copy the code: |
| if test -n "$ac_tool_prefix"; then |
| AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc]) |
| fi |
| fi |
| if test -z "$CC"; then |
| AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) |
| fi |
| if test -z "$CC"; then |
| AC_CHECK_TOOLS(CC, cl.exe) |
| fi |
| if test -z "$CC"; then |
| AC_CHECK_TOOL(CC, clang) |
| fi |
| ]) |
| |
| test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH]) |
| |
| # Provide some information about the compiler. |
| _AS_ECHO_LOG([checking for _AC_LANG compiler version]) |
| set X $ac_compile |
| ac_compiler=$[2] |
| for ac_option in --version -v -V -qversion -version; do |
| _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) |
| done |
| |
| m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl |
| m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl |
| _AC_LANG_COMPILER_GNU |
| if test $ac_compiler_gnu = yes; then |
| GCC=yes |
| else |
| GCC= |
| fi |
| _AC_PROG_CC_G |
| dnl |
| dnl Set ac_prog_cc_stdc to the supported C version. |
| dnl Also set the documented variable ac_cv_prog_cc_stdc; |
| dnl its name was chosen when it was cached, but it is no longer cached. |
| _AC_PROG_CC_C11([ac_prog_cc_stdc=c11 |
| ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11], |
| [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99 |
| ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99], |
| [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89 |
| ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89], |
| [ac_prog_cc_stdc=no |
| ac_cv_prog_cc_stdc=no])])]) |
| dnl |
| AC_LANG_POP(C)dnl |
| ])# AC_PROG_CC |
| |
| |
| |
| # AC_PROG_CXX([LIST-OF-COMPILERS]) |
| # -------------------------------- |
| # LIST-OF-COMPILERS is a space separated list of C++ compilers to search |
| # for (if not specified, a default list is used). This just gives the |
| # user an opportunity to specify an alternative search list for the C++ |
| # compiler. |
| # aCC HP-UX C++ compiler much better than `CC', so test before. |
| # FCC Fujitsu C++ compiler |
| # KCC KAI C++ compiler |
| # RCC Rational C++ |
| # xlC_r AIX C Set++ (with support for reentrant code) |
| # xlC AIX C Set++ |
| AC_DEFUN([AC_PROG_CXX], |
| [AC_LANG_PUSH(C++)dnl |
| AC_ARG_VAR([CXX], [C++ compiler command])dnl |
| AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl |
| _AC_ARG_VAR_LDFLAGS()dnl |
| _AC_ARG_VAR_LIBS()dnl |
| _AC_ARG_VAR_CPPFLAGS()dnl |
| _AC_ARG_VAR_PRECIOUS([CCC])dnl |
| if test -z "$CXX"; then |
| if test -n "$CCC"; then |
| CXX=$CCC |
| else |
| AC_CHECK_TOOLS(CXX, |
| [m4_default([$1], |
| [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])], |
| g++) |
| fi |
| fi |
| # Provide some information about the compiler. |
| _AS_ECHO_LOG([checking for _AC_LANG compiler version]) |
| set X $ac_compile |
| ac_compiler=$[2] |
| for ac_option in --version -v -V -qversion; do |
| _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) |
| done |
| |
| m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl |
| m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl |
| _AC_LANG_COMPILER_GNU |
| if test $ac_compiler_gnu = yes; then |
| GXX=yes |
| else |
| GXX= |
| fi |
| _AC_PROG_CXX_G |
| _AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11 |
| ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 |
| ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11], |
| [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98 |
| ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98], |
| [ac_prog_cxx_stdcxx=no |
| ac_cv_prog_cxx_stdcxx=no])]) |
| AC_LANG_POP(C++)dnl |
| ])# AC_PROG_CXX |
| |
| |
| # _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, |
| # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) |
| # -------------------------------------------------------------- |
| # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') |
| # by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, |
| # try again with each compiler option in the space-separated OPTION-LIST; if one |
| # helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, |
| # else ACTION-IF-UNAVAILABLE. |
| AC_DEFUN([_AC_C_STD_TRY], |
| [AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features]) |
| AC_CACHE_VAL(ac_cv_prog_cc_$1, |
| [ac_cv_prog_cc_$1=no |
| ac_save_CC=$CC |
| AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) |
| for ac_arg in '' $4 |
| do |
| CC="$ac_save_CC $ac_arg" |
| _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) |
| test "x$ac_cv_prog_cc_$1" != "xno" && break |
| done |
| rm -f conftest.$ac_ext |
| CC=$ac_save_CC |
| ])# AC_CACHE_VAL |
| ac_prog_cc_stdc_options= |
| case "x$ac_cv_prog_cc_$1" in |
| x) |
| AC_MSG_RESULT([none needed]) ;; |
| xno) |
| AC_MSG_RESULT([unsupported]) ;; |
| *) |
| ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1" |
| CC=$CC$ac_prog_cc_stdc_options |
| AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; |
| esac |
| AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) |
| ])# _AC_C_STD_TRY |
| |
| # _AC_C_C99_TEST_HEADER |
| # --------------------- |
| # A C header suitable for testing for C99. |
| AC_DEFUN([_AC_C_C99_TEST_HEADER], |
| [[#include <stdarg.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdlib.h> |
| #include <wchar.h> |
| #include <stdio.h> |
| |
| // Check varargs macros. These examples are taken from C99 6.10.3.5. |
| #define debug(...) fprintf (stderr, __VA_ARGS__) |
| #define showlist(...) puts (#__VA_ARGS__) |
| #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) |
| static void |
| test_varargs_macros (void) |
| { |
| int x = 1234; |
| int y = 5678; |
| debug ("Flag"); |
| debug ("X = %d\n", x); |
| showlist (The first, second, and third items.); |
| report (x>y, "x is %d but y is %d", x, y); |
| } |
| |
| // Check long long types. |
| #define BIG64 18446744073709551615ull |
| #define BIG32 4294967295ul |
| #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) |
| #if !BIG_OK |
| your preprocessor is broken; |
| #endif |
| #if BIG_OK |
| #else |
| your preprocessor is broken; |
| #endif |
| static long long int bignum = -9223372036854775807LL; |
| static unsigned long long int ubignum = BIG64; |
| |
| struct incomplete_array |
| { |
| int datasize; |
| double data[]; |
| }; |
| |
| struct named_init { |
| int number; |
| const wchar_t *name; |
| double average; |
| }; |
| |
| typedef const char *ccp; |
| |
| static inline int |
| test_restrict (ccp restrict text) |
| { |
| // See if C++-style comments work. |
| // Iterate through items via the restricted pointer. |
| // Also check for declarations in for loops. |
| for (unsigned int i = 0; *(text+i) != '\0'; ++i) |
| continue; |
| return 0; |
| } |
| |
| // Check varargs and va_copy. |
| static bool |
| test_varargs (const char *format, ...) |
| { |
| va_list args; |
| va_start (args, format); |
| va_list args_copy; |
| va_copy (args_copy, args); |
| |
| const char *str = ""; |
| int number = 0; |
| float fnumber = 0; |
| |
| while (*format) |
| { |
| switch (*format++) |
| { |
| case 's': // string |
| str = va_arg (args_copy, const char *); |
| break; |
| case 'd': // int |
| number = va_arg (args_copy, int); |
| break; |
| case 'f': // float |
| fnumber = va_arg (args_copy, double); |
| break; |
| default: |
| break; |
| } |
| } |
| va_end (args_copy); |
| va_end (args); |
| |
| return *str && number && fnumber; |
| }]])# _AC_C_C99_TEST_HEADER |
| |
| # _AC_C_C99_TEST_BODY |
| # ------------------- |
| # A C body suitable for testing for C99, assuming the corresponding header. |
| AC_DEFUN([_AC_C_C99_TEST_BODY], |
| [[ |
| // Check bool. |
| _Bool success = false; |
| |
| // Check restrict. |
| if (test_restrict ("String literal") == 0) |
| success = true; |
| char *restrict newvar = "Another string"; |
| |
| // Check varargs. |
| success &= test_varargs ("s, d' f .", "string", 65, 34.234); |
| test_varargs_macros (); |
| |
| // Check flexible array members. |
| struct incomplete_array *ia = |
| malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); |
| ia->datasize = 10; |
| for (int i = 0; i < ia->datasize; ++i) |
| ia->data[i] = i * 1.234; |
| |
| // Check named initializers. |
| struct named_init ni = { |
| .number = 34, |
| .name = L"Test wide string", |
| .average = 543.34343, |
| }; |
| |
| ni.number = 58; |
| |
| int dynamic_array[ni.number]; |
| dynamic_array[ni.number - 1] = 543; |
| |
| // work around unused variable warnings |
| return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' |
| || dynamic_array[ni.number - 1] != 543); |
| ]]) |
| |
| # _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) |
| # ---------------------------------------------------------------- |
| # If the C compiler is not in ISO C99 mode by default, try to add an |
| # option to output variable CC to make it so. This macro tries |
| # various options that select ISO C99 on some system or another. It |
| # considers the compiler to be in ISO C99 mode if it handles _Bool, |
| # // comments, flexible array members, inline, long long int, mixed |
| # code and declarations, named initialization of structs, restrict, |
| # va_copy, varargs macros, variable declarations in for loops and |
| # variable length arrays. |
| AC_DEFUN([_AC_PROG_CC_C99], |
| [_AC_C_STD_TRY([c99], |
| [_AC_C_C99_TEST_HEADER], |
| [_AC_C_C99_TEST_BODY], |
| dnl Try |
| dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) |
| dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test) |
| dnl IBM XL C -qlanglvl=extc99 |
| dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99) |
| dnl HP cc -AC99 |
| dnl Intel ICC -std=c99, -c99 (deprecated) |
| dnl IRIX -c99 |
| dnl Solaris -D_STDC_C99= |
| dnl cc's -xc99 option uses linker magic to define the external |
| dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99 |
| dnl behavior for C library functions. This is not wanted here, |
| dnl because it means that a single module compiled with -xc99 |
| dnl alters C runtime behavior for the entire program, not for |
| dnl just the module. Instead, define the (private) symbol |
| dnl _STDC_C99, which suppresses a bogus failure in <stdbool.h>. |
| dnl The resulting compiler passes the test case here, and that's |
| dnl good enough. For more, please see the thread starting at: |
| dnl https://lists.gnu.org/r/autoconf/2010-12/msg00059.html |
| dnl Tru64 -c99 |
| dnl with extended modes being tried first. |
| [[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl |
| ])# _AC_PROG_CC_C99 |
| |
| |
| # _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) |
| # ---------------------------------------------------------------- |
| # If the C compiler is not in ISO C11 mode by default, try to add an |
| # option to output variable CC to make it so. This macro tries |
| # various options that select ISO C11 on some system or another. It |
| # considers the compiler to be in ISO C11 mode if it handles _Alignas, |
| # _Alignof, _Noreturn, _Static_assert, UTF-8 string literals, |
| # duplicate typedefs, and anonymous structures and unions. |
| AC_DEFUN([_AC_PROG_CC_C11], |
| [_AC_C_STD_TRY([c11], |
| [_AC_C_C99_TEST_HEADER[ |
| // Check _Alignas. |
| char _Alignas (double) aligned_as_double; |
| char _Alignas (0) no_special_alignment; |
| extern char aligned_as_int; |
| char _Alignas (0) _Alignas (int) aligned_as_int; |
| |
| // Check _Alignof. |
| enum |
| { |
| int_alignment = _Alignof (int), |
| int_array_alignment = _Alignof (int[100]), |
| char_alignment = _Alignof (char) |
| }; |
| _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); |
| |
| // Check _Noreturn. |
| int _Noreturn does_not_return (void) { for (;;) continue; } |
| |
| // Check _Static_assert. |
| struct test_static_assert |
| { |
| int x; |
| _Static_assert (sizeof (int) <= sizeof (long int), |
| "_Static_assert does not work in struct"); |
| long int y; |
| }; |
| |
| // Check UTF-8 literals. |
| #define u8 syntax error! |
| char const utf8_literal[] = u8"happens to be ASCII" "another string"; |
| |
| // Check duplicate typedefs. |
| typedef long *long_ptr; |
| typedef long int *long_ptr; |
| typedef long_ptr long_ptr; |
| |
| // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. |
| struct anonymous |
| { |
| union { |
| struct { int i; int j; }; |
| struct { int k; long int l; } w; |
| }; |
| int m; |
| } v1; |
| ]], |
| [_AC_C_C99_TEST_BODY[ |
| v1.i = 2; |
| v1.w.k = 5; |
| _Static_assert ((offsetof (struct anonymous, i) |
| == offsetof (struct anonymous, w.k)), |
| "Anonymous union alignment botch"); |
| ]], |
| dnl Try |
| dnl GCC -std=gnu11 (unused restrictive mode: -std=c11) |
| dnl with extended modes being tried first. |
| dnl |
| dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as |
| dnl of September 2012) does not pass the C11 test. For now, try extc1x when |
| dnl compiling the C99 test instead, since it enables _Static_assert and |
| dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes |
| dnl the C11 test in some future version of IBM XL C, we'll add it here, |
| dnl preferably extc11. |
| [[-std=gnu11]], [$1], [$2])[]dnl |
| ])# _AC_PROG_CC_C11 |
| |
| |
| # AC_PROG_CC_C89 |
| # -------------- |
| # Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC, |
| # as that'd be incompatible with how Automake redefines AC_PROG_CC. See |
| # <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>. |
| AU_DEFUN([AC_PROG_CC_C89], |
| [AC_REQUIRE([AC_PROG_CC])], |
| [$0 is obsolete; use AC_PROG_CC] |
| ) |
| |
| # AC_PROG_CC_C99 |
| # -------------- |
| AU_DEFUN([AC_PROG_CC_C99], |
| [AC_REQUIRE([AC_PROG_CC])], |
| [$0 is obsolete; use AC_PROG_CC] |
| ) |
| |
| # AC_PROG_CC_STDC |
| # --------------- |
| AU_DEFUN([AC_PROG_CC_STDC], |
| [AC_REQUIRE([AC_PROG_CC])], |
| [$0 is obsolete; use AC_PROG_CC] |
| ) |
| |
| |
| # AC_C_PROTOTYPES |
| # --------------- |
| # Check if the C compiler supports prototypes, included if it needs |
| # options. |
| AC_DEFUN([AC_C_PROTOTYPES], |
| [AC_REQUIRE([AC_PROG_CC])dnl |
| if test "$ac_prog_cc_stdc" != no; then |
| AC_DEFINE(PROTOTYPES, 1, |
| [Define to 1 if the C compiler supports function prototypes.]) |
| AC_DEFINE(__PROTOTYPES, 1, |
| [Define like PROTOTYPES; this can be used by system headers.]) |
| fi |
| ])# AC_C_PROTOTYPES |
| |
| |
| # _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, |
| # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) |
| # ---------------------------------------------------------------- |
| # Check whether the C++ compiler accepts features of STANDARD (e.g |
| # `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE |
| # and TEST-BODY. If this fails, try again with each compiler option |
| # in the space-separated OPTION-LIST; if one helps, append it to CXX. |
| # If eventually successful, run ACTION-IF-AVAILABLE, else |
| # ACTION-IF-UNAVAILABLE. |
| AC_DEFUN([_AC_CXX_STD_TRY], |
| [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features]) |
| AC_LANG_PUSH(C++)dnl |
| AC_CACHE_VAL(ac_cv_prog_cxx_$1, |
| [ac_cv_prog_cxx_$1=no |
| ac_save_CXX=$CXX |
| AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) |
| for ac_arg in '' $4 |
| do |
| CXX="$ac_save_CXX $ac_arg" |
| _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg]) |
| test "x$ac_cv_prog_cxx_$1" != "xno" && break |
| done |
| rm -f conftest.$ac_ext |
| CXX=$ac_save_CXX |
| ])# AC_CACHE_VAL |
| ac_prog_cxx_stdcxx_options= |
| case "x$ac_cv_prog_cxx_$1" in |
| x) |
| AC_MSG_RESULT([none needed]) ;; |
| xno) |
| AC_MSG_RESULT([unsupported]) ;; |
| *) |
| ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1" |
| CXX=$CXX$ac_prog_cxx_stdcxx_options |
| AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;; |
| esac |
| AC_LANG_POP(C++)dnl |
| AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6]) |
| ])# _AC_CXX_STD_TRY |
| |
| # _AC_CXX_CXX98_TEST_HEADER |
| # ------------------------- |
| # A C++ header suitable for testing for CXX98. |
| AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER], |
| [[ |
| #include <algorithm> |
| #include <cstdlib> |
| #include <fstream> |
| #include <iomanip> |
| #include <iostream> |
| #include <list> |
| #include <map> |
| #include <set> |
| #include <sstream> |
| #include <stdexcept> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| namespace test { |
| typedef std::vector<std::string> string_vec; |
| typedef std::pair<int,bool> map_value; |
| typedef std::map<std::string,map_value> map_type; |
| typedef std::set<int> set_type; |
| |
| template<typename T> |
| class printer { |
| public: |
| printer(std::ostringstream& os): os(os) {} |
| void operator() (T elem) { os << elem << std::endl; } |
| private: |
| std::ostringstream& os; |
| }; |
| } |
| ]])# _AC_CXX_CXX98_TEST_HEADER |
| |
| # _AC_CXX_CXX98_TEST_BODY |
| # ----------------------- |
| # A C++ body suitable for testing for CXX98, assuming the corresponding header. |
| AC_DEFUN([_AC_CXX_CXX98_TEST_BODY], |
| [[ |
| |
| try { |
| // Basic string. |
| std::string teststr("ASCII text"); |
| teststr += " string"; |
| |
| // Simple vector. |
| test::string_vec testvec; |
| testvec.push_back(teststr); |
| testvec.push_back("foo"); |
| testvec.push_back("bar"); |
| if (testvec.size() != 3) { |
| throw std::runtime_error("vector size is not 1"); |
| } |
| |
| // Dump vector into stringstream and obtain string. |
| std::ostringstream os; |
| for (test::string_vec::const_iterator i = testvec.begin(); |
| i != testvec.end(); ++i) { |
| if (i + 1 != testvec.end()) { |
| os << teststr << '\n'; |
| } |
| } |
| // Check algorithms work. |
| std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os)); |
| std::string os_out = os.str(); |
| |
| // Test pair and map. |
| test::map_type testmap; |
| testmap.insert(std::make_pair(std::string("key"), |
| std::make_pair(53,false))); |
| |
| // Test set. |
| int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; |
| test::set_type testset(values, values + sizeof(values)/sizeof(values[0])); |
| std::list<int> testlist(testset.begin(), testset.end()); |
| std::copy(testset.begin(), testset.end(), std::back_inserter(testlist)); |
| } catch (const std::exception& e) { |
| std::cerr << "Caught exception: " << e.what() << std::endl; |
| |
| // Test fstream |
| std::ofstream of("test.txt"); |
| of << "Test ASCII text\n" << std::flush; |
| of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl; |
| of.close(); |
| } |
| std::exit(0); |
| ]]) |
| |
| # _AC_CXX_CXX11_TEST_HEADER |
| # ------------------------- |
| # A C++ header suitable for testing for CXX11. |
| AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER], |
| [[ |
| #include <deque> |
| #include <functional> |
| #include <memory> |
| #include <tuple> |
| #include <array> |
| #include <regex> |
| #include <iostream> |
| |
| namespace cxx11test |
| { |
| typedef std::shared_ptr<std::string> sptr; |
| typedef std::weak_ptr<std::string> wptr; |
| |
| typedef std::tuple<std::string,int,double> tp; |
| typedef std::array<int, 20> int_array; |
| |
| constexpr int get_val() { return 20; } |
| |
| struct testinit |
| { |
| int i; |
| double d; |
| }; |
| |
| class delegate { |
| public: |
| delegate(int n) : n(n) {} |
| delegate(): delegate(2354) {} |
| |
| virtual int getval() { return this->n; }; |
| protected: |
| int n; |
| }; |
| |
| class overridden : public delegate { |
| public: |
| overridden(int n): delegate(n) {} |
| virtual int getval() override final { return this->n * 2; } |
| }; |
| |
| class nocopy { |
| public: |
| nocopy(int i): i(i) {} |
| nocopy() = default; |
| nocopy(const nocopy&) = delete; |
| nocopy & operator=(const nocopy&) = delete; |
| private: |
| int i; |
| }; |
| } |
| ]])# _AC_CXX_CXX11_TEST_HEADER |
| |
| # _AC_CXX_CXX11_TEST_BODY |
| # ----------------------- |
| # A C++ body suitable for testing for CXX11, assuming the corresponding header. |
| AC_DEFUN([_AC_CXX_CXX11_TEST_BODY], |
| [[ |
| { |
| // Test auto and decltype |
| std::deque<int> d; |
| d.push_front(43); |
| d.push_front(484); |
| d.push_front(3); |
| d.push_front(844); |
| int total = 0; |
| for (auto i = d.begin(); i != d.end(); ++i) { total += *i; } |
| |
| auto a1 = 6538; |
| auto a2 = 48573953.4; |
| auto a3 = "String literal"; |
| |
| decltype(a2) a4 = 34895.034; |
| } |
| { |
| // Test constexpr |
| short sa[cxx11test::get_val()] = { 0 }; |
| } |
| { |
| // Test initializer lists |
| cxx11test::testinit il = { 4323, 435234.23544 }; |
| } |
| { |
| // Test range-based for and lambda |
| cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; |
| for (int &x : array) { x += 23; } |
| std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; }); |
| } |
| { |
| using cxx11test::sptr; |
| using cxx11test::wptr; |
| |
| sptr sp(new std::string("ASCII string")); |
| wptr wp(sp); |
| sptr sp2(wp); |
| } |
| { |
| cxx11test::tp tuple("test", 54, 45.53434); |
| double d = std::get<2>(tuple); |
| std::string s; |
| int i; |
| std::tie(s,i,d) = tuple; |
| } |
| { |
| static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$"); |
| std::string testmatch("Test if this string matches"); |
| bool match = std::regex_search(testmatch, filename_regex); |
| } |
| { |
| cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; |
| cxx11test::int_array::size_type size = array.size(); |
| } |
| { |
| // Test constructor delegation |
| cxx11test::delegate d1; |
| cxx11test::delegate d2(); |
| cxx11test::delegate d3(45); |
| } |
| { |
| // Test override and final |
| cxx11test::overridden o1(55464); |
| } |
| { |
| // Test nullptr |
| char *c = nullptr; |
| } |
| { |
| // Test template brackets |
| std::vector<std::pair<int,char*>> v1; |
| } |
| { |
| // Unicode literals |
| char const *utf8 = u8"UTF-8 string \u2500"; |
| char16_t const *utf16 = u"UTF-8 string \u2500"; |
| char32_t const *utf32 = U"UTF-32 string \u2500"; |
| } |
| ]]) |
| |
| # _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) |
| # ------------------------------------------------------------------- |
| |
| # If the C++ compiler is not in ISO C++98 mode by default, try to add |
| # an option to output variable CXX to make it so. This macro tries |
| # various options that select ISO C++98 on some system or another. It |
| # considers the compiler to be in ISO C++98 mode if it handles basic |
| # features of the std namespace including: string, containers (list, |
| # map, set, vector), streams (fstreams, iostreams, stringstreams, |
| # iomanip), pair, exceptions and algorithms. |
| |
| |
| AC_DEFUN([_AC_PROG_CXX_CXX98], |
| [_AC_CXX_STD_TRY([cxx98], |
| [_AC_CXX_CXX98_TEST_HEADER], |
| [_AC_CXX_CXX98_TEST_BODY], |
| dnl Try |
| dnl GCC -std=gnu++98 (unused restrictive mode: -std=c++98) |
| dnl IBM XL C -qlanglvl=extended |
| dnl HP aC++ -AA |
| dnl Intel ICC -std=gnu++98 |
| dnl Solaris N/A (default) |
| dnl Tru64 N/A (default, but -std gnu could be used) |
| dnl with extended modes being tried first. |
| [[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl |
| ])# _AC_PROG_CXX_CXX98 |
| |
| # _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) |
| # ------------------------------------------------------------------- |
| # If the C++ compiler is not in ISO CXX11 mode by default, try to add |
| # an option to output variable CXX to make it so. This macro tries |
| # various options that select ISO C++11 on some system or another. It |
| # considers the compiler to be in ISO C++11 mode if it handles all the |
| # tests from the C++98 checks, plus the following: Language features |
| # (auto, constexpr, decltype, default/deleted constructors, delegate |
| # constructors, final, initializer lists, lambda functions, nullptr, |
| # override, range-based for loops, template brackets without spaces, |
| # unicode literals) and library features (array, memory (shared_ptr, |
| # weak_ptr), regex and tuple types). |
| AC_DEFUN([_AC_PROG_CXX_CXX11], |
| [_AC_CXX_STD_TRY([cxx11], |
| [_AC_CXX_CXX11_TEST_HEADER |
| _AC_CXX_CXX98_TEST_HEADER], |
| [_AC_CXX_CXX11_TEST_BODY |
| _AC_CXX_CXX98_TEST_BODY], |
| dnl Try |
| dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants] |
| dnl IBM XL C -qlanglvl=extended0x |
| dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11) |
| dnl HP aC++ -AA |
| dnl Intel ICC -std=c++11 -std=c++0x |
| dnl Solaris N/A (no support) |
| dnl Tru64 N/A (no support) |
| dnl with extended modes being tried first. |
| [[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl |
| ])# _AC_PROG_CXX_CXX11 |
| |
| |
| ])# m4_version_prereq |