Index: third_party/WebKit/Source/wtf/Optional.h |
diff --git a/third_party/WebKit/Source/wtf/Optional.h b/third_party/WebKit/Source/wtf/Optional.h |
index f522dba472336ec6995eef7a0cc2ed8b0a82b1d7..a28bd804308c3e218f80c575ac77cabae5448102 100644 |
--- a/third_party/WebKit/Source/wtf/Optional.h |
+++ b/third_party/WebKit/Source/wtf/Optional.h |
@@ -5,21 +5,68 @@ |
#ifndef Optional_h |
#define Optional_h |
-#include "base/optional.h" |
-#include "wtf/TypeTraits.h" |
+#include "wtf/Alignment.h" |
+#include "wtf/Allocator.h" |
+#include "wtf/Assertions.h" |
+#include "wtf/Noncopyable.h" |
+#include "wtf/StdLibExtras.h" |
+ |
+#include <new> |
+#include <utility> |
namespace WTF { |
-// WTF::Optional is base::Optional. See base/optional.h for documentation. |
+// This is a lightweight template similar to std::experimental::optional. |
+// It currently does not support assignment, swapping, comparison, etc. |
// |
-// A clang plugin enforces that garbage collected types are not allocated |
-// outside of the heap, similarly we enforce that one doesn't create garbage |
-// collected types nested inside an Optional. |
+// Use this instead of OwnPtr for cases where you only want to conditionally |
+// construct a "scope" object. |
+// |
+// Example: |
+// Optional<DrawingRecorder> recorder; |
+// if (shouldDraw) |
+// recorder.emplace(constructor, args, here); |
+// // recorder destroyed at end of scope |
+// |
+// It can be used in WTF::Vector. |
+// |
+// Note in particular that unlike a pointer, though, dereferencing a const |
+// optional yields a const reference. |
+ |
template <typename T> |
-using Optional = typename std::enable_if<!IsGarbageCollectedType<T>::value, base::Optional<T>>::type; |
+class Optional final { |
+ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
+ WTF_MAKE_NONCOPYABLE(Optional); |
+public: |
+ Optional() : m_ptr(nullptr) { } |
+ ~Optional() |
+ { |
+ if (m_ptr) |
+ m_ptr->~T(); |
+ } |
-constexpr base::nullopt_t nullopt = base::nullopt; |
-constexpr base::in_place_t in_place = base::in_place; |
+ typedef T* Optional::*UnspecifiedBoolType; |
+ operator UnspecifiedBoolType() const { return m_ptr ? &Optional::m_ptr : nullptr; } |
+ |
+ T& operator*() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; } |
+ const T& operator*() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; } |
+ T* operator->() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; } |
+ const T* operator->() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; } |
+ T* get() { return m_ptr; } |
+ const T* get() const { return m_ptr; } |
+ |
+ template <typename... Args> |
+ void emplace(Args&&... args) |
+ { |
+ RELEASE_ASSERT(!m_ptr); |
+ m_ptr = reinterpret_cast_ptr<T*>(&m_storage.buffer); |
+ new (m_ptr) T(std::forward<Args>(args)...); |
+ } |
+ |
+private: |
+ T* m_ptr; |
+ AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage; |
+}; |
} // namespace WTF |