1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

Revert [NFC] Better encapsulation of llvm::Optional Storage

I'm getting the feealing that current Optional implementation is full of UB :-/

llvm-svn: 354217
This commit is contained in:
Serge Guelton 2019-02-17 14:59:21 +00:00
parent 2051d05fd0
commit 03939bc82d

View File

@ -30,12 +30,10 @@ class raw_ostream;
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 @@ public:
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 @@ public:
/// 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 @@ public:
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(); }