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:
Akim Demaille
2018-12-01 18:27:41 +01:00
parent 7d823c505e
commit e76a934853
2 changed files with 36 additions and 41 deletions

View File

@@ -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[
{ {

View File

@@ -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])