From 2d7289e2fa5a69fab523607bfa3b3e2ef2abc072 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Wed, 13 Feb 2019 22:11:09 +0000 Subject: Revert r353962 Specialization of Optional for trivially copyable types yields failure on the buildbots I fail to reproduce locally. Better safe than sorry, reverting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353982 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Optional.h | 93 ++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 65 deletions(-) (limited to 'include/llvm') diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index d7b9d5cddc2..25a3185064f 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -29,61 +29,33 @@ namespace llvm { class raw_ostream; namespace optional_detail { -template struct OptionalStorageBase { +/// Storage for any type. +template ::value> struct OptionalStorage { AlignedCharArrayUnion storage; bool hasVal = false; - OptionalStorageBase() = default; - OptionalStorageBase(const T &y) : hasVal(true) { new (storage.buffer) T(y); } - OptionalStorageBase(T &&y) : hasVal(true) { - new (storage.buffer) T(std::move(y)); - } - - T *getPointer() { - assert(hasVal); - return reinterpret_cast(storage.buffer); - } - const T *getPointer() const { - assert(hasVal); - return reinterpret_cast(storage.buffer); - } - OptionalStorageBase &operator=(T &&y) { - hasVal = true; - new (this->storage.buffer) T(std::move(y)); - return *this; - } - OptionalStorageBase &operator=(const T &y) { - hasVal = true; - new (this->storage.buffer) T(y); - return *this; - } - void reset() { this->hasVal = false; } -}; - -/// Storage for any type. -template ::value> -struct OptionalStorage : OptionalStorageBase { OptionalStorage() = default; - OptionalStorage(const T &y) : OptionalStorageBase(y) {} - OptionalStorage(const OptionalStorage &O) : OptionalStorageBase() { - this->hasVal = O.hasVal; - if (this->hasVal) - new (this->storage.buffer) T(*O.getPointer()); + OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } + OptionalStorage(const OptionalStorage &O) : hasVal(O.hasVal) { + if (hasVal) + new (storage.buffer) T(*O.getPointer()); } - OptionalStorage(T &&y) : OptionalStorageBase(std::move(y)) {} - OptionalStorage(OptionalStorage &&O) : OptionalStorageBase() { - this->hasVal = O.hasVal; + OptionalStorage(T &&y) : hasVal(true) { + new (storage.buffer) T(std::forward(y)); + } + OptionalStorage(OptionalStorage &&O) : hasVal(O.hasVal) { if (O.hasVal) { - new (this->storage.buffer) T(std::move(*O.getPointer())); + new (storage.buffer) T(std::move(*O.getPointer())); } } OptionalStorage &operator=(T &&y) { - if (this->hasVal) - *this->getPointer() = std::move(y); + if (hasVal) + *getPointer() = std::move(y); else { - OptionalStorageBase::operator=(std::move(y)); + new (storage.buffer) T(std::move(y)); + hasVal = true; } return *this; } @@ -102,10 +74,11 @@ struct OptionalStorage : OptionalStorageBase { // requirements (notably: the existence of a default ctor) when implemented // in that way. Careful SFINAE to avoid such pitfalls would be required. OptionalStorage &operator=(const T &y) { - if (this->hasVal) - *this->getPointer() = y; + if (hasVal) + *getPointer() = y; else { - OptionalStorageBase::operator=(y); + new (storage.buffer) T(y); + hasVal = true; } return *this; } @@ -120,30 +93,20 @@ struct OptionalStorage : OptionalStorageBase { ~OptionalStorage() { reset(); } void reset() { - if (this->hasVal) { - (*this->getPointer()).~T(); + if (hasVal) { + (*getPointer()).~T(); + hasVal = false; } - OptionalStorageBase::reset(); } -}; -template struct OptionalStorage : OptionalStorageBase { - OptionalStorage() = default; - OptionalStorage(const T &y) : OptionalStorageBase(y) {} - OptionalStorage(const OptionalStorage &O) = default; - OptionalStorage(T &&y) : OptionalStorageBase(std::move(y)) {} - OptionalStorage(OptionalStorage &&O) = default; - OptionalStorage &operator=(T &&y) { - OptionalStorageBase::operator=(std::move(y)); - return *this; + T *getPointer() { + assert(hasVal); + return reinterpret_cast(storage.buffer); } - OptionalStorage &operator=(OptionalStorage &&O) = default; - OptionalStorage &operator=(const T &y) { - OptionalStorageBase::operator=(y); - return *this; + const T *getPointer() const { + assert(hasVal); + return reinterpret_cast(storage.buffer); } - OptionalStorage &operator=(const OptionalStorage &O) = default; - ~OptionalStorage() = default; }; } // namespace optional_detail -- cgit v1.2.3