class Optional
{
public:
- // std::optional supports non-trivial types as well, but we
- // do not want to fiddle with unions to disable default Value constructor
- // until that work becomes necessary
- static_assert(std::is_trivial<Value>::value, "Value is trivial");
-
- constexpr Optional() noexcept {}
+ constexpr Optional() noexcept: dummy_() {}
constexpr explicit Optional(const Value &v): value_(v), hasValue_(true) {}
+ ~Optional()
+ {
+ // XXX: This simplified implementation does not keep the destructor
+ // trivial for trivial Value types, but optimizing compilers still
+ // optimize such destruction away, and that is sufficient for our
+ // current needs.
+ reset();
+ }
+
+ Optional(const Optional &other): Optional()
+ {
+ if (other.hasValue_)
+ *this = other.value_;
+ }
+
+ Optional &operator =(const Optional &other)
+ {
+ if (this != &other) {
+ if (other.hasValue_)
+ *this = other.value_;
+ else
+ reset();
+ }
+ return *this;
+ }
+
+ Optional(Optional<Value> &&other): Optional()
+ {
+ if (other.hasValue_) {
+ *this = std::move(other.value_);
+ // no other.reset() per std::optional move semantics
+ }
+ }
+
+ Optional &operator =(Optional<Value> &&other)
+ {
+ if (this != &other) {
+ if (other.hasValue_) {
+ *this = std::move(other.value_);
+ // no other.reset() per std::optional move semantics
+ } else {
+ reset();
+ }
+ }
+ return *this;
+ }
+
constexpr explicit operator bool() const noexcept { return hasValue_; }
constexpr bool has_value() const noexcept { return hasValue_; }
return *this;
}
+ void reset() {
+ if (hasValue_) {
+ hasValue_ = false;
+ value_.~Value();
+ }
+ }
+
private:
- Value value_; // stored value; inaccessible/uninitialized unless hasValue_
+ union {
+ /// unused member that helps satisfy various C++ union requirements
+ struct {} dummy_;
+
+ /// stored value; inaccessible/uninitialized unless hasValue_
+ Value value_;
+ };
+
bool hasValue_ = false;
};