• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <algorithm>
18 #include <vector>
19 
20 #include "gtest/gtest.h"
21 #include "transform_array_ref.h"
22 
23 namespace art {
24 
25 namespace {  // anonymous namespace
26 
27 struct ValueHolder {
28   // Deliberately not explicit.
ValueHolderart::__anon1aa1e1e60111::ValueHolder29   ValueHolder(int v) : value(v) { }  // NOLINT
30   int value;
31 };
32 
operator ==(const ValueHolder & lhs,const ValueHolder & rhs)33 [[maybe_unused]] bool operator==(const ValueHolder& lhs, const ValueHolder& rhs) {
34   return lhs.value == rhs.value;
35 }
36 
37 }  // anonymous namespace
38 
TEST(TransformArrayRef,ConstRefAdd1)39 TEST(TransformArrayRef, ConstRefAdd1) {
40   auto add1 = [](const ValueHolder& h) { return h.value + 1; };
41   std::vector<ValueHolder> input({ 7, 6, 4, 0 });
42   std::vector<int> output;
43 
44   auto taref = MakeTransformArrayRef(input, add1);
45   using TarefIter = decltype(taref)::iterator;
46   using ConstTarefIter = decltype(taref)::const_iterator;
47   static_assert(std::is_same_v<int, decltype(taref)::value_type>);
48   static_assert(std::is_same_v<TarefIter, decltype(taref)::pointer>);
49   static_assert(std::is_same_v<int, decltype(taref)::reference>);
50   static_assert(std::is_same_v<ConstTarefIter, decltype(taref)::const_pointer>);
51   static_assert(std::is_same_v<int, decltype(taref)::const_reference>);
52 
53   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
54   ASSERT_EQ(std::vector<int>({ 8, 7, 5, 1 }), output);
55   output.clear();
56 
57   std::copy(taref.cbegin(), taref.cend(), std::back_inserter(output));
58   ASSERT_EQ(std::vector<int>({ 8, 7, 5, 1 }), output);
59   output.clear();
60 
61   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
62   ASSERT_EQ(std::vector<int>({ 1, 5, 7, 8 }), output);
63   output.clear();
64 
65   std::copy(taref.crbegin(), taref.crend(), std::back_inserter(output));
66   ASSERT_EQ(std::vector<int>({ 1, 5, 7, 8 }), output);
67   output.clear();
68 
69   ASSERT_EQ(input.size(), taref.size());
70   ASSERT_EQ(input.empty(), taref.empty());
71   ASSERT_EQ(input.front().value + 1, taref.front());
72   ASSERT_EQ(input.back().value + 1, taref.back());
73 
74   for (size_t i = 0; i != input.size(); ++i) {
75     ASSERT_EQ(input[i].value + 1, taref[i]);
76   }
77 }
78 
TEST(TransformArrayRef,NonConstRefSub1)79 TEST(TransformArrayRef, NonConstRefSub1) {
80   auto sub1 = [](ValueHolder& h) { return h.value - 1; };
81   std::vector<ValueHolder> input({ 4, 4, 5, 7, 10 });
82   std::vector<int> output;
83 
84   auto taref = MakeTransformArrayRef(input, sub1);
85   using TarefIter = decltype(taref)::iterator;
86   static_assert(std::is_same_v<void, decltype(taref)::const_iterator>);
87   static_assert(std::is_same_v<int, decltype(taref)::value_type>);
88   static_assert(std::is_same_v<TarefIter, decltype(taref)::pointer>);
89   static_assert(std::is_same_v<int, decltype(taref)::reference>);
90   static_assert(std::is_same_v<void, decltype(taref)::const_pointer>);
91   static_assert(std::is_same_v<void, decltype(taref)::const_reference>);
92 
93   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
94   ASSERT_EQ(std::vector<int>({ 3, 3, 4, 6, 9 }), output);
95   output.clear();
96 
97   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
98   ASSERT_EQ(std::vector<int>({ 9, 6, 4, 3, 3 }), output);
99   output.clear();
100 
101   ASSERT_EQ(input.size(), taref.size());
102   ASSERT_EQ(input.empty(), taref.empty());
103   ASSERT_EQ(input.front().value - 1, taref.front());
104   ASSERT_EQ(input.back().value - 1, taref.back());
105 
106   for (size_t i = 0; i != input.size(); ++i) {
107     ASSERT_EQ(input[i].value - 1, taref[i]);
108   }
109 }
110 
TEST(TransformArrayRef,ConstAndNonConstRef)111 TEST(TransformArrayRef, ConstAndNonConstRef) {
112   struct Ref {
113     int& operator()(ValueHolder& h) const { return h.value; }
114     const int& operator()(const ValueHolder& h) const { return h.value; }
115   };
116   Ref ref;
117   std::vector<ValueHolder> input({ 1, 0, 1, 0, 3, 1 });
118   std::vector<int> output;
119 
120   auto taref = MakeTransformArrayRef(input, ref);
121   static_assert(std::is_same_v<int, decltype(taref)::value_type>);
122   static_assert(std::is_same_v<int*, decltype(taref)::pointer>);
123   static_assert(std::is_same_v<int&, decltype(taref)::reference>);
124   static_assert(std::is_same_v<const int*, decltype(taref)::const_pointer>);
125   static_assert(std::is_same_v<const int&, decltype(taref)::const_reference>);
126 
127   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
128   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
129   output.clear();
130 
131   std::copy(taref.cbegin(), taref.cend(), std::back_inserter(output));
132   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
133   output.clear();
134 
135   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
136   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
137   output.clear();
138 
139   std::copy(taref.crbegin(), taref.crend(), std::back_inserter(output));
140   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
141   output.clear();
142 
143   ASSERT_EQ(input.size(), taref.size());
144   ASSERT_EQ(input.empty(), taref.empty());
145   ASSERT_EQ(input.front().value, taref.front());
146   ASSERT_EQ(input.back().value, taref.back());
147 
148   for (size_t i = 0; i != input.size(); ++i) {
149     ASSERT_EQ(input[i].value, taref[i]);
150   }
151 
152   // Test writing through the transform iterator.
153   std::vector<int> transform_input({ 24, 37, 11, 71 });
154   std::vector<ValueHolder> transformed(transform_input.size(), 0);
155   taref = MakeTransformArrayRef(transformed, ref);
156   for (size_t i = 0; i != transform_input.size(); ++i) {
157     taref[i] = transform_input[i];
158   }
159   ASSERT_EQ(std::vector<ValueHolder>({ 24, 37, 11, 71 }), transformed);
160 
161   const std::vector<ValueHolder>& cinput = input;
162 
163   auto ctaref = MakeTransformArrayRef(cinput, ref);
164   static_assert(std::is_same_v<int, decltype(ctaref)::value_type>);
165   static_assert(std::is_same_v<const int*, decltype(ctaref)::pointer>);
166   static_assert(std::is_same_v<const int&, decltype(ctaref)::reference>);
167   static_assert(std::is_same_v<const int*, decltype(ctaref)::const_pointer>);
168   static_assert(std::is_same_v<const int&, decltype(ctaref)::const_reference>);
169 
170   std::copy(ctaref.begin(), ctaref.end(), std::back_inserter(output));
171   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
172   output.clear();
173 
174   std::copy(std::begin(ctaref), std::end(ctaref), std::back_inserter(output));
175   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
176   output.clear();
177 
178   std::copy(ctaref.cbegin(), ctaref.cend(), std::back_inserter(output));
179   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
180   output.clear();
181 
182   std::copy(std::cbegin(ctaref), std::cend(ctaref), std::back_inserter(output));
183   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
184   output.clear();
185 
186   std::copy(ctaref.rbegin(), ctaref.rend(), std::back_inserter(output));
187   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
188   output.clear();
189 
190   std::copy(std::rbegin(ctaref), std::rend(ctaref), std::back_inserter(output));
191   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
192   output.clear();
193 
194   std::copy(ctaref.crbegin(), ctaref.crend(), std::back_inserter(output));
195   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
196   output.clear();
197 
198   std::copy(std::crbegin(ctaref), std::crend(ctaref), std::back_inserter(output));
199   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
200   output.clear();
201 
202   ASSERT_EQ(cinput.size(), ctaref.size());
203   ASSERT_EQ(cinput.empty(), ctaref.empty());
204   ASSERT_EQ(cinput.front().value, ctaref.front());
205   ASSERT_EQ(cinput.back().value, ctaref.back());
206 
207   for (size_t i = 0; i != cinput.size(); ++i) {
208     ASSERT_EQ(cinput[i].value, ctaref[i]);
209   }
210 
211   // Test conversion adding const.
212   decltype(ctaref) ctaref2 = taref;
213   ASSERT_EQ(taref.size(), ctaref2.size());
214   for (size_t i = 0; i != taref.size(); ++i) {
215     ASSERT_EQ(taref[i], ctaref2[i]);
216   }
217 }
218 
219 }  // namespace art
220