+ struct StorageTriviallyDestructible {
+ // The union trick allows to initialize the Optional's memory,
+ // so that compiler/tools don't complain about unitialized memory,
+ // without actually calling Value's default constructor.
+ // The rest of the implementation enforces that hasValue/value are
+ // synchronized.
+ union {
+ bool hasValue;
+ struct {
+ bool paddingForHasValue_[1];
+ Value value;
+ };
+ };
+
+ StorageTriviallyDestructible() : hasValue{false} {}
+
+ void clear() {
+ hasValue = false;
+ }
+ };
+
+ struct StorageNonTriviallyDestructible {
+ // See StorageTriviallyDestructible's union
+ union {
+ bool hasValue;
+ struct {
+ bool paddingForHasValue_[1];
+ Value value;
+ };
+ };
+
+ FOLLY_PUSH_WARNING
+ // These are both informational warnings, but they trigger rare enough
+ // that we've left them enabled.
+ FOLLY_MSVC_DISABLE_WARNING(4587) // constructor of .value is not called
+ FOLLY_MSVC_DISABLE_WARNING(4588) // destructor of .value is not called
+ StorageNonTriviallyDestructible() : hasValue{false} {}
+ ~StorageNonTriviallyDestructible() {
+ clear();
+ }
+ FOLLY_POP_WARNING