bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 9/9] variants: prohibit simple copies


From: Akim Demaille
Subject: [PATCH 9/9] variants: prohibit simple copies
Date: Wed, 19 Dec 2012 11:36:10 +0100

The "variant" structure provides a means to store, in a typeless way,
C++ objects.  Manipulating it without provide the type of the stored
content is doomed to failure.  So provide a means to copy in a type
safe way, and prohibit typeless assignments.

* data/c++.m4 (symbol_type::move): New.
* data/lalr1.cc: Use it.
* data/variant.hh (b4_variant_define): Provide variant::copy.
Let variant::operator= abort.
We cannot undefine it, yet, as it is still uses by the implicit
assigment in symbols, which must also be disabled.
---
 data/c++.m4     | 13 +++++++++++++
 data/lalr1.cc   |  9 +++++----
 data/variant.hh | 17 +++++++++++++++++
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/data/c++.m4 b/data/c++.m4
index 10855df..66982de 100644
--- a/data/c++.m4
+++ b/data/c++.m4
@@ -185,6 +185,9 @@ m4_define([b4_public_types_declare],
       /// Default constructor.
       inline symbol_type ();
 
+      /// Destructive move, \a s is emptied.
+      inline void move (symbol_type& s);
+
       /// Constructor for tokens with semantic value.
       inline symbol_type (]b4_join([token_type t],
                                    [const semantic_type& v],
@@ -295,6 +298,16 @@ m4_define([b4_public_types_define],
   }
 
   inline
+  void
+  ]b4_parser_class_name[::symbol_type::move (symbol_type& s)
+  {
+    ]b4_variant_if([b4_symbol_variant([[s.type]], [value], [build], 
[s.value])],
+                   [value = s.value;])[
+    type = s.type;]b4_locations_if([
+    location = s.location;])[
+  }
+
+  inline
   int
   ]b4_parser_class_name[::symbol_type::type_get_ () const
   {
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 0209925..53000ba 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -721,10 +721,11 @@ b4_dollar_popdef])[]dnl
         try
           {
 ]b4_token_ctor_if(
-[            yyla = b4_function_call([yylex], [symbol_type],
-                                     m4_ifdef([b4_lex_param], b4_lex_param));],
-[            yyla.type = yytranslate_ (b4_function_call([yylex], [int],
-                                     [b4_api_PREFIX[STYPE*], 
[&yyla.value]][]dnl
+[          symbol_type yylookahead = b4_function_call([yylex], [symbol_type],
+                                   m4_ifdef([b4_lex_param], b4_lex_param));
+          yyla.move(yylookahead);],
+[          yyla.type = yytranslate_ (b4_function_call([yylex], [int],
+                                    [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
 b4_locations_if([, [[location*], [&yyla.location]]])dnl
 m4_ifdef([b4_lex_param], [, ]b4_lex_param)));])[
           }
diff --git a/data/variant.hh b/data/variant.hh
index 684f9e3..454f360 100644
--- a/data/variant.hh
+++ b/data/variant.hh
@@ -79,6 +79,7 @@ m4_map([b4_char_sizeof_], address@hidden)dnl
 # The needed includes for variants support.
 m4_define([b4_variant_includes],
 [b4_parse_assert_if([[#include <typeinfo>]])[
+#include <cstdlib>  // abort
 #ifndef YYASSERT
 # include <cassert>
 # define YYASSERT assert
@@ -188,6 +189,15 @@ m4_define([b4_variant_define],
       other.destroy<T>();
     }
 
+    /// Copy the content of \a other to this.
+    /// Destroys \a other.
+    template <typename T>
+    inline void
+    copy (const variant<S>& other)
+    {
+      build<T> (other.as<T> ());
+    }
+
     /// Destroy the stored \a T.
     template <typename T>
     inline void
@@ -198,6 +208,13 @@ m4_define([b4_variant_define],
       tname = YY_NULL;])[
     }
 
+    /// Prohibit blind copies.
+    //  private:
+    self_type& operator=(const self_type&)
+    {
+      abort ();
+    }
+
   private:
     /// A buffer large enough to store any of the semantic values.
     /// Long double is chosen as it has the strongest alignment
-- 
1.8.0.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]