mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 00:33:03 +00:00
variant: more assertions
Equip variants with more checking code. Provide a means to request includes. * data/variant.hh (b4_variant_includes): New. * data/lalr1.cc: Use it. * data/variant.hh (variant::built): Define at the end, as a private member. (variant::tname): New. Somewhat makes "built" useless, but let's keep both for a start, in case using "typeinfo" is considered unacceptable in some environments. Fix some formatting issues.
This commit is contained in:
@@ -139,6 +139,7 @@ m4_define([b4_shared_declarations],
|
|||||||
# include <string>]b4_defines_if([[
|
# include <string>]b4_defines_if([[
|
||||||
# include "stack.hh"
|
# include "stack.hh"
|
||||||
]b4_bison_locations_if([[# include "location.hh"]])])[
|
]b4_bison_locations_if([[# include "location.hh"]])])[
|
||||||
|
]b4_variant_if([b4_variant_includes])[
|
||||||
|
|
||||||
]b4_YYDEBUG_define[
|
]b4_YYDEBUG_define[
|
||||||
|
|
||||||
|
|||||||
@@ -74,26 +74,37 @@ m4_map([b4_char_sizeof_], [$@])dnl
|
|||||||
])])
|
])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_variant_includes
|
||||||
|
# -------------------
|
||||||
|
# The needed includes for variants support.
|
||||||
|
m4_define([b4_variant_includes],
|
||||||
|
[b4_parse_assert_if([[#include <typeinfo>]])[
|
||||||
|
#ifndef YYASSERT
|
||||||
|
# include <cassert>
|
||||||
|
# define YYASSERT assert
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
|
||||||
# b4_variant_define
|
# b4_variant_define
|
||||||
# -----------------
|
# -----------------
|
||||||
# Define "variant".
|
# Define "variant".
|
||||||
m4_define([b4_variant_define],
|
m4_define([b4_variant_define],
|
||||||
[[
|
[[ /// A char[S] buffer to store and retrieve objects.
|
||||||
/// A char[S] 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 state.
|
||||||
template <size_t S>
|
template <size_t S>
|
||||||
struct variant
|
struct variant
|
||||||
{]b4_parse_assert_if([
|
{
|
||||||
/// Whether something is contained.
|
/// Type of *this.
|
||||||
bool built;
|
typedef variant<S> self_type;
|
||||||
])[
|
|
||||||
/// Empty construction.
|
/// Empty construction.
|
||||||
inline
|
inline
|
||||||
variant ()]b4_parse_assert_if([
|
variant ()]b4_parse_assert_if([
|
||||||
: built (false)])[
|
: built (false)
|
||||||
|
, tname (YY_NULL)])[
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Instantiate a \a T in here.
|
/// Instantiate a \a T in here.
|
||||||
@@ -101,8 +112,11 @@ m4_define([b4_variant_define],
|
|||||||
inline T&
|
inline T&
|
||||||
build ()
|
build ()
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
assert (!built);
|
YYASSERT (!built);
|
||||||
built = true;])[
|
YYASSERT (!tname);
|
||||||
|
YYASSERT (sizeof (T) <= S);
|
||||||
|
built = true;
|
||||||
|
tname = typeid (T).name ();])[
|
||||||
return *new (buffer.raw) T;
|
return *new (buffer.raw) T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,18 +125,23 @@ m4_define([b4_variant_define],
|
|||||||
inline T&
|
inline T&
|
||||||
build (const T& t)
|
build (const T& t)
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
assert(!built);
|
YYASSERT (!built);
|
||||||
built = true;])[
|
YYASSERT (!tname);
|
||||||
return *new (buffer.raw) T(t);
|
YYASSERT (sizeof (T) <= S);
|
||||||
|
built = true;
|
||||||
|
tname = typeid (T).name ();])[
|
||||||
|
return *new (buffer.raw) T (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct and fill.
|
/// Construct and fill.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
inline
|
||||||
variant (const T& t)]b4_parse_assert_if([
|
variant (const T& t)]b4_parse_assert_if([
|
||||||
: built (true)])[
|
: built (true)
|
||||||
|
, tname (typeid (T).name ())])[
|
||||||
{
|
{
|
||||||
new (buffer.raw) T(t);
|
YYASSERT (sizeof (T) <= S);
|
||||||
|
new (buffer.raw) T (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accessor to a built \a T.
|
/// Accessor to a built \a T.
|
||||||
@@ -130,8 +149,10 @@ m4_define([b4_variant_define],
|
|||||||
inline T&
|
inline T&
|
||||||
as ()
|
as ()
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
assert (built);])[
|
YYASSERT (built);
|
||||||
return reinterpret_cast<T&>(buffer.raw);
|
YYASSERT (tname == typeid (T).name ());
|
||||||
|
YYASSERT (sizeof (T) <= S);])[
|
||||||
|
return reinterpret_cast<T&> (buffer.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Const accessor to a built \a T (for %printer).
|
/// Const accessor to a built \a T (for %printer).
|
||||||
@@ -139,16 +160,21 @@ m4_define([b4_variant_define],
|
|||||||
inline const T&
|
inline const T&
|
||||||
as () const
|
as () const
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
assert(built);])[
|
YYASSERT (built);
|
||||||
return reinterpret_cast<const T&>(buffer.raw);
|
YYASSERT (tname == typeid (T).name ());
|
||||||
|
YYASSERT (sizeof (T) <= S);])[
|
||||||
|
return reinterpret_cast<const T&> (buffer.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the content with \a other.
|
/// Swap the content with \a other, of same type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void
|
inline void
|
||||||
swap (variant<S>& other)
|
swap (variant<S>& other)
|
||||||
{
|
{]b4_parse_assert_if([
|
||||||
std::swap (as<T>(), other.as<T>());
|
YYASSERT (tname == other.tname);])[
|
||||||
|
std::swap (as<T>(), other.as<T>());]b4_parse_assert_if([
|
||||||
|
std::swap (built, other.built);
|
||||||
|
std::swap (tname, other.tname);])[
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign the content of \a other to this.
|
/// Assign the content of \a other to this.
|
||||||
@@ -167,10 +193,12 @@ m4_define([b4_variant_define],
|
|||||||
inline void
|
inline void
|
||||||
destroy ()
|
destroy ()
|
||||||
{
|
{
|
||||||
as<T>().~T();]b4_parse_assert_if([
|
as<T> ().~T ();]b4_parse_assert_if([
|
||||||
built = false;])[
|
built = false;
|
||||||
|
tname = YY_NULL;])[
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
/// A buffer large enough to store any of the semantic values.
|
/// A buffer large enough to store any of the semantic values.
|
||||||
/// Long double is chosen as it has the strongest alignment
|
/// Long double is chosen as it has the strongest alignment
|
||||||
/// constraints.
|
/// constraints.
|
||||||
@@ -178,7 +206,11 @@ m4_define([b4_variant_define],
|
|||||||
{
|
{
|
||||||
long double align_me;
|
long double align_me;
|
||||||
char raw[S];
|
char raw[S];
|
||||||
} buffer;
|
} buffer;]b4_parse_assert_if([
|
||||||
|
/// Whether something is contained.
|
||||||
|
bool built;
|
||||||
|
/// If defined, the name of the stored type.
|
||||||
|
const char* tname;])[
|
||||||
};
|
};
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -197,7 +229,8 @@ m4_define([b4_semantic_type_declare],
|
|||||||
{]b4_type_foreach([b4_char_sizeof])[};
|
{]b4_type_foreach([b4_char_sizeof])[};
|
||||||
|
|
||||||
/// Symbol semantic values.
|
/// Symbol semantic values.
|
||||||
typedef variant<sizeof(union_type)> semantic_type;])
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user