+ struct StorageTriviallyDestructible {
+ // uninitialized
+ union { Value value; };
+ bool hasValue;
+
+ StorageTriviallyDestructible() : hasValue{false} {}
+
+ void clear() {
+ hasValue = false;
+ }
+ };
+
+ struct StorageNonTriviallyDestructible {
+ // uninitialized
+ union { Value value; };
+ bool hasValue;
+
+ StorageNonTriviallyDestructible() : hasValue{false} {}
+
+ ~StorageNonTriviallyDestructible() {
+ clear();
+ }
+
+ void clear() {
+ if (hasValue) {
+ hasValue = false;
+ value.~Value();
+ }
+ }
+ };
+
+ using Storage =
+ typename std::conditional<std::is_trivially_destructible<Value>::value,
+ StorageTriviallyDestructible,
+ StorageNonTriviallyDestructible>::type;
+
+ Storage storage_;