[Clang/AMDGPU] Zero sized arrays not allowed in HIP device code. (#113470)
[llvm-project.git] / llvm / unittests / ADT / RangeAdapterTest.cpp
blobc1a8a984f233b0206c5c257d3011cd6de677f22c
1 //===- RangeAdapterTest.cpp - Unit tests for range adapters --------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/STLExtras.h"
10 #include "gtest/gtest.h"
12 #include <iterator>
13 #include <list>
14 #include <vector>
16 using namespace llvm;
18 namespace {
20 // A wrapper around vector which exposes rbegin(), rend().
21 class ReverseOnlyVector {
22 std::vector<int> Vec;
24 public:
25 ReverseOnlyVector(std::initializer_list<int> list) : Vec(list) {}
27 typedef std::vector<int>::reverse_iterator reverse_iterator;
28 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
29 reverse_iterator rbegin() { return Vec.rbegin(); }
30 reverse_iterator rend() { return Vec.rend(); }
31 const_reverse_iterator rbegin() const { return Vec.rbegin(); }
32 const_reverse_iterator rend() const { return Vec.rend(); }
35 // A wrapper around vector which exposes begin(), end(), rbegin() and rend().
36 // begin() and end() don't have implementations as this ensures that we will
37 // get a linker error if reverse() chooses begin()/end() over rbegin(), rend().
38 class BidirectionalVector {
39 mutable std::vector<int> Vec;
41 public:
42 BidirectionalVector(std::initializer_list<int> list) : Vec(list) {}
44 typedef std::vector<int>::iterator iterator;
45 iterator begin() const;
46 iterator end() const;
48 typedef std::vector<int>::reverse_iterator reverse_iterator;
49 reverse_iterator rbegin() const { return Vec.rbegin(); }
50 reverse_iterator rend() const { return Vec.rend(); }
53 /// This is the same as BidirectionalVector but with the addition of const
54 /// begin/rbegin methods to ensure that the type traits for has_rbegin works.
55 class BidirectionalVectorConsts {
56 std::vector<int> Vec;
58 public:
59 BidirectionalVectorConsts(std::initializer_list<int> list) : Vec(list) {}
61 typedef std::vector<int>::iterator iterator;
62 typedef std::vector<int>::const_iterator const_iterator;
63 iterator begin();
64 iterator end();
65 const_iterator begin() const;
66 const_iterator end() const;
68 typedef std::vector<int>::reverse_iterator reverse_iterator;
69 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
70 reverse_iterator rbegin() { return Vec.rbegin(); }
71 reverse_iterator rend() { return Vec.rend(); }
72 const_reverse_iterator rbegin() const { return Vec.rbegin(); }
73 const_reverse_iterator rend() const { return Vec.rend(); }
76 /// Check that types with custom iterators work.
77 class CustomIteratorVector {
78 mutable std::vector<int> V;
80 public:
81 CustomIteratorVector(std::initializer_list<int> list) : V(list) {}
83 typedef std::vector<int>::iterator iterator;
84 class reverse_iterator {
85 std::vector<int>::iterator I;
87 public:
88 reverse_iterator() = default;
89 reverse_iterator(const reverse_iterator &) = default;
90 reverse_iterator &operator=(const reverse_iterator &) = default;
92 explicit reverse_iterator(std::vector<int>::iterator I) : I(I) {}
94 reverse_iterator &operator++() {
95 --I;
96 return *this;
98 reverse_iterator &operator--() {
99 ++I;
100 return *this;
102 int &operator*() const { return *std::prev(I); }
103 int *operator->() const { return &*std::prev(I); }
104 friend bool operator==(const reverse_iterator &L,
105 const reverse_iterator &R) {
106 return L.I == R.I;
108 friend bool operator!=(const reverse_iterator &L,
109 const reverse_iterator &R) {
110 return !(L == R);
114 iterator begin() const { return V.begin(); }
115 iterator end() const { return V.end(); }
116 reverse_iterator rbegin() const { return reverse_iterator(V.end()); }
117 reverse_iterator rend() const { return reverse_iterator(V.begin()); }
120 template <typename R> void TestRev(const R &r) {
121 int counter = 3;
122 for (int i : r)
123 EXPECT_EQ(i, counter--);
126 // Test fixture
127 template <typename T> class RangeAdapterLValueTest : public ::testing::Test {};
129 typedef ::testing::Types<std::vector<int>, std::list<int>, int[4]>
130 RangeAdapterLValueTestTypes;
131 TYPED_TEST_SUITE(RangeAdapterLValueTest, RangeAdapterLValueTestTypes, );
133 TYPED_TEST(RangeAdapterLValueTest, TrivialOperation) {
134 TypeParam v = {0, 1, 2, 3};
135 TestRev(reverse(v));
137 const TypeParam c = {0, 1, 2, 3};
138 TestRev(reverse(c));
141 template <typename T> struct RangeAdapterRValueTest : testing::Test {};
143 typedef ::testing::Types<std::vector<int>, std::list<int>, CustomIteratorVector,
144 ReverseOnlyVector, BidirectionalVector,
145 BidirectionalVectorConsts>
146 RangeAdapterRValueTestTypes;
147 TYPED_TEST_SUITE(RangeAdapterRValueTest, RangeAdapterRValueTestTypes, );
149 TYPED_TEST(RangeAdapterRValueTest, TrivialOperation) {
150 TestRev(reverse(TypeParam({0, 1, 2, 3})));
153 TYPED_TEST(RangeAdapterRValueTest, RangeType) {
154 static_assert(
155 std::is_same_v<decltype(reverse(std::declval<TypeParam>()).begin()),
156 decltype(std::declval<TypeParam>().rbegin())>,
157 "reverse().begin() should have the same type as rbegin()");
158 static_assert(
159 std::is_same_v<decltype(reverse(std::declval<const TypeParam>()).begin()),
160 decltype(std::declval<const TypeParam>().rbegin())>,
161 "reverse().begin() should have the same type as rbegin() [const]");
164 } // anonymous namespace