diff options
Diffstat (limited to 'include/llvm/Support/ErrorOr.h')
-rw-r--r-- | include/llvm/Support/ErrorOr.h | 52 |
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(); |