1# bison-cxx-std.m4 serial 1 2 3# Copyright (C) 2018-2021 Free Software Foundation, Inc. 4 5# This file is free software; the Free Software Foundation 6# gives unlimited permission to copy and/or distribute it, 7# with or without modifications, as long as this notice is preserved. 8 9m4_define([_BISON_CXXSTD_98_snippet], 10[#include <vector> 11 12typedef std::vector<int> ints; 13]) 14 15m4_define([_BISON_CXXSTD_03_snippet], 16[]) 17 18m4_define([_BISON_CXXSTD_11_snippet], 19[#include <algorithm> 20#include <memory> 21#include <set> 22#include <sstream> 23#include <string> 24 25 // C++11 26 template <typename T> 27 struct check 28 { 29 static_assert(sizeof(int) <= sizeof(T), "not big enough"); 30 }; 31 32 using right_angle_brackets = check<check<bool>>; 33 34 auto f = std::make_shared<std::string>("shared_ptr"); 35 36 int a; 37 decltype(a) b; 38 39 typedef check<int> check_type; 40 check_type c; 41 check_type&& cr = static_cast<check_type&&>(c); 42 43 auto d = a; 44 45 // Some versions of libstdc++ do not support std::set::emplace. 46 void foo() 47 { 48 std::set<int> is; 49 is.emplace(42); 50 } 51 52 // Clang++ 3.5, for a while, was unable to process properly 53 // the for-loop because its variable, r, is a typedef... 54 // It failed as follows: 55 // 56 // error: unexpected ':' in nested name specifier; did you mean '::'? 57 // for (auto r: std::set<int>{1, 2}) 58 // ^ 59 // :: 60 using r = std::set<int>; 61 void bar() 62 { 63 for (int r: std::set<int>{1, 2}) 64 continue; 65 } 66 67 // GCC 4.8.2 on Solaris 11.3 does not support to_string. 68 auto e = std::to_string(42); 69]) 70 71m4_define([_BISON_CXXSTD_14_snippet], 72[ // C++14 73 void mismatch() 74 { 75 using ints = std::vector<int>; 76 auto v1 = ints{1, 2, 3}; 77 auto v2 = ints{1, 2}; 78 std::mismatch(std::begin(v1), std::end(v1), 79 std::begin(v2), std::end(v2)); 80 } 81]) 82 83m4_define([_BISON_CXXSTD_17_snippet], 84[ // C++17 85 namespace ns1::ns2::ns3 {} 86 87#include <optional> 88 auto opt_string = std::optional<std::string>{}; 89 auto out = std::ostringstream{}; 90]) 91 92m4_define([_BISON_CXXSTD_2A_snippet], 93[ // C++2A 94]) 95 96 97m4_define([_BISON_CXXSTD_testbody(98)], 98[AC_LANG_PROGRAM([ 99_BISON_CXXSTD_98_snippet 100])]) 101 102m4_define([_BISON_CXXSTD_testbody(03)], 103[AC_LANG_PROGRAM([ 104_BISON_CXXSTD_98_snippet 105_BISON_CXXSTD_03_snippet 106])]) 107 108m4_define([_BISON_CXXSTD_testbody(11)], 109[AC_LANG_PROGRAM([ 110_BISON_CXXSTD_98_snippet 111_BISON_CXXSTD_03_snippet 112_BISON_CXXSTD_11_snippet 113])]) 114 115m4_define([_BISON_CXXSTD_testbody(14)], 116[AC_LANG_PROGRAM([ 117_BISON_CXXSTD_98_snippet 118_BISON_CXXSTD_03_snippet 119_BISON_CXXSTD_11_snippet 120_BISON_CXXSTD_14_snippet 121])]) 122 123m4_define([_BISON_CXXSTD_testbody(17)], 124[AC_LANG_PROGRAM([ 125_BISON_CXXSTD_98_snippet 126_BISON_CXXSTD_03_snippet 127_BISON_CXXSTD_11_snippet 128_BISON_CXXSTD_14_snippet 129_BISON_CXXSTD_17_snippet 130])]) 131 132m4_define([_BISON_CXXSTD_testbody(2a)], 133[AC_LANG_PROGRAM([ 134_BISON_CXXSTD_98_snippet 135_BISON_CXXSTD_03_snippet 136_BISON_CXXSTD_11_snippet 137_BISON_CXXSTD_14_snippet 138_BISON_CXXSTD_17_snippet 139_BISON_CXXSTD_2A_snippet 140])]) 141 142 143m4_define([_BISON_CXXSTD_testbody], 144[m4_ifdef([$0($1)], 145 [m4_indir([$0($1)], m4_shift2($@))], 146 [m4_fatal([$0: unknown C++ standard: $1])])]) 147 148 149# BISON_CXXSTD(STD) 150# ----------------- 151# Check whether the C++ compiler support STD (11, 98, 2a, etc.). 152# If it does, AC_SUBST 'CXX<STD>_CXXFLAGS' to the corresponding flags. 153AC_DEFUN([BISON_CXXSTD], 154[AC_REQUIRE([AC_PROG_CXX]) 155AC_LANG_PUSH([C++]) 156for f in '-std=c++$1' '-std=c++$1 -stdlib=libc++' 157do 158 BISON_CHECK_COMPILER_FLAG([$f], 159 [AC_SUBST(m4_toupper([CXX$1_CXXFLAGS]), [$f]) break], 160 [], [], 161 [_BISON_CXXSTD_testbody($1)]) 162done 163AC_LANG_POP([C++]) 164]) 165