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 _______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits