Commit r331416 breaks the big-endian PPC bot. On the big endian build, we
[llvm-core.git] / unittests / ADT / RangeAdapterTest.cpp
blobedc1ced72ba9f3377846b8cd15da92b2338984cf
1 //===- RangeAdapterTest.cpp - Unit tests for range adapters --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/iterator_range.h"
12 #include "gtest/gtest.h"
14 #include <iterator>
15 #include <list>
16 #include <vector>
18 using namespace llvm;
20 namespace {
22 // A wrapper around vector which exposes rbegin(), rend().
23 class ReverseOnlyVector {
24 std::vector<int> Vec;
26 public:
27 ReverseOnlyVector(std::initializer_list<int> list) : Vec(list) {}
29 typedef std::vector<int>::reverse_iterator reverse_iterator;
30 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
31 reverse_iterator rbegin() { return Vec.rbegin(); }
32 reverse_iterator rend() { return Vec.rend(); }
33 const_reverse_iterator rbegin() const { return Vec.rbegin(); }
34 const_reverse_iterator rend() const { return Vec.rend(); }
37 // A wrapper around vector which exposes begin(), end(), rbegin() and rend().
38 // begin() and end() don't have implementations as this ensures that we will
39 // get a linker error if reverse() chooses begin()/end() over rbegin(), rend().
40 class BidirectionalVector {
41 mutable std::vector<int> Vec;
43 public:
44 BidirectionalVector(std::initializer_list<int> list) : Vec(list) {}
46 typedef std::vector<int>::iterator iterator;
47 iterator begin() const;
48 iterator end() const;
50 typedef std::vector<int>::reverse_iterator reverse_iterator;
51 reverse_iterator rbegin() const { return Vec.rbegin(); }
52 reverse_iterator rend() const { return Vec.rend(); }
55 /// This is the same as BidirectionalVector but with the addition of const
56 /// begin/rbegin methods to ensure that the type traits for has_rbegin works.
57 class BidirectionalVectorConsts {
58 std::vector<int> Vec;
60 public:
61 BidirectionalVectorConsts(std::initializer_list<int> list) : Vec(list) {}
63 typedef std::vector<int>::iterator iterator;
64 typedef std::vector<int>::const_iterator const_iterator;
65 iterator begin();
66 iterator end();
67 const_iterator begin() const;
68 const_iterator end() const;
70 typedef std::vector<int>::reverse_iterator reverse_iterator;
71 typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
72 reverse_iterator rbegin() { return Vec.rbegin(); }
73 reverse_iterator rend() { return Vec.rend(); }
74 const_reverse_iterator rbegin() const { return Vec.rbegin(); }
75 const_reverse_iterator rend() const { return Vec.rend(); }
78 /// Check that types with custom iterators work.
79 class CustomIteratorVector {
80 mutable std::vector<int> V;
82 public:
83 CustomIteratorVector(std::initializer_list<int> list) : V(list) {}
85 typedef std::vector<int>::iterator iterator;
86 class reverse_iterator {
87 std::vector<int>::iterator I;
89 public:
90 reverse_iterator() = default;
91 reverse_iterator(const reverse_iterator &) = default;
92 reverse_iterator &operator=(const reverse_iterator &) = default;
94 explicit reverse_iterator(std::vector<int>::iterator I) : I(I) {}
96 reverse_iterator &operator++() {
97 --I;
98 return *this;
100 reverse_iterator &operator--() {
101 ++I;
102 return *this;
104 int &operator*() const { return *std::prev(I); }
105 int *operator->() const { return &*std::prev(I); }
106 friend bool operator==(const reverse_iterator &L,
107 const reverse_iterator &R) {
108 return L.I == R.I;
110 friend bool operator!=(const reverse_iterator &L,
111 const reverse_iterator &R) {
112 return !(L == R);
116 iterator begin() const { return V.begin(); }
117 iterator end() const { return V.end(); }
118 reverse_iterator rbegin() const { return reverse_iterator(V.end()); }
119 reverse_iterator rend() const { return reverse_iterator(V.begin()); }
122 template <typename R> void TestRev(const R &r) {
123 int counter = 3;
124 for (int i : r)
125 EXPECT_EQ(i, counter--);
128 // Test fixture
129 template <typename T> class RangeAdapterLValueTest : public ::testing::Test {};
131 typedef ::testing::Types<std::vector<int>, std::list<int>, int[4]>
132 RangeAdapterLValueTestTypes;
133 TYPED_TEST_CASE(RangeAdapterLValueTest, RangeAdapterLValueTestTypes);
135 TYPED_TEST(RangeAdapterLValueTest, TrivialOperation) {
136 TypeParam v = {0, 1, 2, 3};
137 TestRev(reverse(v));
139 const TypeParam c = {0, 1, 2, 3};
140 TestRev(reverse(c));
143 template <typename T> struct RangeAdapterRValueTest : testing::Test {};
145 typedef ::testing::Types<std::vector<int>, std::list<int>, CustomIteratorVector,
146 ReverseOnlyVector, BidirectionalVector,
147 BidirectionalVectorConsts>
148 RangeAdapterRValueTestTypes;
149 TYPED_TEST_CASE(RangeAdapterRValueTest, RangeAdapterRValueTestTypes);
151 TYPED_TEST(RangeAdapterRValueTest, TrivialOperation) {
152 TestRev(reverse(TypeParam({0, 1, 2, 3})));
155 TYPED_TEST(RangeAdapterRValueTest, HasRbegin) {
156 static_assert(has_rbegin<TypeParam>::value, "rbegin() should be defined");
159 TYPED_TEST(RangeAdapterRValueTest, RangeType) {
160 static_assert(
161 std::is_same<
162 decltype(reverse(*static_cast<TypeParam *>(nullptr)).begin()),
163 decltype(static_cast<TypeParam *>(nullptr)->rbegin())>::value,
164 "reverse().begin() should have the same type as rbegin()");
165 static_assert(
166 std::is_same<
167 decltype(reverse(*static_cast<const TypeParam *>(nullptr)).begin()),
168 decltype(static_cast<const TypeParam *>(nullptr)->rbegin())>::value,
169 "reverse().begin() should have the same type as rbegin() [const]");
172 } // anonymous namespace