[gcc r14-7608] gccrs: Improve Optional<T> implementation

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:44:49 GMT 2024


https://gcc.gnu.org/g:4a71a18da8a1ea731ad69c34771bd6ee1085cc64

commit r14-7608-g4a71a18da8a1ea731ad69c34771bd6ee1085cc64
Author: Owen Avery <powerboat9.gamer@gmail.com>
Date:   Fri May 12 03:13:30 2023 -0400

    gccrs: Improve Optional<T> implementation
    
    gcc/rust/ChangeLog:
    
            * util/rust-optional.h
            (class Optional<T>): Improve inner state.
    
    Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>

Diff:
---
 gcc/rust/util/rust-optional.h | 80 ++++++++++++++++++++++++++++---------------
 1 file changed, 52 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h
index 658d90faa87..66730bd992d 100644
--- a/gcc/rust/util/rust-optional.h
+++ b/gcc/rust/util/rust-optional.h
@@ -74,48 +74,72 @@ namespace Rust {
 template <typename T> class Optional
 {
 private:
-  struct Empty
+  struct tag_some
   {
   };
-
-  enum Kind
+  struct tag_none
   {
-    Some,
-    None
-  } kind;
+  };
 
-  union Content
+  bool field_is_some;
+
+  union
   {
-    Empty empty;
     T value;
+  };
 
-    Content () = default;
-  } content;
+  Optional (tag_some, const T &value) : field_is_some (true), value (value) {}
+  Optional (tag_some, T &&value) : field_is_some (true), value (value) {}
 
-  Optional<T> (Kind kind, Content content) : kind (kind), content (content) {}
+  Optional (tag_none) : field_is_some (false) {}
 
 public:
-  Optional (const Optional &other) = default;
-  Optional &operator= (const Optional &other) = default;
-  Optional (Optional &&other) = default;
+  Optional (const Optional &other)
+  {
+    if ((field_is_some = other.field_is_some))
+      new (&value) T (other.value);
+  }
 
-  static Optional<T> some (T value)
+  Optional (Optional &&other)
   {
-    Content content;
-    content.value = value;
+    if ((field_is_some = other.field_is_some))
+      new (&value) T (other.value);
+  }
 
-    return Optional (Kind::Some, content);
+  Optional &operator= (const Optional &other)
+  {
+    if (is_some ())
+      value.~T ();
+    if ((field_is_some = other.field_is_some))
+      new (&value) T (other.value);
+    return *this;
   }
 
-  static Optional<T> none ()
+  Optional &operator= (Optional &&other)
   {
-    Content content;
-    content.empty = Empty ();
+    if (is_some ())
+      value.~T ();
+    if ((field_is_some = other.field_is_some))
+      new (&value) T (other.value);
+    return *this;
+  }
 
-    return Optional (Kind::None, content);
+  ~Optional ()
+  {
+    if (is_some ())
+      value.~T ();
   }
 
-  bool is_some () const { return kind == Kind::Some; }
+  static Optional some (const T &value)
+  {
+    return Optional (tag_some (), value);
+  }
+
+  static Optional some (T &&value) { return Optional (tag_some (), value); }
+
+  static Optional none () { return Optional (tag_none ()); }
+
+  bool is_some () const { return field_is_some; }
   bool is_none () const { return !is_some (); }
 
   /**
@@ -135,24 +159,24 @@ public:
   {
     rust_assert (is_some ());
 
-    return content.value;
+    return value;
   }
 
   T &get ()
   {
     rust_assert (is_some ());
 
-    return content.value;
+    return value;
   }
 
   T take ()
   {
     rust_assert (is_some ());
 
-    auto to_return = std::move (content.value);
+    T to_return = std::move (value);
+    value.~T ();
 
-    content.empty = Empty ();
-    kind = Kind::None;
+    field_is_some = false;
 
     return to_return;
   }


More information about the Gcc-cvs mailing list