1 //===- RangeAdapterTest.cpp - Unit tests for range adapters --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/iterator_range.h"
12 #include "gtest/gtest.h"
22 // A wrapper around vector which exposes rbegin(), rend().
23 class ReverseOnlyVector
{
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
;
44 BidirectionalVector(std::initializer_list
<int> list
) : Vec(list
) {}
46 typedef std::vector
<int>::iterator iterator
;
47 iterator
begin() 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
{
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
;
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
;
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
;
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++() {
100 reverse_iterator
&operator--() {
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
) {
110 friend bool operator!=(const reverse_iterator
&L
,
111 const reverse_iterator
&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
) {
125 EXPECT_EQ(i
, counter
--);
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};
139 const TypeParam c
= {0, 1, 2, 3};
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
) {
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()");
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