Add copy/move constructors and assignment operators to WTF::Optional
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jun 2014 20:54:57 +0000 (20:54 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Jun 2014 20:54:57 +0000 (20:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134119

Reviewed by Andreas Kling.

* wtf/Optional.h:
(WTF::Optional::Optional):
(WTF::Optional::operator=):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170202 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/Optional.h

index 351d0e7..5c7e78c 100644 (file)
@@ -1,3 +1,14 @@
+2014-06-20  Anders Carlsson  <andersca@apple.com>
+
+        Add copy/move constructors and assignment operators to WTF::Optional
+        https://bugs.webkit.org/show_bug.cgi?id=134119
+
+        Reviewed by Andreas Kling.
+
+        * wtf/Optional.h:
+        (WTF::Optional::Optional):
+        (WTF::Optional::operator=):
+
 2014-06-19  Anders Carlsson  <andersca@apple.com>
 
         Add WTF::Optional class
index f3d68cb..d00af1a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <type_traits>
 #include <wtf/Assertions.h>
+#include <wtf/StdLibExtras.h>
 
 // WTF::Optional is a class based on std::optional, described here:
 // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3527.html
@@ -57,6 +58,20 @@ public:
     {
     }
 
+    Optional(const Optional& other)
+        : m_isEngaged(other.m_isEngaged)
+    {
+        if (m_isEngaged)
+            new (NotNull, std::addressof(m_value)) T(other.m_value);
+    }
+
+    Optional(Optional&& other)
+        : m_isEngaged(other.m_isEngaged)
+    {
+        if (m_isEngaged)
+            new (NotNull, std::addressof(m_value)) T(std::move(other.m_value));
+    }
+
     Optional(T&& value)
         : m_isEngaged(true)
         , m_value(std::move(value))
@@ -68,7 +83,6 @@ public:
         : m_isEngaged(true)
         , m_value(std::forward<Args>(args)...)
     {
-
     }
 
     ~Optional()
@@ -77,6 +91,53 @@ public:
             m_value.~T();
     }
 
+    Optional& operator=(const Optional& other)
+    {
+        if (m_isEngaged == other.m_isEngaged) {
+            if (m_isEngaged)
+                m_value = other.m_value;
+            return *this;
+        }
+
+        if (m_isEngaged)
+            m_value.~T();
+        else
+            new (NotNull, std::addressof(m_value)) T(other.m_value);
+        m_isEngaged = other.m_isEngaged;
+
+        return *this;
+    }
+
+    Optional& operator=(Optional&& other)
+    {
+        if (m_isEngaged == other.m_isEngaged) {
+            if (m_isEngaged)
+                m_value = std::move(other.m_value);
+            return *this;
+        }
+
+        if (m_isEngaged)
+            m_value.~T();
+        else
+            new (NotNull, std::addressof(m_value)) T(std::move(other.m_value));
+        m_isEngaged = other.m_isEngaged;
+
+        return *this;
+    }
+
+    template<typename U>
+    Optional& operator=(U&& u)
+    {
+        if (m_isEngaged) {
+            m_value = std::forward<U>(u);
+            return *this;
+        }
+
+        new (NotNull, std::addressof(m_value)) T(std::forward<U>(u));
+        m_isEngaged = true;
+        return *this;
+    }
+
     explicit operator bool() const { return m_isEngaged; }
 
     T& value()