[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
c++: check that emplace for rvalues works
From: |
Akim Demaille |
Subject: |
c++: check that emplace for rvalues works |
Date: |
Sun, 21 Oct 2018 09:48:00 +0200 |
commit 07a4b32f4dbb92eb0aad110cdf8060ab65dae49a
Author: Akim Demaille <address@hidden>
Date: Sat Oct 20 19:42:25 2018 +0200
c++: check that emplace for rvalues works
See the previous commit.
* tests/local.at (AT_REQUIRE_CXX_VERSION): New.
* tests/types.at (api.value.type): Check emplace in C++14.
diff --git a/tests/local.at b/tests/local.at
index 3bcb8357..0b4231f9 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -138,7 +138,7 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
# This sucks hard, GNU M4 should really provide M5-like $$1.
m4_define([_AT_BISON_OPTION_PUSHDEFS],
[m4_if([$1$2], $[1]$[2], [],
- [m4_fatal([$0: Invalid arguments: address@hidden)])dnl
+ [m4_fatal([$0: invalid arguments: address@hidden)])dnl
m4_pushdef([AT_AUTOMOVE_IF],
[m4_bmatch([$3], [%define api\.value\.automove], [$1], [$2])])
m4_pushdef([AT_DEFINES_IF],
@@ -904,6 +904,33 @@ AT_PARSER_CHECK([./c-and-cxx])
])
+# AT_REQUIRE_CXX_VERSION(STD)
+# ---------------------------
+# Skip unless this compiler supports at least C++ STD (e.g., "11",
+# "14", etc.).
+m4_define([AT_REQUIRE_CXX_VERSION],
+[AT_DATA([check.cc],
+[[int main ()
+{
+#if __cplusplus < ]m4_case([$1],
+ [98], [199711],
+ [03], [199711],
+ [11], [201103],
+ [14], [201402],
+ [17], [201703],
+ [2a], [201709],
+ [m4_fatal([$0: invalid arguments: address@hidden)])[
+ return 77;
+#else
+ return 0;
+#endif
+}
+]])
+AT_COMPILE_CXX([check])
+AT_CHECK([@&address@hidden/check])
+])
+
+
# AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
# ------------------------------------
# Check that we can expect exceptions to be handled properly.
diff --git a/tests/types.at b/tests/types.at
index 27553726..e31af74b 100644
--- a/tests/types.at
+++ b/tests/types.at
@@ -66,14 +66,19 @@ AT_CLEANUP
# $3: PARSER-ACTION,
# $4: INPUT,
# $5: SCANNER-ACTION,
-# $6: RESULT)
+# $6: RESULT,
+# $7: REQUIREMENT)
# --------------------------------------
# Compile the grammar and check the expected result.
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
+#
+# Use REQUIREMENT e.g. skip the test if the compiler does not meet the
+# requirements.
m4_pushdef([_AT_TEST],
[
AT_SETUP([$1])
AT_KEYWORDS([api.value.type])
+$7
AT_BISON_OPTION_PUSHDEFS([%debug $1 $2])
AT_DATA_GRAMMAR([test.y],
[[%debug
@@ -100,8 +105,9 @@ start: $3;
]])
AT_FULL_COMPILE([[test]])
-AT_PARSER_CHECK([./test], 0, [$6
-], [stderr])
+AT_PARSER_CHECK([[./test]], 0, [[$6
+]])
+
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
@@ -111,7 +117,8 @@ AT_CLEANUP
# $3: PARSER-ACTION,
# $4: INPUT,
# $5: SCANNER-ACTION,
-# $6: RESULT)
+# $6: RESULT,
+# $7: REQUIREMENT)
# --------------------------------------
# Check with and without %defines, to avoid regressions. It turns out
# that in that case yacc.c calls the set-up of the %union twice,
@@ -121,8 +128,8 @@ AT_CLEANUP
# a second time doubled the side-effects and resulted in a double
# definition of the union members.
m4_pushdef([AT_TEST],
-[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6])
- _AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6])
+[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6], [$7])
+ _AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6], [$7])
])
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
@@ -248,17 +255,35 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc],
[glr.cc]],
# A Bison-defined variant, for lalr1.cc only.
m4_if(b4_skel, [lalr1.cc], [
- AT_TEST([%skeleton "]b4_skel["
- %define api.value.type variant],
- [%token <int> '1';
- %token <std::string> '2';],
- ['1' '2' { std::cout << $1 << ", " << $2 << '\n'; }],
- ["12"],
- [if (res == '1')
- AT_VAL.build (10);
- else if (res == '2')
- AT_VAL.build<std::string> ("two");],
- [10, two])])
+ AT_TEST([%skeleton "]b4_skel["
+ %define api.value.type variant],
+ [%token <int> '1';
+ %token <std::string> '2';],
+ ['1' '2' { std::cout << $1 << ", " << $2 << '\n'; }],
+ ["12"],
+ [if (res == '1')
+ AT_VAL.build (10);
+ else if (res == '2')
+ AT_VAL.build<std::string> ("two");],
+ [10, two])
+
+ # Move-only types.
+ AT_TEST([%skeleton "]b4_skel["
+ %code requires { #include <memory> }
+ %define api.value.type variant],
+ [[%token <std::unique_ptr<int>> '1';
+ %token <std::unique_ptr<std::string>> '2';]],
+ ['1' '2' { std::cout << *$1 << ", " << *$2 << '\n'; }],
+ ["12"],
+ [[if (res == '1')
+ ]AT_VAL[.emplace <std::unique_ptr<int>>
+ (std::make_unique <int> (10));
+ else if (res == '2')
+ ]AT_VAL[.emplace <std::unique_ptr<std::string>>
+ (std::make_unique <std::string> ("two"));]],
+ [10, two],
+ [AT_REQUIRE_CXX_VERSION(14)])])
+ ])
])
m4_popdef([AT_TEST])
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- c++: check that emplace for rvalues works,
Akim Demaille <=