Revert "Windows: Add support for unicode command lines"
[oota-llvm.git] / include / llvm / Support / ErrorOr.h
index c22c3ca84ff6ce683943f6762532b51fdf6d33dc..f3ac305fe77560f34fc549ff953e02be22598be3 100644 (file)
@@ -180,6 +180,16 @@ private:
 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;
@@ -199,63 +209,44 @@ public:
     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
@@ -303,6 +294,75 @@ public:
   }
 
 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;
   }
@@ -337,6 +397,22 @@ class ErrorOr<void> {
 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);