Ver Fonte

[Support][ErrorOr] Add support for convertable types.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174357 91177308-0d34-0410-b5e6-96231b3b80d8
Michael J. Spencer há 12 anos atrás
pai
commit
a33e1fafac
2 ficheiros alterados com 16 adições e 3 exclusões
  1. 5 3
      include/llvm/Support/ErrorOr.h
  2. 11 0
      unittests/Support/ErrorOrTest.cpp

+ 5 - 3
include/llvm/Support/ErrorOr.h

@@ -162,6 +162,7 @@ public:
 /// T cannot be a rvalue reference.
 template<class T>
 class ErrorOr {
+  template <class OtherT> friend class ErrorOr;
   static const bool isRef = is_reference<T>::value;
   typedef ReferenceStorage<typename remove_reference<T>::type> wrap;
 
@@ -198,7 +199,8 @@ public:
     new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
   }
 
-  ErrorOr(const ErrorOr &Other) : IsValid(false) {
+  template <class OtherT>
+  ErrorOr(ErrorOr<OtherT> &Other) : IsValid(false) {
     // Construct an invalid ErrorOr if other is invalid.
     if (!Other.IsValid)
       return;
@@ -227,7 +229,8 @@ public:
   }
 
 #if LLVM_HAS_RVALUE_REFERENCES
-  ErrorOr(ErrorOr &&Other) : IsValid(false) {
+  template <class OtherT>
+  ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
     // Construct an invalid ErrorOr if other is invalid.
     if (!Other.IsValid)
       return;
@@ -311,7 +314,6 @@ private:
     return &Val->get();
   }
 
-protected:
   storage_type *get() {
     assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
     assert(!HasError && "Cannot get value when an error exists!");

+ 11 - 0
unittests/Support/ErrorOrTest.cpp

@@ -53,6 +53,17 @@ TEST(ErrorOr, Types) {
   EXPECT_EQ(3, **t3());
 #endif
 }
+
+struct B {};
+struct D : B {};
+
+TEST(ErrorOr, Covariant) {
+  ErrorOr<B*> b(ErrorOr<D*>(0));
+
+#if LLVM_HAS_CXX11_STDLIB
+  ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(0));
+#endif
+}
 } // end anon namespace
 
 struct InvalidArgError {