]) # b4_variant_if
+# b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
+# ----------------------------------------------------
+m4_define([b4_assert_if],
+[b4_percent_define_ifdef([[assert]], [$1], [$2])])
+
+
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
# --------------------------------------
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
])])
-# b4_symbol_variant(YYTYPE, YYVAL, ACTION)
-# ----------------------------------------
+# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
+# ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE.
m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar],
- [$2.$3<$][3>()])dnl
+ [$2.$3<$][3>(m4_shift3($@))])dnl
switch ($1)
{
m4_map([b4_symbol_action_], m4_defn([b4_type_names]))
]b4_percent_code_get([[requires]])[
+]b4_assert_if([#include <cassert>])[
#include <string>
#include <iostream>
#include "stack.hh"
/// via the current state.
template <size_t S>
struct variant
- {
+ {]b4_assert_if([
+ /// Whether something is contained.
+ bool built;
+
+ /// Initially uninitialized.
+ variant ()
+ : built(false)
+ {}])[
+
/// Instantiate a \a T in here.
template <typename T>
inline T&
build()
- {
+ {]b4_assert_if([
+ assert(!built);
+ built = true;])[
return *new (buffer) T;
}
- /// Destroy the stored \a T.
- template <typename T>
- inline void
- destroy()
- {
- reinterpret_cast<T&>(buffer).~T();
- }
-
/// Accessor to a built \a T.
template <typename T>
inline T&
as()
- {
+ {]b4_assert_if([
+ assert(built);])[
return reinterpret_cast<T&>(buffer);
}
template <typename T>
inline const T&
as() const
- {
+ {]b4_assert_if([
+ assert(built);])[
return reinterpret_cast<const T&>(buffer);
}
+ /// Swap the content with \a other.
+ template <typename T>
+ inline void
+ swap(variant<S>& other)
+ {
+ std::swap(as<T>(), other.as<T>());
+ }
+
+ /// Assign the content of \a other to this.
+ /// Destroys \a other.
+ template <typename T>
+ inline void
+ build(variant<S>& other)
+ {
+ build<T>();
+ swap<T>(other);
+ other.destroy<T>();
+ }
+
+ /// Destroy the stored \a T.
+ template <typename T>
+ inline void
+ destroy()
+ {
+ as<T>().~T();]b4_assert_if([
+ built = false;])[
+ }
+
/// A buffer large enough to store any of the semantic values.
char buffer[S];
};
# define YYCDEBUG if (yydebug_) (*yycdebug_)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug_) \
+ do { \
+ if (yydebug_) \
{ \
*yycdebug_ << Title << ' '; \
yy_symbol_print_ ((Type), (Value), (Location)); \
*yycdebug_ << std::endl; \
} \
-} while (false)
+ } while (false)
# define YY_REDUCE_PRINT(Rule) \
-do { \
- if (yydebug_) \
- yy_reduce_print_ (Rule); \
-} while (false)
+ do { \
+ if (yydebug_) \
+ yy_reduce_print_ (Rule); \
+ } while (false)
# define YY_STACK_PRINT() \
-do { \
- if (yydebug_) \
- yystack_print_ (); \
-} while (false)
+ do { \
+ if (yydebug_) \
+ yystack_print_ (); \
+ } while (false)
#else /* !YYDEBUG */
]b4_parser_class_name[::yypush_ (state_type s,
semantic_type& v, const location_type& l)
{
- yystack_.push (data_type (s, v, l));
+]b4_variant_if(
+[[ yystack_.push (data_type (s, semantic_type(), l));
+ ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], [build], [v])],
+[ yystack_.push (data_type (s, v, l));])[
}
void
if (yychar <= yyeof_)
{
- /* Return failure if at end of input. */
- if (yychar == yyeof_)
- YYABORT;
+ /* Return failure if at end of input. */
+ if (yychar == yyeof_)
+ YYABORT;
}
else
{