mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-16 07:43:03 +00:00
c++: don't define variant<S>, directly define semantic_type
Instead of defining yy::variant<S> and then alias yy::parser::semantic_type to variant<sizeof (union_type)>, directly define yy::parser::semantic_type. This model is more appropriate if we want to sit the storage on top of unions in C++11. * data/variant.hh (b4_variant_define): Specialize and inline the definition into... (b4_value_type_declare): Here. Define union_type here. * data/lalr1.cc: Adjust.
This commit is contained in:
@@ -178,8 +178,6 @@ m4_define([b4_shared_declarations],
|
|||||||
]b4_bison_locations_if([m4_ifndef([b4_location_file],
|
]b4_bison_locations_if([m4_ifndef([b4_location_file],
|
||||||
[b4_location_define])])[
|
[b4_location_define])])[
|
||||||
|
|
||||||
]b4_variant_if([b4_variant_define])[
|
|
||||||
|
|
||||||
/// A Bison parser.
|
/// A Bison parser.
|
||||||
class ]b4_parser_class_name[
|
class ]b4_parser_class_name[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,38 +78,45 @@ m4_define([b4_variant_includes],
|
|||||||
#endif
|
#endif
|
||||||
]])
|
]])
|
||||||
|
|
||||||
# b4_variant_define
|
|
||||||
# -----------------
|
|
||||||
# Define "variant".
|
## -------------------------- ##
|
||||||
m4_define([b4_variant_define],
|
## Adjustments for variants. ##
|
||||||
[[ /// A char[S] buffer to store and retrieve objects.
|
## -------------------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_value_type_declare
|
||||||
|
# ---------------------
|
||||||
|
# Declare semantic_type.
|
||||||
|
m4_define([b4_value_type_declare],
|
||||||
|
[[ /// A buffer to store and retrieve objects.
|
||||||
///
|
///
|
||||||
/// Sort of a variant, but does not keep track of the nature
|
/// Sort of a variant, but does not keep track of the nature
|
||||||
/// of the stored data, since that knowledge is available
|
/// of the stored data, since that knowledge is available
|
||||||
/// via the current state.
|
/// via the current parser state.
|
||||||
template <size_t S>
|
class semantic_type
|
||||||
struct variant
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
/// Type of *this.
|
/// Type of *this.
|
||||||
typedef variant<S> self_type;
|
typedef semantic_type self_type;
|
||||||
|
|
||||||
/// Empty construction.
|
/// Empty construction.
|
||||||
variant () YY_NOEXCEPT
|
semantic_type () YY_NOEXCEPT
|
||||||
: yybuffer_ ()]b4_parse_assert_if([
|
: yybuffer_ ()]b4_parse_assert_if([
|
||||||
, yytypeid_ (YY_NULLPTR)])[
|
, yytypeid_ (YY_NULLPTR)])[
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Construct and fill.
|
/// Construct and fill.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
variant (YY_RVREF (T) t)]b4_parse_assert_if([
|
semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
|
||||||
: yytypeid_ (&typeid (T))])[
|
: yytypeid_ (&typeid (T))])[
|
||||||
{
|
{
|
||||||
YYASSERT (sizeof (T) <= S);
|
YYASSERT (sizeof (T) <= size);
|
||||||
new (yyas_<T> ()) T (YY_MOVE (t));
|
new (yyas_<T> ()) T (YY_MOVE (t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destruction, allowed only if empty.
|
/// Destruction, allowed only if empty.
|
||||||
~variant () YY_NOEXCEPT
|
~semantic_type () YY_NOEXCEPT
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (!yytypeid_);
|
YYASSERT (!yytypeid_);
|
||||||
])[}
|
])[}
|
||||||
@@ -120,7 +127,7 @@ m4_define([b4_variant_define],
|
|||||||
emplace ()
|
emplace ()
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (!yytypeid_);
|
YYASSERT (!yytypeid_);
|
||||||
YYASSERT (sizeof (T) <= S);
|
YYASSERT (sizeof (T) <= size);
|
||||||
yytypeid_ = & typeid (T);])[
|
yytypeid_ = & typeid (T);])[
|
||||||
return *new (yyas_<T> ()) T ();
|
return *new (yyas_<T> ()) T ();
|
||||||
}
|
}
|
||||||
@@ -132,7 +139,7 @@ m4_define([b4_variant_define],
|
|||||||
emplace (U&& u)
|
emplace (U&& u)
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (!yytypeid_);
|
YYASSERT (!yytypeid_);
|
||||||
YYASSERT (sizeof (T) <= S);
|
YYASSERT (sizeof (T) <= size);
|
||||||
yytypeid_ = & typeid (T);])[
|
yytypeid_ = & typeid (T);])[
|
||||||
return *new (yyas_<T> ()) T (std::forward <U>(u));
|
return *new (yyas_<T> ()) T (std::forward <U>(u));
|
||||||
}
|
}
|
||||||
@@ -143,7 +150,7 @@ m4_define([b4_variant_define],
|
|||||||
emplace (const T& t)
|
emplace (const T& t)
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (!yytypeid_);
|
YYASSERT (!yytypeid_);
|
||||||
YYASSERT (sizeof (T) <= S);
|
YYASSERT (sizeof (T) <= size);
|
||||||
yytypeid_ = & typeid (T);])[
|
yytypeid_ = & typeid (T);])[
|
||||||
return *new (yyas_<T> ()) T (t);
|
return *new (yyas_<T> ()) T (t);
|
||||||
}
|
}
|
||||||
@@ -174,7 +181,7 @@ m4_define([b4_variant_define],
|
|||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (yytypeid_);
|
YYASSERT (yytypeid_);
|
||||||
YYASSERT (*yytypeid_ == typeid (T));
|
YYASSERT (*yytypeid_ == typeid (T));
|
||||||
YYASSERT (sizeof (T) <= S);])[
|
YYASSERT (sizeof (T) <= size);])[
|
||||||
return *yyas_<T> ();
|
return *yyas_<T> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +192,7 @@ m4_define([b4_variant_define],
|
|||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
YYASSERT (yytypeid_);
|
YYASSERT (yytypeid_);
|
||||||
YYASSERT (*yytypeid_ == typeid (T));
|
YYASSERT (*yytypeid_ == typeid (T));
|
||||||
YYASSERT (sizeof (T) <= S);])[
|
YYASSERT (sizeof (T) <= size);])[
|
||||||
return *yyas_<T> ();
|
return *yyas_<T> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +203,7 @@ m4_define([b4_variant_define],
|
|||||||
/// unconstructed variants: it would require some dynamic testing, which
|
/// unconstructed variants: it would require some dynamic testing, which
|
||||||
/// should not be the variant's responsibility.
|
/// should not be the variant's responsibility.
|
||||||
/// Swapping between built and (possibly) non-built is done with
|
/// Swapping between built and (possibly) non-built is done with
|
||||||
/// variant::move ().
|
/// self_type::move ().
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void
|
void
|
||||||
swap (self_type& other) YY_NOEXCEPT
|
swap (self_type& other) YY_NOEXCEPT
|
||||||
@@ -253,7 +260,7 @@ m4_define([b4_variant_define],
|
|||||||
private:
|
private:
|
||||||
/// Prohibit blind copies.
|
/// Prohibit blind copies.
|
||||||
self_type& operator= (const self_type&);
|
self_type& operator= (const self_type&);
|
||||||
variant (const self_type&);
|
semantic_type (const self_type&);
|
||||||
|
|
||||||
/// Accessor to raw memory as \a T.
|
/// Accessor to raw memory as \a T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -273,12 +280,20 @@ m4_define([b4_variant_define],
|
|||||||
return static_cast<const T*> (yyp);
|
return static_cast<const T*> (yyp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An auxiliary type to compute the largest semantic type.
|
||||||
|
union union_type
|
||||||
|
{]b4_type_foreach([b4_char_sizeof])[ };
|
||||||
|
|
||||||
|
/// The size of the largest semantic type.
|
||||||
|
enum { size = sizeof (union_type) };
|
||||||
|
|
||||||
|
/// A buffer to store semantic values.
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
/// Strongest alignment constraints.
|
/// Strongest alignment constraints.
|
||||||
long double yyalign_me;
|
long double yyalign_me;
|
||||||
/// A buffer large enough to store any of the semantic values.
|
/// A buffer large enough to store any of the semantic values.
|
||||||
char yyraw[S];
|
char yyraw[size];
|
||||||
} yybuffer_;]b4_parse_assert_if([
|
} yybuffer_;]b4_parse_assert_if([
|
||||||
|
|
||||||
/// Whether the content is built: if defined, the name of the stored type.
|
/// Whether the content is built: if defined, the name of the stored type.
|
||||||
@@ -287,24 +302,6 @@ m4_define([b4_variant_define],
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
## -------------------------- ##
|
|
||||||
## Adjustments for variants. ##
|
|
||||||
## -------------------------- ##
|
|
||||||
|
|
||||||
|
|
||||||
# b4_value_type_declare
|
|
||||||
# ---------------------
|
|
||||||
# Declare semantic_type.
|
|
||||||
m4_define([b4_value_type_declare],
|
|
||||||
[[ /// An auxiliary type to compute the largest semantic type.
|
|
||||||
union union_type
|
|
||||||
{]b4_type_foreach([b4_char_sizeof])[};
|
|
||||||
|
|
||||||
/// Symbol semantic values.
|
|
||||||
typedef variant<sizeof (union_type)> semantic_type;][]dnl
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
# How the semantic value is extracted when using variants.
|
# How the semantic value is extracted when using variants.
|
||||||
|
|
||||||
# b4_symbol_value(VAL, [TYPE])
|
# b4_symbol_value(VAL, [TYPE])
|
||||||
|
|||||||
Reference in New Issue
Block a user