brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.6 KiB · 736c8fb Raw
500 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/ArrayRef.h"10#include "llvm/Support/Allocator.h"11#include "gtest/gtest.h"12#include <limits>13#include <vector>14#if __has_include(<version>)15#include <version>16#endif17#ifdef __cpp_lib_span18#include <span>19#endif20 21using namespace llvm;22 23// Check that the ArrayRef-of-pointer converting constructor only allows adding24// cv qualifiers (not removing them, or otherwise changing the type)25static_assert(std::is_convertible_v<ArrayRef<int *>, ArrayRef<const int *>>,26              "Adding const");27static_assert(std::is_convertible_v<ArrayRef<int *>, ArrayRef<volatile int *>>,28              "Adding volatile");29static_assert(!std::is_convertible_v<ArrayRef<int *>, ArrayRef<float *>>,30              "Changing pointer of one type to a pointer of another");31static_assert(!std::is_convertible_v<ArrayRef<const int *>, ArrayRef<int *>>,32              "Removing const");33static_assert(!std::is_convertible_v<ArrayRef<volatile int *>, ArrayRef<int *>>,34              "Removing volatile");35 36// Check that we can't accidentally assign a temporary location to an ArrayRef.37// (Unfortunately we can't make use of the same thing with constructors.)38static_assert(!std::is_assignable_v<ArrayRef<int *> &, int *>,39              "Assigning from single prvalue element");40static_assert(!std::is_assignable_v<ArrayRef<int *> &, int *&&>,41              "Assigning from single xvalue element");42static_assert(std::is_assignable_v<ArrayRef<int *> &, int *&>,43              "Assigning from single lvalue element");44static_assert(45    !std::is_assignable_v<ArrayRef<int *> &, std::initializer_list<int *>>,46    "Assigning from an initializer list");47 48namespace {49 50TEST(ArrayRefTest, AllocatorCopy) {51  BumpPtrAllocator Alloc;52  static const uint16_t Words1[] = { 1, 4, 200, 37 };53  ArrayRef<uint16_t> Array1 = ArrayRef(Words1, 4);54  static const uint16_t Words2[] = { 11, 4003, 67, 64000, 13 };55  ArrayRef<uint16_t> Array2 = ArrayRef(Words2, 5);56  ArrayRef<uint16_t> Array1c = Array1.copy(Alloc);57  ArrayRef<uint16_t> Array2c = Array2.copy(Alloc);58  EXPECT_TRUE(Array1.equals(Array1c));59  EXPECT_NE(Array1.data(), Array1c.data());60  EXPECT_TRUE(Array2.equals(Array2c));61  EXPECT_NE(Array2.data(), Array2c.data());62 63  // Check that copy can cope with uninitialized memory.64  struct NonAssignable {65    const char *Ptr;66 67    NonAssignable(const char *Ptr) : Ptr(Ptr) {}68    NonAssignable(const NonAssignable &RHS) = default;69    void operator=(const NonAssignable &RHS) { assert(RHS.Ptr != nullptr); }70    bool operator==(const NonAssignable &RHS) const { return Ptr == RHS.Ptr; }71  } Array3Src[] = {"hello", "world"};72  ArrayRef<NonAssignable> Array3Copy = ArrayRef(Array3Src).copy(Alloc);73  EXPECT_EQ(ArrayRef(Array3Src), Array3Copy);74  EXPECT_NE(ArrayRef(Array3Src).data(), Array3Copy.data());75}76 77// This test is pure UB given the ArrayRef<> implementation.78// You are not allowed to produce non-null pointers given null base pointer.79TEST(ArrayRefTest, DISABLED_SizeTSizedOperations) {80  ArrayRef<char> AR(nullptr, std::numeric_limits<ptrdiff_t>::max());81 82  // Check that drop_back accepts size_t-sized numbers.83  EXPECT_EQ(1U, AR.drop_back(AR.size() - 1).size());84 85  // Check that drop_front accepts size_t-sized numbers.86  EXPECT_EQ(1U, AR.drop_front(AR.size() - 1).size());87 88  // Check that slice accepts size_t-sized numbers.89  EXPECT_EQ(1U, AR.slice(AR.size() - 1).size());90  EXPECT_EQ(AR.size() - 1, AR.slice(1, AR.size() - 1).size());91}92 93TEST(ArrayRefTest, DropBack) {94  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};95  ArrayRef<int> AR1(TheNumbers);96  ArrayRef<int> AR2(TheNumbers, AR1.size() - 1);97  EXPECT_TRUE(AR1.drop_back().equals(AR2));98}99 100TEST(ArrayRefTest, DropFront) {101  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};102  ArrayRef<int> AR1(TheNumbers);103  ArrayRef<int> AR2(&TheNumbers[2], AR1.size() - 2);104  EXPECT_TRUE(AR1.drop_front(2).equals(AR2));105}106 107TEST(ArrayRefTest, ConsumeFront) {108  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};109  ArrayRef<int> AR1(TheNumbers);110  ArrayRef<int> AR2(&TheNumbers[2], AR1.size() - 2);111  EXPECT_EQ(&AR1.consume_front(), &TheNumbers[0]);112  EXPECT_EQ(&AR1.consume_front(), &TheNumbers[1]);113  EXPECT_TRUE(AR1.equals(AR2));114}115 116TEST(ArrayRefTest, ConsumeBack) {117  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};118  ArrayRef<int> AR1(TheNumbers);119  ArrayRef<int> AR2(TheNumbers, AR1.size() - 2);120  EXPECT_EQ(&AR1.consume_back(), &TheNumbers[5]);121  EXPECT_EQ(&AR1.consume_back(), &TheNumbers[4]);122  EXPECT_TRUE(AR1.equals(AR2));123}124 125TEST(ArrayRefTest, MutableArryaRefConsumeFront) {126  int TheNumbers[] = {4, 8, 15, 16, 23, 42};127  MutableArrayRef<int> AR1(TheNumbers);128  MutableArrayRef<int> AR2(&TheNumbers[2], AR1.size() - 2);129  EXPECT_EQ(&AR1.consume_front(), &TheNumbers[0]);130  EXPECT_EQ(&AR1.consume_front(), &TheNumbers[1]);131  EXPECT_TRUE(AR1.equals(AR2));132 133  AR1.consume_front() = 33;134  EXPECT_EQ(TheNumbers[2], 33);135}136 137TEST(ArrayRefTest, MutableArryaRefConsumeBack) {138  int TheNumbers[] = {4, 8, 15, 16, 23, 42};139  MutableArrayRef<int> AR1(TheNumbers);140  MutableArrayRef<int> AR2(TheNumbers, AR1.size() - 2);141  EXPECT_EQ(&AR1.consume_back(), &TheNumbers[5]);142  EXPECT_EQ(&AR1.consume_back(), &TheNumbers[4]);143  EXPECT_TRUE(AR1.equals(AR2));144 145  AR1.consume_back() = 33;146  EXPECT_EQ(TheNumbers[3], 33);147}148 149TEST(ArrayRefTest, DropWhile) {150  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};151  ArrayRef<int> AR1(TheNumbers);152  ArrayRef<int> Expected = AR1.drop_front(3);153  EXPECT_EQ(Expected, AR1.drop_while([](const int &N) { return N % 2 == 1; }));154 155  EXPECT_EQ(AR1, AR1.drop_while([](const int &N) { return N < 0; }));156  EXPECT_EQ(ArrayRef<int>(),157            AR1.drop_while([](const int &N) { return N > 0; }));158}159 160TEST(ArrayRefTest, DropUntil) {161  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};162  ArrayRef<int> AR1(TheNumbers);163  ArrayRef<int> Expected = AR1.drop_front(3);164  EXPECT_EQ(Expected, AR1.drop_until([](const int &N) { return N % 2 == 0; }));165 166  EXPECT_EQ(ArrayRef<int>(),167            AR1.drop_until([](const int &N) { return N < 0; }));168  EXPECT_EQ(AR1, AR1.drop_until([](const int &N) { return N > 0; }));169}170 171TEST(ArrayRefTest, TakeBack) {172  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};173  ArrayRef<int> AR1(TheNumbers);174  ArrayRef<int> AR2(AR1.end() - 1, 1);175  EXPECT_TRUE(AR1.take_back().equals(AR2));176}177 178TEST(ArrayRefTest, TakeFront) {179  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};180  ArrayRef<int> AR1(TheNumbers);181  ArrayRef<int> AR2(AR1.data(), 2);182  EXPECT_TRUE(AR1.take_front(2).equals(AR2));183}184 185TEST(ArrayRefTest, TakeWhile) {186  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};187  ArrayRef<int> AR1(TheNumbers);188  ArrayRef<int> Expected = AR1.take_front(3);189  EXPECT_EQ(Expected, AR1.take_while([](const int &N) { return N % 2 == 1; }));190 191  EXPECT_EQ(ArrayRef<int>(),192            AR1.take_while([](const int &N) { return N < 0; }));193  EXPECT_EQ(AR1, AR1.take_while([](const int &N) { return N > 0; }));194}195 196TEST(ArrayRefTest, TakeUntil) {197  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};198  ArrayRef<int> AR1(TheNumbers);199  ArrayRef<int> Expected = AR1.take_front(3);200  EXPECT_EQ(Expected, AR1.take_until([](const int &N) { return N % 2 == 0; }));201 202  EXPECT_EQ(AR1, AR1.take_until([](const int &N) { return N < 0; }));203  EXPECT_EQ(ArrayRef<int>(),204            AR1.take_until([](const int &N) { return N > 0; }));205}206 207TEST(ArrayRefTest, Equals) {208  static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};209  ArrayRef<int> AR1(A1);210  EXPECT_TRUE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8}));211  EXPECT_FALSE(AR1.equals({8, 1, 2, 4, 5, 6, 6, 7}));212  EXPECT_FALSE(AR1.equals({2, 4, 5, 6, 6, 7, 8, 1}));213  EXPECT_FALSE(AR1.equals({0, 1, 2, 4, 5, 6, 6, 7}));214  EXPECT_FALSE(AR1.equals({1, 2, 42, 4, 5, 6, 7, 8}));215  EXPECT_FALSE(AR1.equals({42, 2, 3, 4, 5, 6, 7, 8}));216  EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 42}));217  EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7}));218  EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8, 9}));219 220  ArrayRef<int> AR1a = AR1.drop_back();221  EXPECT_TRUE(AR1a.equals({1, 2, 3, 4, 5, 6, 7}));222  EXPECT_FALSE(AR1a.equals({1, 2, 3, 4, 5, 6, 7, 8}));223 224  ArrayRef<int> AR1b = AR1a.slice(2, 4);225  EXPECT_TRUE(AR1b.equals({3, 4, 5, 6}));226  EXPECT_FALSE(AR1b.equals({2, 3, 4, 5, 6}));227  EXPECT_FALSE(AR1b.equals({3, 4, 5, 6, 7}));228}229 230TEST(ArrayRefTest, EmptyEquals) {231  EXPECT_TRUE(ArrayRef<unsigned>() == ArrayRef<unsigned>());232}233 234TEST(ArrayRefTest, Compare) {235  ArrayRef<char> Ban("Ban");236  ArrayRef<char> Banana("Banana");237  ArrayRef<char> Band("Band");238 239  EXPECT_TRUE(Ban < Banana);240  EXPECT_TRUE(Ban <= Banana);241  EXPECT_FALSE(Ban > Banana);242  EXPECT_FALSE(Ban >= Banana);243 244  EXPECT_FALSE(Banana < Banana);245  EXPECT_TRUE(Banana <= Banana);246  EXPECT_FALSE(Banana > Banana);247  EXPECT_TRUE(Banana >= Banana);248 249  EXPECT_TRUE(Banana < Band);250  EXPECT_TRUE(Banana <= Band);251  EXPECT_FALSE(Banana > Band);252  EXPECT_FALSE(Banana >= Band);253}254 255TEST(ArrayRefTest, ConstConvert) {256  int buf[4];257  for (int i = 0; i < 4; ++i)258    buf[i] = i;259 260  static int *A[] = {&buf[0], &buf[1], &buf[2], &buf[3]};261  ArrayRef<const int *> a((ArrayRef<int *>(A)));262  a = ArrayRef<int *>(A);263}264 265static std::vector<int> ReturnTest12() { return {1, 2}; }266static void ArgTest12(ArrayRef<int> A) {267  EXPECT_EQ(2U, A.size());268  EXPECT_EQ(1, A[0]);269  EXPECT_EQ(2, A[1]);270}271 272TEST(ArrayRefTest, InitializerList) {273  std::initializer_list<int> init_list = { 0, 1, 2, 3, 4 };274  ArrayRef<int> A = init_list;275  for (int i = 0; i < 5; ++i)276    EXPECT_EQ(i, A[i]);277 278  std::vector<int> B = ReturnTest12();279  A = B;280  EXPECT_EQ(1, A[0]);281  EXPECT_EQ(2, A[1]);282 283  ArgTest12({1, 2});284}285 286TEST(ArrayRefTest, EmptyInitializerList) {287  ArrayRef<int> A = {};288  EXPECT_TRUE(A.empty());289 290  A = {};291  EXPECT_TRUE(A.empty());292}293 294TEST(ArrayRefTest, ArrayRef) {295  static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};296 297  // A copy is expected for non-const ArrayRef (thin copy)298  ArrayRef<int> AR1(A1);299  const ArrayRef<int> &AR1Ref = ArrayRef(AR1);300  EXPECT_NE(&AR1, &AR1Ref);301  EXPECT_TRUE(AR1.equals(AR1Ref));302 303  // A copy is expected for non-const ArrayRef (thin copy)304  const ArrayRef<int> AR2(A1);305  const ArrayRef<int> &AR2Ref = ArrayRef(AR2);306  EXPECT_NE(&AR2Ref, &AR2);307  EXPECT_TRUE(AR2.equals(AR2Ref));308}309 310TEST(ArrayRefTest, OwningArrayRef) {311  static const int A1[] = {0, 1};312  OwningArrayRef<int> A{ArrayRef(A1)};313  OwningArrayRef<int> B(std::move(A));314  EXPECT_EQ(A.data(), nullptr);315}316 317TEST(ArrayRefTest, ArrayRefFromStdArray) {318  std::array<int, 5> A1{{42, -5, 0, 1000000, -1000000}};319  ArrayRef<int> A2 = ArrayRef(A1);320 321  EXPECT_EQ(A1.size(), A2.size());322  for (std::size_t i = 0; i < A1.size(); ++i) {323    EXPECT_EQ(A1[i], A2[i]);324  }325}326 327struct TestRandomAccessIterator {328  using iterator_category = std::random_access_iterator_tag;329};330 331static_assert(!std::is_constructible_v<332                  ArrayRef<int>, iterator_range<TestRandomAccessIterator>>,333              "cannot construct from iterator range with non-pointer iterator");334static_assert(!std::is_constructible_v<ArrayRef<int>, iterator_range<int>>,335              "cannot construct from iterator range with non-pointer iterator");336 337class TestBase {};338 339class TestDerived : public TestBase {};340 341static_assert(342    !std::is_constructible_v<ArrayRef<TestDerived>, iterator_range<TestBase *>>,343    "cannot construct ArrayRef with derived type");344static_assert(345    !std::is_constructible_v<ArrayRef<TestBase>, iterator_range<TestDerived *>>,346    "cannot construct ArrayRef base type");347static_assert(!std::is_constructible_v<ArrayRef<TestBase *>,348                                       iterator_range<TestDerived **>>,349              "cannot construct ArrayRef pointer of base type");350 351static_assert(352    !std::is_constructible_v<ArrayRef<int>, iterator_range<const int *>>,353    "cannot construct ArrayRef with non-const elements from const iterator "354    "range");355static_assert(356    std::is_constructible_v<ArrayRef<char *>, iterator_range<char **>>,357    "should be able to construct ArrayRef from iterator_range over pointers");358static_assert(359    !std::is_constructible_v<ArrayRef<char *>, iterator_range<char *const *>>,360    "should be able to construct ArrayRef from iterator_range over pointers");361 362TEST(ArrayRefTest, ArrayRefFromIteratorRange) {363  int A1[] = {42, -5, 0, 1000000, -1000000, 0};364  ArrayRef<int> A2 = make_range(&A1[0], &A1[5]);365 366  EXPECT_EQ(5ull, A2.size());367  for (std::size_t i = 0; i < A2.size(); ++i)368    EXPECT_EQ(A1[i], A2[i]);369 370  ArrayRef<const int> A3 = make_range(&A1[0], &A1[5]);371  EXPECT_EQ(5ull, A3.size());372  for (std::size_t i = 0; i < A3.size(); ++i)373    EXPECT_EQ(A1[i], A3[i]);374}375 376TEST(ArrayRefTest, ArrayRefFromIteratorConstRange) {377  const int A1[] = {42, -5, 0, 1000000, -1000000, 0};378  ArrayRef<const int> A2 = make_range(&A1[0], &A1[5]);379 380  EXPECT_EQ(5ull, A2.size());381  for (std::size_t i = 0; i < A2.size(); ++i)382    EXPECT_EQ(A1[i], A2[i]);383}384 385static_assert(std::is_trivially_copyable_v<ArrayRef<int>>,386              "trivially copyable");387 388TEST(ArrayRefTest, MutableArrayRefDeductionGuides) {389  // Single element390  {391    int x = 0;392    auto aref = MutableArrayRef(x);393    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);394    EXPECT_EQ(aref.data(), &x);395    EXPECT_EQ(aref.size(), 1u);396 397    // Make sure it's mutable still398    aref[0] = 1;399    EXPECT_EQ(x, 1);400  }401 402  // Pointer + length403  {404    int x[] = {0, 1, 2, 3};405    auto aref = MutableArrayRef(&x[0], 4);406    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);407    EXPECT_EQ(aref.data(), &x[0]);408    EXPECT_EQ(aref.size(), 4u);409  }410 411  // // Pointer + pointer412  {413    int x[] = {0, 1, 2, 3};414    auto aref = MutableArrayRef(std::begin(x), std::end(x));415    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);416    EXPECT_EQ(aref.data(), &x[0]);417    EXPECT_EQ(aref.size(), 4u);418  }419 420  // SmallVector421  {422    SmallVector<int> sv1;423    SmallVectorImpl<int> &sv2 = sv1;424    sv1.resize(5);425    auto aref1 = MutableArrayRef(sv1);426    auto aref2 = MutableArrayRef(sv2);427    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref1)>);428    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref2)>);429    EXPECT_EQ(aref1.data(), sv1.data());430    EXPECT_EQ(aref1.size(), sv1.size());431    EXPECT_EQ(aref2.data(), sv2.data());432    EXPECT_EQ(aref2.size(), sv2.size());433  }434 435  // std::vector436  {437    std::vector<int> x(5);438    auto aref = MutableArrayRef(x);439    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);440    EXPECT_EQ(aref.data(), x.data());441    EXPECT_EQ(aref.size(), x.size());442  }443 444  // std::array445  {446    std::array<int, 5> x{};447    auto aref = MutableArrayRef(x);448    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);449    EXPECT_EQ(aref.data(), x.data());450    EXPECT_EQ(aref.size(), x.size());451  }452 453  // MutableArrayRef454  {455    MutableArrayRef<int> x{};456    auto aref = MutableArrayRef(x);457    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);458    EXPECT_EQ(aref.data(), x.data());459    EXPECT_EQ(aref.size(), x.size());460 461    const MutableArrayRef<int> y{};462    auto aref2 = MutableArrayRef(y);463    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref2)>);464    EXPECT_EQ(aref2.data(), y.data());465    EXPECT_EQ(aref2.size(), y.size());466  }467 468  // C-style array469  {470    int x[] = {0, 1, 2, 3};471    auto aref = MutableArrayRef(x);472    static_assert(std::is_same_v<MutableArrayRef<int>, decltype(aref)>);473    EXPECT_EQ(aref.data(), &x[0]);474    EXPECT_EQ(aref.size(), 4u);475  }476}477 478#ifdef __cpp_lib_span479static_assert(std::is_constructible_v<ArrayRef<int>, std::span<const int>>,480              "should be able to construct ArrayRef from const std::span");481static_assert(std::is_constructible_v<std::span<const int>, ArrayRef<int>>,482              "should be able to construct const std::span from ArrayRef");483static_assert(std::is_constructible_v<ArrayRef<int>, std::span<int>>,484              "should be able to construct ArrayRef from mutable std::span");485static_assert(!std::is_constructible_v<std::span<int>, ArrayRef<int>>,486              "cannot construct mutable std::span from ArrayRef");487 488static_assert(489    !std::is_constructible_v<MutableArrayRef<int>, std::span<const int>>,490    "cannot construct MutableArrayRef from const std::span");491static_assert(492    std::is_constructible_v<std::span<const int>, MutableArrayRef<int>>,493    "should be able to construct const std::span from MutableArrayRef");494static_assert(495    std::is_constructible_v<MutableArrayRef<int>, std::span<int>>,496    "should be able to construct MutableArrayRef from mutable std::span");497#endif498 499} // end anonymous namespace500