diff --git a/lldb/include/lldb/Utility/Either.h b/lldb/include/lldb/Utility/Either.h index ec683096859b..ae647363512d 100644 --- a/lldb/include/lldb/Utility/Either.h +++ b/lldb/include/lldb/Utility/Either.h @@ -12,36 +12,56 @@ #include "llvm/ADT/Optional.h" +#include + namespace lldb_utility { template - 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 ::value>::type * = nullptr > + Either (const Either& rhs) + { + switch (rhs.m_selected) + { + case Selected::One: + m_t1 = rhs.GetAs().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs().getValue(); + m_selected = Selected::Two; + break; + } + } + + template ::value>::type * = nullptr> llvm::Optional - GetAs() + GetAs() const { switch (m_selected) { @@ -52,9 +72,9 @@ namespace lldb_utility { } } - template ::value>::type * = nullptr > + template ::value>::type * = nullptr> llvm::Optional - GetAs() + GetAs() const { switch (m_selected) { @@ -64,6 +84,68 @@ namespace lldb_utility { return llvm::Optional(); } } + + template + ResultType + Apply (std::function if_T1, + std::function 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& rhs) + { + return (GetAs() == rhs.GetAs()) && (GetAs() == rhs.GetAs()); + } + + explicit + operator bool () + { + switch (m_selected) + { + case Selected::One: + return (bool)m_t1; + case Selected::Two: + return (bool)m_t2; + } + } + + Either& + operator = (const Either& rhs) + { + switch (rhs.m_selected) + { + case Selected::One: + m_t1 = rhs.GetAs().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs().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