mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-20 09:43:03 +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
|
until it sees the '='. So we notate the two possible reductions to
|
||||||
indicate that each conflicts in one rule.
|
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 POSIX Yacc compatibility warnings
|
||||||
|
|
||||||
More Bison specific directives are now reported with -y or -Wyacc. This
|
More Bison specific directives are now reported with -y or -Wyacc. This
|
||||||
|
|||||||
@@ -121,6 +121,18 @@ m4_define([b4_value_type_declare],
|
|||||||
YYASSERT (!yytypeid_);
|
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.
|
/// Instantiate an empty \a T in here.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T&
|
T&
|
||||||
@@ -132,18 +144,6 @@ m4_define([b4_value_type_declare],
|
|||||||
return *new (yyas_<T> ()) T ();
|
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.
|
/// Instantiate a \a T in here from \a t.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T&
|
T&
|
||||||
|
|||||||
@@ -11088,20 +11088,17 @@ in midrule actions. It is mandatory to use typed midrule actions
|
|||||||
(@pxref{Typed Midrule Actions}).
|
(@pxref{Typed Midrule Actions}).
|
||||||
|
|
||||||
@deftypemethod {semantic_type} {T&} emplace<T> ()
|
@deftypemethod {semantic_type} {T&} emplace<T> ()
|
||||||
Initialize, but leave empty. Return a reference to where the actual value
|
@deftypemethodx {semantic_type} {T&} emplace<T> (const T& @var{t})
|
||||||
may be stored. Requires that the variant was not initialized yet.
|
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
|
@end deftypemethod
|
||||||
|
|
||||||
@deftypemethod {semantic_type} {T&} emplace<T> (const T& @var{t})
|
@deftypemethod {semantic_type} {T&} emplace<T, U> (U&&... @var{u})
|
||||||
Initialize, and copy-construct from @var{t}. Available in C++98/C++03 only.
|
Available in C++11 and later only. Build a variant of type @code{T} from
|
||||||
|
the variadic forwarding references @var{u...}.
|
||||||
@end deftypemethod
|
@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
|
@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
|
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
|
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"));],
|
AT_VAL.build (std::make_pair<std::string, std::string> ("two", "deux"));],
|
||||||
[10:11, two:deux])
|
[10:11, two:deux])
|
||||||
|
|
||||||
# Move-only types.
|
# Move-only types, and variadic emplace.
|
||||||
AT_TEST([%skeleton "]b4_skel["
|
AT_TEST([%skeleton "]b4_skel["
|
||||||
%code requires { #include <memory> }
|
%code requires { #include <memory> }
|
||||||
%define api.value.type variant],
|
%define api.value.type variant],
|
||||||
[[%token <std::unique_ptr<int>> '1';
|
[[%token <std::unique_ptr<int>> '1';
|
||||||
%token <std::unique_ptr<std::string>> '2';]],
|
%token <std::pair<int, int>> '2';]],
|
||||||
['1' '2' { std::cout << *$1 << ", " << *$2 << '\n'; }],
|
['1' '2' { std::cout << *$1 << ", "
|
||||||
|
<< $2.first << ", "
|
||||||
|
<< $2.second << '\n'; }],
|
||||||
["12"],
|
["12"],
|
||||||
[[if (res == '1')
|
[[if (res == '1')
|
||||||
]AT_VAL[.emplace <std::unique_ptr<int>>
|
]AT_VAL[.emplace <std::unique_ptr<int>>
|
||||||
(std::make_unique <int> (10));
|
(std::make_unique <int> (10));
|
||||||
else if (res == '2')
|
else if (res == '2')
|
||||||
]AT_VAL[.emplace <std::unique_ptr<std::string>>
|
]AT_VAL[.emplace <std::pair<int, int>> (21, 22);]],
|
||||||
(std::make_unique <std::string> ("two"));]],
|
[10, 21, 22],
|
||||||
[10, two],
|
|
||||||
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])])
|
[AT_REQUIRE_CXX_STD(14, [echo "$at_std not supported"; continue])])])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|||||||
Reference in New Issue
Block a user