aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Support/ErrorOr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support/ErrorOr.h')
-rw-r--r--include/llvm/Support/ErrorOr.h52
1 files changed, 32 insertions, 20 deletions
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index 0742a2d..84763de 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -13,8 +13,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_ERROR_OR_H
-#define LLVM_SUPPORT_ERROR_OR_H
+#ifndef LLVM_SUPPORT_ERROROR_H
+#define LLVM_SUPPORT_ERROROR_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/AlignOf.h"
@@ -68,9 +68,9 @@ public:
/// \endcode
///
///
-/// An implicit conversion to bool provides a way to check if there was an
-/// error. The unary * and -> operators provide pointer like access to the
-/// value. Accessing the value when there is an error has undefined behavior.
+/// Implicit conversion to bool returns true if there is a usable value. The
+/// unary * and -> operators provide pointer like access to the value. Accessing
+/// the value when there is an error has undefined behavior.
///
/// When T is a reference type the behaivor is slightly different. The reference
/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
@@ -115,19 +115,19 @@ public:
}
template <class OtherT>
- ErrorOr(const ErrorOr<OtherT> &Other) {
+ ErrorOr(
+ const ErrorOr<OtherT> &Other,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
+ nullptr) {
copyConstruct(Other);
}
- ErrorOr &operator =(const ErrorOr &Other) {
- copyAssign(Other);
- return *this;
- }
-
template <class OtherT>
- ErrorOr &operator =(const ErrorOr<OtherT> &Other) {
- copyAssign(Other);
- return *this;
+ explicit ErrorOr(
+ const ErrorOr<OtherT> &Other,
+ typename std::enable_if<
+ !std::is_convertible<OtherT, const T &>::value>::type * = nullptr) {
+ copyConstruct(Other);
}
ErrorOr(ErrorOr &&Other) {
@@ -135,17 +135,29 @@ public:
}
template <class OtherT>
- ErrorOr(ErrorOr<OtherT> &&Other) {
+ ErrorOr(
+ ErrorOr<OtherT> &&Other,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
+ nullptr) {
moveConstruct(std::move(Other));
}
- ErrorOr &operator =(ErrorOr &&Other) {
- moveAssign(std::move(Other));
+ // This might eventually need SFINAE but it's more complex than is_convertible
+ // & I'm too lazy to write it right now.
+ template <class OtherT>
+ explicit ErrorOr(
+ ErrorOr<OtherT> &&Other,
+ typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
+ nullptr) {
+ moveConstruct(std::move(Other));
+ }
+
+ ErrorOr &operator=(const ErrorOr &Other) {
+ copyAssign(Other);
return *this;
}
- template <class OtherT>
- ErrorOr &operator =(ErrorOr<OtherT> &&Other) {
+ ErrorOr &operator=(ErrorOr &&Other) {
moveAssign(std::move(Other));
return *this;
}
@@ -161,7 +173,7 @@ public:
}
reference get() { return *getStorage(); }
- const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
+ const_reference get() const { return const_cast<ErrorOr<T> *>(this)->get(); }
std::error_code getError() const {
return HasError ? *getErrorStorage() : std::error_code();