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