Mercurial > octave
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 ]]) |