1 //===- llvm/unittest/ADT/ArrayRefTest.cpp - ArrayRef unit tests -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/ArrayRef.h" 10 #include "llvm/Support/Allocator.h" 11 #include "llvm/Support/raw_ostream.h" 12 #include "gtest/gtest.h" 13 #include <limits> 14 #include <vector> 15 using namespace llvm; 16 17 // Check that the ArrayRef-of-pointer converting constructor only allows adding 18 // cv qualifiers (not removing them, or otherwise changing the type) 19 static_assert( 20 std::is_convertible<ArrayRef<int *>, ArrayRef<const int *>>::value, 21 "Adding const"); 22 static_assert( 23 std::is_convertible<ArrayRef<int *>, ArrayRef<volatile int *>>::value, 24 "Adding volatile"); 25 static_assert(!std::is_convertible<ArrayRef<int *>, ArrayRef<float *>>::value, 26 "Changing pointer of one type to a pointer of another"); 27 static_assert( 28 !std::is_convertible<ArrayRef<const int *>, ArrayRef<int *>>::value, 29 "Removing const"); 30 static_assert( 31 !std::is_convertible<ArrayRef<volatile int *>, ArrayRef<int *>>::value, 32 "Removing volatile"); 33 34 // Check that we can't accidentally assign a temporary location to an ArrayRef. 35 // (Unfortunately we can't make use of the same thing with constructors.) 36 // 37 // Disable this check under MSVC; even MSVC 2015 isn't inconsistent between 38 // std::is_assignable and actually writing such an assignment. 39 #if !defined(_MSC_VER) 40 static_assert( 41 !std::is_assignable<ArrayRef<int *>&, int *>::value, 42 "Assigning from single prvalue element"); 43 static_assert( 44 !std::is_assignable<ArrayRef<int *>&, int * &&>::value, 45 "Assigning from single xvalue element"); 46 static_assert( 47 std::is_assignable<ArrayRef<int *>&, int * &>::value, 48 "Assigning from single lvalue element"); 49 static_assert( 50 !std::is_assignable<ArrayRef<int *>&, std::initializer_list<int *>>::value, 51 "Assigning from an initializer list"); 52 #endif 53 54 // Check Typedefs. 55 static_assert( 56 std::is_same<ArrayRef<int>::value_type, int>::value, 57 "erroneous value_type"); 58 static_assert( 59 std::is_same<ArrayRef<const int>::value_type, int>::value, 60 "erroneous value_type"); 61 62 namespace { 63 64 TEST(ArrayRefTest, AllocatorCopy) { 65 BumpPtrAllocator Alloc; 66 static const uint16_t Words1[] = { 1, 4, 200, 37 }; 67 ArrayRef<uint16_t> Array1 = makeArrayRef(Words1, 4); 68 static const uint16_t Words2[] = { 11, 4003, 67, 64000, 13 }; 69 ArrayRef<uint16_t> Array2 = makeArrayRef(Words2, 5); 70 ArrayRef<uint16_t> Array1c = Array1.copy(Alloc); 71 ArrayRef<uint16_t> Array2c = Array2.copy(Alloc); 72 EXPECT_TRUE(Array1.equals(Array1c)); 73 EXPECT_NE(Array1.data(), Array1c.data()); 74 EXPECT_TRUE(Array2.equals(Array2c)); 75 EXPECT_NE(Array2.data(), Array2c.data()); 76 77 // Check that copy can cope with uninitialized memory. 78 struct NonAssignable { 79 const char *Ptr; 80 81 NonAssignable(const char *Ptr) : Ptr(Ptr) {} 82 NonAssignable(const NonAssignable &RHS) = default; 83 void operator=(const NonAssignable &RHS) { assert(RHS.Ptr != nullptr); } 84 bool operator==(const NonAssignable &RHS) const { return Ptr == RHS.Ptr; } 85 } Array3Src[] = {"hello", "world"}; 86 ArrayRef<NonAssignable> Array3Copy = makeArrayRef(Array3Src).copy(Alloc); 87 EXPECT_EQ(makeArrayRef(Array3Src), Array3Copy); 88 EXPECT_NE(makeArrayRef(Array3Src).data(), Array3Copy.data()); 89 } 90 91 TEST(ArrayRefTest, SizeTSizedOperations) { 92 ArrayRef<char> AR(nullptr, std::numeric_limits<ptrdiff_t>::max()); 93 94 // Check that drop_back accepts size_t-sized numbers. 95 EXPECT_EQ(1U, AR.drop_back(AR.size() - 1).size()); 96 97 // Check that drop_front accepts size_t-sized numbers. 98 EXPECT_EQ(1U, AR.drop_front(AR.size() - 1).size()); 99 100 // Check that slice accepts size_t-sized numbers. 101 EXPECT_EQ(1U, AR.slice(AR.size() - 1).size()); 102 EXPECT_EQ(AR.size() - 1, AR.slice(1, AR.size() - 1).size()); 103 } 104 105 TEST(ArrayRefTest, DropBack) { 106 static const int TheNumbers[] = {4, 8, 15, 16, 23, 42}; 107 ArrayRef<int> AR1(TheNumbers); 108 ArrayRef<int> AR2(TheNumbers, AR1.size() - 1); 109 EXPECT_TRUE(AR1.drop_back().equals(AR2)); 110 } 111 112 TEST(ArrayRefTest, DropFront) { 113 static const int TheNumbers[] = {4, 8, 15, 16, 23, 42}; 114 ArrayRef<int> AR1(TheNumbers); 115 ArrayRef<int> AR2(&TheNumbers[2], AR1.size() - 2); 116 EXPECT_TRUE(AR1.drop_front(2).equals(AR2)); 117 } 118 119 TEST(ArrayRefTest, DropWhile) { 120 static const int TheNumbers[] = {1, 3, 5, 8, 10, 11}; 121 ArrayRef<int> AR1(TheNumbers); 122 ArrayRef<int> Expected = AR1.drop_front(3); 123 EXPECT_EQ(Expected, AR1.drop_while([](const int &N) { return N % 2 == 1; })); 124 125 EXPECT_EQ(AR1, AR1.drop_while([](const int &N) { return N < 0; })); 126 EXPECT_EQ(ArrayRef<int>(), 127 AR1.drop_while([](const int &N) { return N > 0; })); 128 } 129 130 TEST(ArrayRefTest, DropUntil) { 131 static const int TheNumbers[] = {1, 3, 5, 8, 10, 11}; 132 ArrayRef<int> AR1(TheNumbers); 133 ArrayRef<int> Expected = AR1.drop_front(3); 134 EXPECT_EQ(Expected, AR1.drop_until([](const int &N) { return N % 2 == 0; })); 135 136 EXPECT_EQ(ArrayRef<int>(), 137 AR1.drop_until([](const int &N) { return N < 0; })); 138 EXPECT_EQ(AR1, AR1.drop_until([](const int &N) { return N > 0; })); 139 } 140 141 TEST(ArrayRefTest, TakeBack) { 142 static const int TheNumbers[] = {4, 8, 15, 16, 23, 42}; 143 ArrayRef<int> AR1(TheNumbers); 144 ArrayRef<int> AR2(AR1.end() - 1, 1); 145 EXPECT_TRUE(AR1.take_back().equals(AR2)); 146 } 147 148 TEST(ArrayRefTest, TakeFront) { 149 static const int TheNumbers[] = {4, 8, 15, 16, 23, 42}; 150 ArrayRef<int> AR1(TheNumbers); 151 ArrayRef<int> AR2(AR1.data(), 2); 152 EXPECT_TRUE(AR1.take_front(2).equals(AR2)); 153 } 154 155 TEST(ArrayRefTest, TakeWhile) { 156 static const int TheNumbers[] = {1, 3, 5, 8, 10, 11}; 157 ArrayRef<int> AR1(TheNumbers); 158 ArrayRef<int> Expected = AR1.take_front(3); 159 EXPECT_EQ(Expected, AR1.take_while([](const int &N) { return N % 2 == 1; })); 160 161 EXPECT_EQ(ArrayRef<int>(), 162 AR1.take_while([](const int &N) { return N < 0; })); 163 EXPECT_EQ(AR1, AR1.take_while([](const int &N) { return N > 0; })); 164 } 165 166 TEST(ArrayRefTest, TakeUntil) { 167 static const int TheNumbers[] = {1, 3, 5, 8, 10, 11}; 168 ArrayRef<int> AR1(TheNumbers); 169 ArrayRef<int> Expected = AR1.take_front(3); 170 EXPECT_EQ(Expected, AR1.take_until([](const int &N) { return N % 2 == 0; })); 171 172 EXPECT_EQ(AR1, AR1.take_until([](const int &N) { return N < 0; })); 173 EXPECT_EQ(ArrayRef<int>(), 174 AR1.take_until([](const int &N) { return N > 0; })); 175 } 176 177 TEST(ArrayRefTest, Equals) { 178 static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8}; 179 ArrayRef<int> AR1(A1); 180 EXPECT_TRUE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8})); 181 EXPECT_FALSE(AR1.equals({8, 1, 2, 4, 5, 6, 6, 7})); 182 EXPECT_FALSE(AR1.equals({2, 4, 5, 6, 6, 7, 8, 1})); 183 EXPECT_FALSE(AR1.equals({0, 1, 2, 4, 5, 6, 6, 7})); 184 EXPECT_FALSE(AR1.equals({1, 2, 42, 4, 5, 6, 7, 8})); 185 EXPECT_FALSE(AR1.equals({42, 2, 3, 4, 5, 6, 7, 8})); 186 EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 42})); 187 EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7})); 188 EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8, 9})); 189 190 ArrayRef<int> AR1a = AR1.drop_back(); 191 EXPECT_TRUE(AR1a.equals({1, 2, 3, 4, 5, 6, 7})); 192 EXPECT_FALSE(AR1a.equals({1, 2, 3, 4, 5, 6, 7, 8})); 193 194 ArrayRef<int> AR1b = AR1a.slice(2, 4); 195 EXPECT_TRUE(AR1b.equals({3, 4, 5, 6})); 196 EXPECT_FALSE(AR1b.equals({2, 3, 4, 5, 6})); 197 EXPECT_FALSE(AR1b.equals({3, 4, 5, 6, 7})); 198 } 199 200 TEST(ArrayRefTest, EmptyEquals) { 201 EXPECT_TRUE(ArrayRef<unsigned>() == ArrayRef<unsigned>()); 202 } 203 204 TEST(ArrayRefTest, ConstConvert) { 205 int buf[4]; 206 for (int i = 0; i < 4; ++i) 207 buf[i] = i; 208 209 static int *A[] = {&buf[0], &buf[1], &buf[2], &buf[3]}; 210 ArrayRef<const int *> a((ArrayRef<int *>(A))); 211 a = ArrayRef<int *>(A); 212 } 213 214 static std::vector<int> ReturnTest12() { return {1, 2}; } 215 static void ArgTest12(ArrayRef<int> A) { 216 EXPECT_EQ(2U, A.size()); 217 EXPECT_EQ(1, A[0]); 218 EXPECT_EQ(2, A[1]); 219 } 220 221 TEST(ArrayRefTest, InitializerList) { 222 std::initializer_list<int> init_list = { 0, 1, 2, 3, 4 }; 223 ArrayRef<int> A = init_list; 224 for (int i = 0; i < 5; ++i) 225 EXPECT_EQ(i, A[i]); 226 227 std::vector<int> B = ReturnTest12(); 228 A = B; 229 EXPECT_EQ(1, A[0]); 230 EXPECT_EQ(2, A[1]); 231 232 ArgTest12({1, 2}); 233 } 234 235 TEST(ArrayRefTest, EmptyInitializerList) { 236 ArrayRef<int> A = {}; 237 EXPECT_TRUE(A.empty()); 238 239 A = {}; 240 EXPECT_TRUE(A.empty()); 241 } 242 243 // Test that makeArrayRef works on ArrayRef (no-op) 244 TEST(ArrayRefTest, makeArrayRef) { 245 static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8}; 246 247 // No copy expected for non-const ArrayRef (true no-op) 248 ArrayRef<int> AR1(A1); 249 ArrayRef<int> &AR1Ref = makeArrayRef(AR1); 250 EXPECT_EQ(&AR1, &AR1Ref); 251 252 // A copy is expected for non-const ArrayRef (thin copy) 253 const ArrayRef<int> AR2(A1); 254 const ArrayRef<int> &AR2Ref = makeArrayRef(AR2); 255 EXPECT_NE(&AR2Ref, &AR2); 256 EXPECT_TRUE(AR2.equals(AR2Ref)); 257 } 258 259 static_assert(is_trivially_copyable<ArrayRef<int>>::value, 260 "trivially copyable"); 261 262 } // end anonymous namespace 263