X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/733fb7c593486846eca5a60d1e3ff6880ce358d7..312c0cff71e784e116c0ecac4c33bc94d54f78de:/data/variant.hh diff --git a/data/variant.hh b/data/variant.hh index 1b033886..da0d2a39 100644 --- a/data/variant.hh +++ b/data/variant.hh @@ -72,7 +72,6 @@ m4_map([ b4_symbol_tag_comment], [$@])dnl # The needed includes for variants support. m4_define([b4_variant_includes], [b4_parse_assert_if([[#include ]])[ -#include // abort #ifndef YYASSERT # include # define YYASSERT assert @@ -100,13 +99,29 @@ m4_define([b4_variant_define], , tname (YY_NULL)])[ {} - /// Instantiate a \a T in here. + /// Construct and fill. + template + variant (const T& t)]b4_parse_assert_if([ + : built (true) + , tname (typeid (T).name ())])[ + { + YYASSERT (sizeof (T) <= S); + new (buffer.raw) T (t); + } + + /// Destruction, allowed only if empty. + ~variant () + {]b4_parse_assert_if([ + YYASSERT (!built); + ])[} + + /// Instantiate an empty \a T in here. template T& build () {]b4_parse_assert_if([ - //YYASSERT (!built); - //YYASSERT (!tname); + YYASSERT (!built); + YYASSERT (!tname); YYASSERT (sizeof (T) <= S); built = true; tname = typeid (T).name ();])[ @@ -118,24 +133,14 @@ m4_define([b4_variant_define], T& build (const T& t) {]b4_parse_assert_if([ - //YYASSERT (!built); - //YYASSERT (!tname); + YYASSERT (!built); + YYASSERT (!tname); YYASSERT (sizeof (T) <= S); built = true; tname = typeid (T).name ();])[ return *new (buffer.raw) T (t); } - /// Construct and fill. - template - variant (const T& t)]b4_parse_assert_if([ - : built (true) - , tname (typeid (T).name ())])[ - { - YYASSERT (sizeof (T) <= S); - new (buffer.raw) T (t); - } - /// Accessor to a built \a T. template T& @@ -159,11 +164,12 @@ m4_define([b4_variant_define], } /// Swap the content with \a other, of same type. + /// /// Both variants must be built beforehand, because swapping the actual /// data requires reading it (with as()), and this is not possible on /// unconstructed variants: it would require some dynamic testing, which /// should not be the variant's responsability. - /// Swapping between built and ((possibly) non-built is done with + /// Swapping between built and (possibly) non-built is done with /// variant::move (). template void @@ -175,7 +181,8 @@ m4_define([b4_variant_define], std::swap (as(), other.as()); } - /// Assign the content of \a other to this. + /// Move the content of \a other to this. + /// /// Destroys \a other. template void @@ -188,7 +195,6 @@ m4_define([b4_variant_define], } /// Copy the content of \a other to this. - /// Destroys \a other. template void copy (const variant& other) @@ -206,19 +212,11 @@ m4_define([b4_variant_define], tname = YY_NULL;])[ } + private: /// Prohibit blind copies. - private: - self_type& operator=(const self_type&) - { - abort (); - } - - variant (const self_type&) - { - abort (); - } + self_type& operator=(const self_type&); + variant (const self_type&); - private: /// A buffer large enough to store any of the semantic values. /// Long double is chosen as it has the strongest alignment /// constraints. @@ -227,7 +225,8 @@ m4_define([b4_variant_define], long double align_me; char raw[S]; } buffer;]b4_parse_assert_if([ - /// Whether something is contained. + + /// Whether the content is built. bool built; /// If defined, the name of the stored type. const char* tname;])[ @@ -312,14 +311,15 @@ m4_define([b4_symbol_constructor_define_], b4_parser_class_name::make_[]b4_symbol_([$1], [id]) (dnl b4_join(b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]), - b4_locations_if([const location_type& l]))) + b4_locations_if([const location_type& l])))[ { - return symbol_type (b4_join([token::b4_symbol([$1], [id])], - b4_symbol_if([$1], [has_type], [v]), - b4_locations_if([l]))); + symbol_type res (token::]b4_symbol([$1], [id])[]b4_locations_if([, l])[); + ]b4_symbol_if([$1], [has_type], [res.value.build (v);])[ + // ]b4_locations_if([res.location = l;])[ + return res; } -])])]) +]])])]) # b4_symbol_constructor_define