comparison m4/prog_cxx.m4 @ 21304:0cf6c08cb252

configure.ac: check support for C11 and C++11 (patch #8906) * configure.ac: two new checks for support of C++11 and C11 versions of the standard and to add required flags to CXX and CC. These need to be done before AC_PROG_CPP and AC_PROG_CXXPP since the later will make use of the defined CXX and CC. * m4/prog_c.m4, m4/prog_cxx.m4: added files for OCTAVE_PROG_CC_C11 and OCTAVE_PROG_CXX_CXX11 which are copied from autoconf source tree implementations of _AC_PROG_CC_C11 and _AC_PROG_CXX_CXX11.
author Carnë Draug <carandraug@octave.org>
date Thu, 18 Feb 2016 16:20:49 +0000
parents
children fd4ff31b3eed
comparison
equal deleted inserted replaced
21303:325e04c63f8c 21304:0cf6c08cb252
1 # Copyright (C) 2001-2016 Free Software Foundation, Inc.
2 #
3 #
4 # This is pretty much copy and paste of the unreleased autoconf macros
5 # (where it is named AC_PROG_CC_C11). Once we are dependent on
6 # autoconf version with that macro, we can simply change to use that
7 # one instead. Copied from autoconf commit 04be2b7a (2016/02/06)
8 #
9 #
10 # This file is part of Autoconf. This program is free
11 # software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the
13 # Free Software Foundation, either version 3 of the License, or
14 # (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, see <http://www.gnu.org/licenses/>.
23
24 # OCTAVE_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
25 # -------------------------------------------------------------------
26 # If the C++ compiler is not in ISO CXX11 mode by default, try to add
27 # an option to output variable CXX to make it so. This macro tries
28 # various options that select ISO C++11 on some system or another. It
29 # considers the compiler to be in ISO C++11 mode if it handles all the
30 # tests from the C++98 checks, plus the following: Language features
31 # (auto, constexpr, decltype, default/deleted constructors, delegate
32 # constructors, final, initialiser lists, lambda functions, nullptr,
33 # override, range-based for loops, template brackets without spaces,
34 # unicode literals) and library features (array, memory (shared_ptr,
35 # weak_ptr), regex and tuple types).
36 AC_DEFUN([OCTAVE_PROG_CXX_CXX11],
37 [OCTAVE_CXX_STD_TRY([cxx11],
38 [OCTAVE_CXX_CXX11_TEST_HEADER
39 OCTAVE_CXX_CXX98_TEST_HEADER],
40 [OCTAVE_CXX_CXX11_TEST_BODY
41 OCTAVE_CXX_CXX98_TEST_BODY],
42 dnl Try
43 dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants]
44 dnl IBM XL C -qlanglvl=extended0x
45 dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11)
46 dnl HP aC++ -AA
47 dnl Intel ICC -std=c++11 -std=c++0x
48 dnl Solaris N/A (no support)
49 dnl Tru64 N/A (no support)
50 dnl with extended modes being tried first.
51 [[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl
52 ])# OCTAVE_PROG_CXX_CXX11
53
54
55 # OCTAVE_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
56 # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
57 # ----------------------------------------------------------------
58 # Check whether the C++ compiler accepts features of STANDARD (e.g
59 # `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE
60 # and TEST-BODY. If this fails, try again with each compiler option
61 # in the space-separated OPTION-LIST; if one helps, append it to CXX.
62 # If eventually successful, run ACTION-IF-AVAILABLE, else
63 # ACTION-IF-UNAVAILABLE.
64 AC_DEFUN([OCTAVE_CXX_STD_TRY],
65 [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
66 AC_LANG_PUSH(C++)dnl
67 AC_CACHE_VAL(ac_cv_prog_cxx_$1,
68 [ac_cv_prog_cxx_$1=no
69 ac_save_CXX=$CXX
70 AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
71 for ac_arg in '' $4
72 do
73 CXX="$ac_save_CXX $ac_arg"
74 _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg])
75 test "x$ac_cv_prog_cxx_$1" != "xno" && break
76 done
77 rm -f conftest.$ac_ext
78 CXX=$ac_save_CXX
79 ])# AC_CACHE_VAL
80 ac_prog_cxx_stdcxx_options=
81 case "x$ac_cv_prog_cxx_$1" in
82 x)
83 AC_MSG_RESULT([none needed]) ;;
84 xno)
85 AC_MSG_RESULT([unsupported]) ;;
86 *)
87 ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1"
88 CXX=$CXX$ac_prog_cxx_stdcxx_options
89 AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;;
90 esac
91 AC_LANG_POP(C++)dnl
92 AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6])
93 ])# OCTAVE_CXX_STD_TRY
94
95 # OCTAVE_CXX_CXX98_TEST_HEADER
96 # -------------------------
97 # A C++ header suitable for testing for CXX98.
98 AC_DEFUN([OCTAVE_CXX_CXX98_TEST_HEADER],
99 [[
100 #include <algorithm>
101 #include <cstdlib>
102 #include <fstream>
103 #include <iomanip>
104 #include <iostream>
105 #include <list>
106 #include <map>
107 #include <set>
108 #include <sstream>
109 #include <stdexcept>
110 #include <string>
111 #include <utility>
112 #include <vector>
113
114 namespace test {
115 typedef std::vector<std::string> string_vec;
116 typedef std::pair<int,bool> map_value;
117 typedef std::map<std::string,map_value> map_type;
118 typedef std::set<int> set_type;
119
120 template<typename T>
121 class printer {
122 public:
123 printer(std::ostringstream& os): os(os) {}
124 void operator() (T elem) { os << elem << std::endl; }
125 private:
126 std::ostringstream& os;
127 };
128 }
129 ]])# OCTAVE_CXX_CXX98_TEST_HEADER
130
131 # OCTAVE_CXX_CXX98_TEST_BODY
132 # -----------------------
133 # A C++ body suitable for testing for CXX98, assuming the corresponding header.
134 AC_DEFUN([OCTAVE_CXX_CXX98_TEST_BODY],
135 [[
136
137 try {
138 // Basic string.
139 std::string teststr("ASCII text");
140 teststr += " string";
141
142 // Simple vector.
143 test::string_vec testvec;
144 testvec.push_back(teststr);
145 testvec.push_back("foo");
146 testvec.push_back("bar");
147 if (testvec.size() != 3) {
148 throw std::runtime_error("vector size is not 1");
149 }
150
151 // Dump vector into stringstream and obtain string.
152 std::ostringstream os;
153 for (test::string_vec::const_iterator i = testvec.begin();
154 i != testvec.end(); ++i) {
155 if (i + 1 != testvec.end()) {
156 os << teststr << '\n';
157 }
158 }
159 // Check algorithms work.
160 std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os));
161 std::string os_out = os.str();
162
163 // Test pair and map.
164 test::map_type testmap;
165 testmap.insert(std::make_pair(std::string("key"),
166 std::make_pair(53,false)));
167
168 // Test set.
169 int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
170 test::set_type testset(values, values + sizeof(values)/sizeof(values[0]));
171 std::list<int> testlist(testset.begin(), testset.end());
172 std::copy(testset.begin(), testset.end(), std::back_inserter(testlist));
173 } catch (const std::exception& e) {
174 std::cerr << "Caught exception: " << e.what() << std::endl;
175
176 // Test fstream
177 std::ofstream of("test.txt");
178 of << "Test ASCII text\n" << std::flush;
179 of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl;
180 of.close();
181 }
182 std::exit(0);
183 ]])
184
185
186 # OCTAVE_CXX_CXX11_TEST_HEADER
187 # -------------------------
188 # A C++ header suitable for testing for CXX11.
189 AC_DEFUN([OCTAVE_CXX_CXX11_TEST_HEADER],
190 [[
191 #include <deque>
192 #include <functional>
193 #include <memory>
194 #include <tuple>
195 #include <array>
196 #include <regex>
197 #include <iostream>
198
199 namespace cxx11test
200 {
201 typedef std::shared_ptr<std::string> sptr;
202 typedef std::weak_ptr<std::string> wptr;
203
204 typedef std::tuple<std::string,int,double> tp;
205 typedef std::array<int, 20> int_array;
206
207 constexpr int get_val() { return 20; }
208
209 struct testinit
210 {
211 int i;
212 double d;
213 };
214
215 class delegate {
216 public:
217 delegate(int n) : n(n) {}
218 delegate(): delegate(2354) {}
219
220 virtual int getval() { return this->n; };
221 protected:
222 int n;
223 };
224
225 class overridden : public delegate {
226 public:
227 overridden(int n): delegate(n) {}
228 virtual int getval() override final { return this->n * 2; }
229 };
230
231 class nocopy {
232 public:
233 nocopy(int i): i(i) {}
234 nocopy() = default;
235 nocopy(const nocopy&) = delete;
236 nocopy & operator=(const nocopy&) = delete;
237 private:
238 int i;
239 };
240 }
241 ]])# OCTAVE_CXX_CXX11_TEST_HEADER
242
243 # OCTAVE_CXX_CXX11_TEST_BODY
244 # -----------------------
245 # A C++ body suitable for testing for CXX11, assuming the corresponding header.
246 AC_DEFUN([OCTAVE_CXX_CXX11_TEST_BODY],
247 [[
248 {
249 // Test auto and decltype
250 std::deque<int> d;
251 d.push_front(43);
252 d.push_front(484);
253 d.push_front(3);
254 d.push_front(844);
255 int total = 0;
256 for (auto i = d.begin(); i != d.end(); ++i) { total += *i; }
257
258 auto a1 = 6538;
259 auto a2 = 48573953.4;
260 auto a3 = "String literal";
261
262 decltype(a2) a4 = 34895.034;
263 }
264 {
265 // Test constexpr
266 short sa[cxx11test::get_val()] = { 0 };
267 }
268 {
269 // Test initialiser lists
270 cxx11test::testinit il = { 4323, 435234.23544 };
271 }
272 {
273 // Test range-based for and lambda
274 cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
275 for (int &x : array) { x += 23; }
276 std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; });
277 }
278 {
279 using cxx11test::sptr;
280 using cxx11test::wptr;
281
282 sptr sp(new std::string("ASCII string"));
283 wptr wp(sp);
284 sptr sp2(wp);
285 }
286 {
287 cxx11test::tp tuple("test", 54, 45.53434);
288 double d = std::get<2>(tuple);
289 std::string s;
290 int i;
291 std::tie(s,i,d) = tuple;
292 }
293 {
294 static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$");
295 std::string testmatch("Test if this string matches");
296 bool match = std::regex_search(testmatch, filename_regex);
297 }
298 {
299 cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
300 cxx11test::int_array::size_type size = array.size();
301 }
302 {
303 // Test constructor delegation
304 cxx11test::delegate d1;
305 cxx11test::delegate d2();
306 cxx11test::delegate d3(45);
307 }
308 {
309 // Test override and final
310 cxx11test::overridden o1(55464);
311 }
312 {
313 // Test nullptr
314 char *c = nullptr;
315 }
316 {
317 // Test template brackets
318 std::vector<std::pair<int,char*>> v1;
319 }
320 {
321 // Unicode literals
322 char *utf8 = u8"UTF-8 string \u2500";
323 char16_t *utf16 = u"UTF-8 string \u2500";
324 char32_t *utf32 = U"UTF-32 string \u2500";
325 }
326 ]])