aboutsummaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
authorSerge Guelton <sguelton@redhat.com>2019-02-13 22:11:09 +0000
committerSerge Guelton <sguelton@redhat.com>2019-02-13 22:11:09 +0000
commit2d7289e2fa5a69fab523607bfa3b3e2ef2abc072 (patch)
tree9db9d748d0d8c58faf51149a95d7009ac8ef8857 /include/llvm
parentff64ebce03520a872f457a1d8b8263923fe1b2b5 (diff)
downloadllvm-2d7289e2fa5a69fab523607bfa3b3e2ef2abc072.tar.gz
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
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/Optional.h93
1 files changed, 28 insertions, 65 deletions
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 <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