Revert [NFC] Better encapsulation of llvm::Optional Storage
I'm getting the feealing that current Optional implementation is full of UB :-/
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354217 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 09a26b6..25a3185 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -30,12 +30,10 @@
namespace optional_detail {
/// Storage for any type.
-template <typename T, bool = is_trivially_copyable<T>::value>
-class OptionalStorage {
+template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
AlignedCharArrayUnion<T> storage;
bool hasVal = false;
-public:
OptionalStorage() = default;
OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
@@ -109,14 +107,6 @@
assert(hasVal);
return reinterpret_cast<const T *>(storage.buffer);
}
-
- template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
- reset();
- hasVal = true;
- new (storage.buffer) T(std::forward<ArgTypes>(Args)...);
- }
-
- bool hasValue() const { return hasVal; }
};
} // namespace optional_detail
@@ -144,7 +134,9 @@
/// Create a new object by constructing it in place with the given arguments.
template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
- Storage.emplace(std::forward<ArgTypes>(Args)...);
+ reset();
+ Storage.hasVal = true;
+ new (getPointer()) T(std::forward<ArgTypes>(Args)...);
}
static inline Optional create(const T *y) {
@@ -159,13 +151,19 @@
void reset() { Storage.reset(); }
- const T *getPointer() const { return Storage.getPointer(); }
- T *getPointer() { return Storage.getPointer(); }
+ const T *getPointer() const {
+ assert(Storage.hasVal);
+ return reinterpret_cast<const T *>(Storage.storage.buffer);
+ }
+ T *getPointer() {
+ assert(Storage.hasVal);
+ return reinterpret_cast<T *>(Storage.storage.buffer);
+ }
const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); }
- explicit operator bool() const { return hasValue(); }
- bool hasValue() const { return Storage.hasValue(); }
+ explicit operator bool() const { return Storage.hasVal; }
+ bool hasValue() const { return Storage.hasVal; }
const T *operator->() const { return getPointer(); }
T *operator->() { return getPointer(); }
const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); }