aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Utility/Either.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Utility/Either.h')
-rw-r--r--include/lldb/Utility/Either.h154
1 files changed, 154 insertions, 0 deletions
diff --git a/include/lldb/Utility/Either.h b/include/lldb/Utility/Either.h
new file mode 100644
index 000000000000..ae647363512d
--- /dev/null
+++ b/include/lldb/Utility/Either.h
@@ -0,0 +1,154 @@
+//===-- Either.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Either_h_
+#define liblldb_Either_h_
+
+#include "llvm/ADT/Optional.h"
+
+#include <functional>
+
+namespace lldb_utility {
+ template <typename T1, typename T2>
+ class Either
+ {
+ private:
+ enum class Selected
+ {
+ One, Two
+ };
+
+ Selected m_selected;
+ union
+ {
+ T1 m_t1;
+ T2 m_t2;
+ };
+
+ public:
+ Either (const T1& t1)
+ {
+ m_t1 = t1;
+ m_selected = Selected::One;
+ }
+
+ Either (const T2& t2)
+ {
+ m_t2 = t2;
+ m_selected = Selected::Two;
+ }
+
+ 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() const
+ {
+ switch (m_selected)
+ {
+ case Selected::One:
+ return m_t1;
+ default:
+ return llvm::Optional<T1>();
+ }
+ }
+
+ template <class X, typename std::enable_if<std::is_same<T2,X>::value>::type * = nullptr>
+ llvm::Optional<T2>
+ GetAs() const
+ {
+ switch (m_selected)
+ {
+ case Selected::Two:
+ return m_t2;
+ default:
+ 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
+
+#endif // #ifndef liblldb_Either_h_
+