diff options
author | Michael Gottesman <mgottesman@apple.com> | 2014-12-31 23:33:18 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2014-12-31 23:33:18 +0000 |
commit | 77b1aa98ed886df65c294d711eb2ca31f39eeee3 (patch) | |
tree | 494caac21a90df01e199b9733f09664caa8285fd /llvm | |
parent | 0ba09e6b843995837862e841e0184d4af19e1b05 (diff) | |
download | bcm5719-llvm-77b1aa98ed886df65c294d711eb2ca31f39eeee3.tar.gz bcm5719-llvm-77b1aa98ed886df65c294d711eb2ca31f39eeee3.zip |
Add an ArrayRef upcasting constructor from ArrayRef<U*> -> ArrayRef<T*> where T is a base of U.
llvm-svn: 225053
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ADT/ArrayRef.h | 10 | ||||
-rw-r--r-- | llvm/unittests/ADT/ArrayRefTest.cpp | 35 |
2 files changed, 45 insertions, 0 deletions
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h index 8c14a423c8f..b93142d90bc 100644 --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -112,6 +112,16 @@ namespace llvm { std::is_convertible<U *const *, T const *>::value>::type* = 0) : Data(A.data()), Length(A.size()) {} + /// Construct an ArrayRef<T*> from an ArrayRef<U*> where T is a super class + /// of U. This uses SFINAE to ensure that only ArrayRefs with this property + /// can be converted. This is an upcasting constructor. + template <typename U> + ArrayRef(const ArrayRef<U> &A, + typename std::enable_if<std::is_base_of< + typename std::remove_pointer<T>::type, + typename std::remove_pointer<U>::type>::value>::type * = 0) + : Data(reinterpret_cast<T const *>(A.data())), Length(A.size()) {} + /// @} /// @name Simple Operations /// @{ diff --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp index f9c98a563fa..9cd17f00d9a 100644 --- a/llvm/unittests/ADT/ArrayRefTest.cpp +++ b/llvm/unittests/ADT/ArrayRefTest.cpp @@ -90,4 +90,39 @@ TEST(ArrayRefTest, ConstConvert) { a = ArrayRef<int *>(A); } +struct A { + int data; + + A() : data(0) {} +}; + +struct B : A { + int data2; + + B() : A(), data2(0) {} +}; + +TEST(ArrayRefTest, UpcastConvert) { + B Data[5]; + + for (unsigned i = 0, e = 5; i != e; ++i) { + Data[i].data = i + 5; + Data[i].data2 = i + 30; + } + + B *DataPtrs[5]; + for (unsigned i = 0, e = 5; i != e; ++i) { + DataPtrs[i] = &Data[i]; + } + + ArrayRef<B *> BArray(DataPtrs, 5); + ArrayRef<A *> AArray(BArray); + + EXPECT_TRUE(AArray.size() == 5); + for (unsigned i = 0, e = 5; i != e; ++i) { + A *a = AArray[i]; + EXPECT_TRUE(a->data == int(i + 5)); + } +} + } // end anonymous namespace |