From 98b4fd82b72f95542ce398c477f7a46df05b2e6a Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Sat, 16 Feb 2019 09:19:58 +0000 Subject: [PATCH] Make Optional Trivially Copyable when T is trivially copyable This is another attempt in the process, works nicely on my setup, let's check how it behaves on other targets. llvm-svn: 354199 --- llvm/include/llvm/ADT/Optional.h | 53 +++++++++++++++++++++++++++++++++++++ llvm/unittests/ADT/OptionalTest.cpp | 7 +++++ 2 files changed, 60 insertions(+) diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index 25a3185..ab83b67 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -108,6 +108,59 @@ template ::value> struct OptionalSto return reinterpret_cast(storage.buffer); } }; +template struct OptionalStorage { + AlignedCharArrayUnion storage; + bool hasVal = false; + + OptionalStorage() = default; + + OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } + OptionalStorage(const OptionalStorage &O) = default; + OptionalStorage(T &&y) : hasVal(true) { + new (storage.buffer) T(std::forward(y)); + } + OptionalStorage(OptionalStorage &&O) = default; + + OptionalStorage &operator=(T &&y) { + if (hasVal) + *getPointer() = std::move(y); + else { + new (storage.buffer) T(std::move(y)); + hasVal = true; + } + return *this; + } + OptionalStorage &operator=(OptionalStorage &&O) = default; + + OptionalStorage &operator=(const T &y) { + if (hasVal) + *getPointer() = y; + else { + new (storage.buffer) T(y); + hasVal = true; + } + return *this; + } + OptionalStorage &operator=(const OptionalStorage &O) = default; + + ~OptionalStorage() = default; + + void reset() { + if (hasVal) { + (*getPointer()).~T(); + hasVal = false; + } + } + + T *getPointer() { + assert(hasVal); + return reinterpret_cast(storage.buffer); + } + const T *getPointer() const { + assert(hasVal); + return reinterpret_cast(storage.buffer); + } +}; } // namespace optional_detail diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index 98adacc..015fcf3 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -14,8 +14,15 @@ #include + using namespace llvm; +static_assert(llvm::is_trivially_copyable>::value, + "trivially copyable"); + +static_assert(llvm::is_trivially_copyable>>::value, + "trivially copyable"); + namespace { struct NonDefaultConstructible { -- 2.7.4