X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FOptional.h;h=def3670f00ab69946c0fce6eb12441eebd4466dd;hb=2d6a824fc67a236d41c7a6cdf5734654d42fe710;hp=f4bc9ff4ce7a36bb47eb82f7a5d49a4d5d7a7e10;hpb=1e2aee3a27a694e4015a23b4c30a00e29a6ed7ce;p=folly.git diff --git a/folly/Optional.h b/folly/Optional.h index f4bc9ff4..def3670f 100644 --- a/folly/Optional.h +++ b/folly/Optional.h @@ -54,8 +54,8 @@ * cout << *v << endl; * } */ -#include #include +#include #include #include @@ -82,6 +82,12 @@ const None none = nullptr; # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif // __GNUC__ +class OptionalEmptyException : public std::runtime_error { + public: + OptionalEmptyException() + : std::runtime_error("Empty Optional cannot be unwrapped") {} +}; + template class Optional { public: @@ -205,24 +211,34 @@ class Optional { } } - const Value& value() const { - assert(hasValue()); + const Value& value() const& { + require_value(); return value_; } - Value& value() { - assert(hasValue()); + Value& value() & { + require_value(); return value_; } + Value value() && { + require_value(); + return std::move(value_); + } + + const Value* get_pointer() const& { return hasValue_ ? &value_ : nullptr; } + Value* get_pointer() & { return hasValue_ ? &value_ : nullptr; } + Value* get_pointer() && = delete; + bool hasValue() const { return hasValue_; } explicit operator bool() const { return hasValue(); } - const Value& operator*() const { return value(); } - Value& operator*() { return value(); } + const Value& operator*() const& { return value(); } + Value& operator*() & { return value(); } + Value operator*() && { return std::move(value()); } const Value* operator->() const { return &value(); } Value* operator->() { return &value(); } @@ -239,6 +255,12 @@ class Optional { } private: + void require_value() const { + if (!hasValue_) { + throw OptionalEmptyException(); + } + } + template void construct(Args&&... args) { const void* ptr = &value_; @@ -258,12 +280,12 @@ class Optional { template const T* get_pointer(const Optional& opt) { - return opt ? &opt.value() : nullptr; + return opt.get_pointer(); } template T* get_pointer(Optional& opt) { - return opt ? &opt.value() : nullptr; + return opt.get_pointer(); } template