Rename fixup from TDelayedDestruction to DelayedDestruction.
[folly.git] / folly / Optional.h
index f4bc9ff4ce7a36bb47eb82f7a5d49a4d5d7a7e10..def3670f00ab69946c0fce6eb12441eebd4466dd 100644 (file)
@@ -54,8 +54,8 @@
  *    cout << *v << endl;
  *  }
  */
-#include <cassert>
 #include <cstddef>
+#include <stdexcept>
 #include <type_traits>
 #include <utility>
 
@@ -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 Value>
 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<class... Args>
   void construct(Args&&... args) {
     const void* ptr = &value_;
@@ -258,12 +280,12 @@ class Optional {
 
 template<class T>
 const T* get_pointer(const Optional<T>& opt) {
-  return opt ? &opt.value() : nullptr;
+  return opt.get_pointer();
 }
 
 template<class T>
 T* get_pointer(Optional<T>& opt) {
-  return opt ? &opt.value() : nullptr;
+  return opt.get_pointer();
 }
 
 template<class T>