diff options
| author | Serge Guelton <sguelton@redhat.com> | 2019-02-13 22:11:09 +0000 |
|---|---|---|
| committer | Serge Guelton <sguelton@redhat.com> | 2019-02-13 22:11:09 +0000 |
| commit | 221c39165da51d0ee1fa3b89433f82a988c3bc3e (patch) | |
| tree | 152290db72c2cbb9839dc7d841a190d484b40a1d /llvm | |
| parent | 8331f61a51a7a0a1efbf5ed398e181593023d151 (diff) | |
| download | bcm5719-llvm-221c39165da51d0ee1fa3b89433f82a988c3bc3e.tar.gz bcm5719-llvm-221c39165da51d0ee1fa3b89433f82a988c3bc3e.zip | |
Revert r353962
Specialization of Optional for trivially copyable types yields failure on the buildbots I fail to reproduce locally.
Better safe than sorry, reverting.
llvm-svn: 353982
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/ADT/Optional.h | 93 | ||||
| -rw-r--r-- | llvm/unittests/ADT/OptionalTest.cpp | 20 |
2 files changed, 28 insertions, 85 deletions
diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index d7b9d5cddc2..25a3185064f 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -29,61 +29,33 @@ namespace llvm { class raw_ostream; namespace optional_detail { -template <typename T> struct OptionalStorageBase { +/// Storage for any type. +template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage { AlignedCharArrayUnion<T> 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<T *>(storage.buffer); - } - const T *getPointer() const { - assert(hasVal); - return reinterpret_cast<const T *>(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 <typename T, bool = is_trivially_copyable<T>::value> -struct OptionalStorage : OptionalStorageBase<T> { OptionalStorage() = default; - OptionalStorage(const T &y) : OptionalStorageBase<T>(y) {} - OptionalStorage(const OptionalStorage &O) : OptionalStorageBase<T>() { - 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<T>(std::move(y)) {} - OptionalStorage(OptionalStorage &&O) : OptionalStorageBase<T>() { - this->hasVal = O.hasVal; + OptionalStorage(T &&y) : hasVal(true) { + new (storage.buffer) T(std::forward<T>(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<T>::operator=(std::move(y)); + new (storage.buffer) T(std::move(y)); + hasVal = true; } return *this; } @@ -102,10 +74,11 @@ struct OptionalStorage : OptionalStorageBase<T> { // 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<T>::operator=(y); + new (storage.buffer) T(y); + hasVal = true; } return *this; } @@ -120,30 +93,20 @@ struct OptionalStorage : OptionalStorageBase<T> { ~OptionalStorage() { reset(); } void reset() { - if (this->hasVal) { - (*this->getPointer()).~T(); + if (hasVal) { + (*getPointer()).~T(); + hasVal = false; } - OptionalStorageBase<T>::reset(); } -}; -template <typename T> struct OptionalStorage<T, true> : OptionalStorageBase<T> { - OptionalStorage() = default; - OptionalStorage(const T &y) : OptionalStorageBase<T>(y) {} - OptionalStorage(const OptionalStorage &O) = default; - OptionalStorage(T &&y) : OptionalStorageBase<T>(std::move(y)) {} - OptionalStorage(OptionalStorage &&O) = default; - OptionalStorage &operator=(T &&y) { - OptionalStorageBase<T>::operator=(std::move(y)); - return *this; + T *getPointer() { + assert(hasVal); + return reinterpret_cast<T *>(storage.buffer); } - OptionalStorage &operator=(OptionalStorage &&O) = default; - OptionalStorage &operator=(const T &y) { - OptionalStorageBase<T>::operator=(y); - return *this; + const T *getPointer() const { + assert(hasVal); + return reinterpret_cast<const T *>(storage.buffer); } - OptionalStorage &operator=(const OptionalStorage &O) = default; - ~OptionalStorage() = default; }; } // namespace optional_detail diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index c39b6727cd5..98adaccca96 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -18,12 +18,6 @@ using namespace llvm; namespace { -static_assert(llvm::is_trivially_copyable<Optional<int>>::value, - "trivially copyable"); - -static_assert(llvm::is_trivially_copyable<Optional<std::array<int, 3>>>::value, - "trivially copyable"); - struct NonDefaultConstructible { static unsigned CopyConstructions; static unsigned Destructions; @@ -51,10 +45,6 @@ unsigned NonDefaultConstructible::CopyConstructions = 0; unsigned NonDefaultConstructible::Destructions = 0; unsigned NonDefaultConstructible::CopyAssignments = 0; -static_assert( - !llvm::is_trivially_copyable<Optional<NonDefaultConstructible>>::value, - "not trivially copyable"); - // Test fixture class OptionalTest : public testing::Test { }; @@ -213,10 +203,6 @@ struct MultiArgConstructor { }; unsigned MultiArgConstructor::Destructions = 0; -static_assert( - !llvm::is_trivially_copyable<Optional<MultiArgConstructor>>::value, - "not trivially copyable"); - TEST_F(OptionalTest, Emplace) { MultiArgConstructor::ResetCounts(); Optional<MultiArgConstructor> A; @@ -264,9 +250,6 @@ unsigned MoveOnly::MoveConstructions = 0; unsigned MoveOnly::Destructions = 0; unsigned MoveOnly::MoveAssignments = 0; -static_assert(!llvm::is_trivially_copyable<Optional<MoveOnly>>::value, - "not trivially copyable"); - TEST_F(OptionalTest, MoveOnlyNull) { MoveOnly::ResetCounts(); Optional<MoveOnly> O; @@ -368,9 +351,6 @@ private: unsigned Immovable::Constructions = 0; unsigned Immovable::Destructions = 0; -static_assert(!llvm::is_trivially_copyable<Optional<Immovable>>::value, - "not trivially copyable"); - TEST_F(OptionalTest, ImmovableEmplace) { Optional<Immovable> A; Immovable::ResetCounts(); |

