public:
ErrorOr() : IsValid(false) {}
+ template <class E>
+ ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value,
+ void *>::type = 0)
+ : HasError(true), IsValid(true) {
+ Error = new ErrorHolderBase;
+ Error->Error = make_error_code(ErrorCode);
+ Error->HasUserData = false;
+ }
+
ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
Error = new ErrorHolderBase;
Error->Error = EC;
new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
}
+ ErrorOr(const ErrorOr &Other) : IsValid(false) {
+ copyConstruct(Other);
+ }
+
template <class OtherT>
- ErrorOr(ErrorOr<OtherT> &Other) : IsValid(false) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
- if (!Other.HasError) {
- // Get the other value.
- HasError = false;
- new (get()) storage_type(*Other.get());
- } else {
- // Get other's error.
- Error = Other.Error;
- HasError = true;
- Error->aquire();
- }
+ ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) {
+ copyConstruct(Other);
}
ErrorOr &operator =(const ErrorOr &Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(Other);
+ copyAssign(Other);
+ return *this;
+ }
+ template <class OtherT>
+ ErrorOr &operator =(const ErrorOr<OtherT> &Other) {
+ copyAssign(Other);
return *this;
}
#if LLVM_HAS_RVALUE_REFERENCES
+ ErrorOr(ErrorOr &&Other) : IsValid(false) {
+ moveConstruct(std::move(Other));
+ }
+
template <class OtherT>
ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
- // Construct an invalid ErrorOr if other is invalid.
- if (!Other.IsValid)
- return;
- IsValid = true;
- if (!Other.HasError) {
- // Get the other value.
- HasError = false;
- new (get()) storage_type(std::move(*Other.get()));
- // Tell other not to do any destruction.
- Other.IsValid = false;
- } else {
- // Get other's error.
- Error = Other.Error;
- HasError = true;
- // Tell other not to do any destruction.
- Other.IsValid = false;
- }
+ moveConstruct(std::move(Other));
}
ErrorOr &operator =(ErrorOr &&Other) {
- if (this == &Other)
- return *this;
-
- this->~ErrorOr();
- new (this) ErrorOr(std::move(Other));
+ moveAssign(std::move(Other));
+ return *this;
+ }
+ template <class OtherT>
+ ErrorOr &operator =(ErrorOr<OtherT> &&Other) {
+ moveAssign(std::move(Other));
return *this;
}
#endif
}
private:
+ template <class OtherT>
+ void copyConstruct(const ErrorOr<OtherT> &Other) {
+ // Construct an invalid ErrorOr if other is invalid.
+ if (!Other.IsValid)
+ return;
+ IsValid = true;
+ if (!Other.HasError) {
+ // Get the other value.
+ HasError = false;
+ new (get()) storage_type(*Other.get());
+ } else {
+ // Get other's error.
+ Error = Other.Error;
+ HasError = true;
+ Error->aquire();
+ }
+ }
+
+ template <class T1>
+ static bool compareThisIfSameType(const T1 &a, const T1 &b) {
+ return &a == &b;
+ }
+
+ template <class T1, class T2>
+ static bool compareThisIfSameType(const T1 &a, const T2 &b) {
+ return false;
+ }
+
+ template <class OtherT>
+ void copyAssign(const ErrorOr<OtherT> &Other) {
+ if (compareThisIfSameType(*this, Other))
+ return;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(Other);
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCES
+ template <class OtherT>
+ void moveConstruct(ErrorOr<OtherT> &&Other) {
+ // Construct an invalid ErrorOr if other is invalid.
+ if (!Other.IsValid)
+ return;
+ IsValid = true;
+ if (!Other.HasError) {
+ // Get the other value.
+ HasError = false;
+ new (get()) storage_type(std::move(*Other.get()));
+ // Tell other not to do any destruction.
+ Other.IsValid = false;
+ } else {
+ // Get other's error.
+ Error = Other.Error;
+ HasError = true;
+ // Tell other not to do any destruction.
+ Other.IsValid = false;
+ }
+ }
+
+ template <class OtherT>
+ void moveAssign(ErrorOr<OtherT> &&Other) {
+ if (compareThisIfSameType(*this, Other))
+ return;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(std::move(Other));
+ }
+#endif
+
pointer toPointer(pointer Val) {
return Val;
}
public:
ErrorOr() : Error(0, 0) {}
+ template <class E>
+ ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value,
+ void *> ::type = 0)
+ : Error(0, 0) {
+ error_code EC = make_error_code(ErrorCode);
+ if (EC == errc::success) {
+ Error.setInt(1);
+ return;
+ }
+ ErrorHolderBase *EHB = new ErrorHolderBase;
+ EHB->Error = EC;
+ EHB->HasUserData = false;
+ Error.setPointer(EHB);
+ }
+
ErrorOr(llvm::error_code EC) : Error(0, 0) {
if (EC == errc::success) {
Error.setInt(1);