mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
C++: support variadic emplace
Suggested by Askar Safin. http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00006.html * data/variant.hh: Implement. * tests/types.at: Check. * doc/bison.texi: Document.
This commit is contained in:
16
NEWS
16
NEWS
@@ -100,6 +100,22 @@ GNU Bison NEWS
|
||||
until it sees the '='. So we notate the two possible reductions to
|
||||
indicate that each conflicts in one rule.
|
||||
|
||||
*** C++: Variadic emplace
|
||||
|
||||
If your application requires C++11, you may now use a variadic emplace for
|
||||
semantic values:
|
||||
|
||||
%define api.value.type variant
|
||||
%token <std::pair<int, int>> PAIR
|
||||
|
||||
in your scanner:
|
||||
|
||||
int yylex (parser::semantic_type *lvalp)
|
||||
{
|
||||
lvalp->emplace <std::pair<int, int>> (1, 2);
|
||||
return parser::token::PAIR;
|
||||
}
|
||||
|
||||
*** More POSIX Yacc compatibility warnings
|
||||
|
||||
More Bison specific directives are now reported with -y or -Wyacc. This
|
||||
|
||||
@@ -121,6 +121,18 @@ m4_define([b4_value_type_declare],
|
||||
YYASSERT (!yytypeid_);
|
||||
])[}
|
||||
|
||||
# if 201103L <= YY_CPLUSPLUS
|
||||
/// Instantiate a \a T in here from \a t.
|
||||
template <typename T, typename... U>
|
||||
T&
|
||||
emplace (U&&... u)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytypeid_);
|
||||
YYASSERT (sizeof (T) <= size);
|
||||
yytypeid_ = & typeid (T);])[
|
||||
return *new (yyas_<T> ()) T (std::forward <U>(u)...);
|
||||
}
|
||||
# else
|
||||
/// Instantiate an empty \a T in here.
|
||||
template <typename T>
|
||||
T&
|
||||
@@ -132,18 +144,6 @@ m4_define([b4_value_type_declare],
|
||||
return *new (yyas_<T> ()) T ();
|
||||
}
|
||||
|
||||
# if 201103L <= YY_CPLUSPLUS
|
||||
/// Instantiate a \a T in here from \a t.
|
||||
template <typename T, typename U>
|
||||
T&
|
||||
emplace (U&& u)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytypeid_);
|
||||
YYASSERT (sizeof (T) <= size);
|
||||
yytypeid_ = & typeid (T);])[
|
||||
return *new (yyas_<T> ()) T (std::forward <U>(u));
|
||||
}
|
||||
# else
|
||||
/// Instantiate a \a T in here from \a t.
|
||||
template <typename T>
|
||||
T&
|
||||
|
||||
@@ -11088,20 +11088,17 @@ in midrule actions. It is mandatory to use typed midrule actions
|
||||
(@pxref{Typed Midrule Actions}).
|
||||
|
||||
@deftypemethod {semantic_type} {T&} emplace<T> ()
|
||||
Initialize, but leave empty. Return a reference to where the actual value
|
||||
may be stored. Requires that the variant was not initialized yet.
|
||||
@deftypemethodx {semantic_type} {T&} emplace<T> (const T& @var{t})
|
||||
Available in C++98/C++03 only. Default construct/copy-construct from
|
||||
@var{t}. Return a reference to where the actual value may be stored.
|
||||
Requires that the variant was not initialized yet.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {semantic_type} {T&} emplace<T> (const T& @var{t})
|
||||
Initialize, and copy-construct from @var{t}. Available in C++98/C++03 only.
|
||||
@deftypemethod {semantic_type} {T&} emplace<T, U> (U&&... @var{u})
|
||||
Available in C++11 and later only. Build a variant of type @code{T} from
|
||||
the variadic forwarding references @var{u...}.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {semantic_type} {T&} emplace<T, U> (U&& @var{u})
|
||||
Build a variant of type @code{T} from the forwarding reference @var{u}.
|
||||
Available in C++11 and later only.
|
||||
@end deftypemethod
|
||||
|
||||
|
||||
@strong{Warning}: We do not use Boost.Variant, for two reasons. First, it
|
||||
appeared unacceptable to require Boost on the user's machine (i.e., the
|
||||
machine on which the generated parser will be compiled, not the machine on
|
||||
|
||||
@@ -288,21 +288,22 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
AT_VAL.build (std::make_pair<std::string, std::string> ("two", "deux"));],
|
||||
[10:11, two:deux])
|
||||
|
||||
# Move-only types.
|
||||
# Move-only types, and variadic emplace.
|
||||
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'; }],
|
||||
%token <std::pair<int, int>> '2';]],
|
||||
['1' '2' { std::cout << *$1 << ", "
|
||||
<< $2.first << ", "
|
||||
<< $2.second << '\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_VAL[.emplace <std::pair<int, int>> (21, 22);]],
|
||||
[10, 21, 22],
|
||||
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])])
|
||||
])
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user