forked from OSchip/llvm-project
Several improvements to the Either<T,U> type
llvm-svn: 243053
This commit is contained in:
parent
d9c1bc9955
commit
fe563d5573
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue