diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2023-05-12 03:13:30 -0400 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 18:37:20 +0100 |
commit | 4a71a18da8a1ea731ad69c34771bd6ee1085cc64 (patch) | |
tree | 015fe8b00eea92a9be215286389332904550da3b /gcc/rust/util/rust-optional.h | |
parent | dfd2e26bda189f573d40eaf1f6b5a44180c31640 (diff) | |
download | gcc-4a71a18da8a1ea731ad69c34771bd6ee1085cc64.zip gcc-4a71a18da8a1ea731ad69c34771bd6ee1085cc64.tar.gz gcc-4a71a18da8a1ea731ad69c34771bd6ee1085cc64.tar.bz2 |
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>
Diffstat (limited to 'gcc/rust/util/rust-optional.h')
-rw-r--r-- | gcc/rust/util/rust-optional.h | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h index 658d90f..66730bd 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; } |