[Lldb-commits] [lldb] r243053 - Several improvements to the Either<T, U> type

Enrico Granata egranata at apple.com
Thu Jul 23 15:17:39 PDT 2015


Author: enrico
Date: Thu Jul 23 17:17:39 2015
New Revision: 243053

URL: http://llvm.org/viewvc/llvm-project?rev=243053&view=rev
Log:
Several improvements to the Either<T,U> type


Modified:
    lldb/trunk/include/lldb/Utility/Either.h

Modified: lldb/trunk/include/lldb/Utility/Either.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Either.h?rev=243053&r1=243052&r2=243053&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/Either.h (original)
+++ lldb/trunk/include/lldb/Utility/Either.h Thu Jul 23 17:17:39 2015
@@ -12,36 +12,56 @@
 
 #include "llvm/ADT/Optional.h"
 
+#include <functional>
+
 namespace lldb_utility {
     template <typename T1, typename T2>
-    class Either {
+    class Either
+    {
     private:
-        enum class Selected {
+        enum class Selected
+        {
             One, Two
         };
         
         Selected m_selected;
-        union {
+        union
+        {
             T1 m_t1;
             T2 m_t2;
         };
         
     public:
-        Either(const T1& t1)
+        Either (const T1& t1)
         {
             m_t1 = t1;
             m_selected = Selected::One;
         }
         
-        Either(const T2& t2)
+        Either (const T2& t2)
         {
             m_t2 = t2;
             m_selected = Selected::Two;
         }
         
-        template <class X, typename std::enable_if<std::is_same<T1,X>::value>::type * = nullptr >
+        Either (const Either<T1,T2>& rhs)
+        {
+            switch (rhs.m_selected)
+            {
+                case Selected::One:
+                    m_t1 = rhs.GetAs<T1>().getValue();
+                    m_selected = Selected::One;
+                    break;
+                case Selected::Two:
+                    m_t2 = rhs.GetAs<T2>().getValue();
+                    m_selected = Selected::Two;
+                    break;
+            }
+        }
+        
+        template <class X, typename std::enable_if<std::is_same<T1,X>::value>::type * = nullptr>
         llvm::Optional<T1>
-        GetAs()
+        GetAs() const
         {
             switch (m_selected)
             {
@@ -52,9 +72,9 @@ namespace lldb_utility {
             }
         }
         
-        template <class X, typename std::enable_if<std::is_same<T2,X>::value>::type * = nullptr >
+        template <class X, typename std::enable_if<std::is_same<T2,X>::value>::type * = nullptr>
         llvm::Optional<T2>
-        GetAs()
+        GetAs() const
         {
             switch (m_selected)
             {
@@ -64,6 +84,68 @@ namespace lldb_utility {
                     return llvm::Optional<T2>();
             }
         }
+        
+        template <class ResultType>
+        ResultType
+        Apply (std::function<ResultType(T1)> if_T1,
+               std::function<ResultType(T2)> if_T2) const
+        {
+            switch (m_selected)
+            {
+                case Selected::One:
+                    return if_T1(m_t1);
+                case Selected::Two:
+                    return if_T2(m_t2);
+            }
+        }
+        
+        bool
+        operator == (const Either<T1,T2>& rhs)
+        {
+            return (GetAs<T1>() == rhs.GetAs<T1>()) && (GetAs<T2>() == rhs.GetAs<T2>());
+        }
+        
+        explicit
+        operator bool ()
+        {
+            switch (m_selected)
+            {
+                case Selected::One:
+                    return (bool)m_t1;
+                case Selected::Two:
+                    return (bool)m_t2;
+            }
+        }
+        
+        Either<T1,T2>&
+        operator = (const Either<T1,T2>& rhs)
+        {
+            switch (rhs.m_selected)
+            {
+                case Selected::One:
+                    m_t1 = rhs.GetAs<T1>().getValue();
+                    m_selected = Selected::One;
+                    break;
+                case Selected::Two:
+                    m_t2 = rhs.GetAs<T2>().getValue();
+                    m_selected = Selected::Two;
+                    break;
+            }
+            return *this;
+        }
+        
+        ~Either ()
+        {
+            switch (m_selected)
+            {
+                case Selected::One:
+                    m_t1.T1::~T1();
+                    break;
+                case Selected::Two:
+                    m_t2.T2::~T2();
+                    break;
+            }
+        }
     };
     
 } // namespace lldb_utility





More information about the lldb-commits mailing list