• 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 
22 #include "base/transform_array_ref.h"
23 
24 namespace art {
25 
26 namespace {  // anonymous namespace
27 
28 struct ValueHolder {
29   // Deliberately not explicit.
ValueHolderart::__anon8c34bbba0111::ValueHolder30   ValueHolder(int v) : value(v) { }  // NOLINT
31   int value;
32 };
33 
operator ==(const ValueHolder & lhs,const ValueHolder & rhs)34 ATTRIBUTE_UNUSED bool operator==(const ValueHolder& lhs, const ValueHolder& rhs) {
35   return lhs.value == rhs.value;
36 }
37 
38 }  // anonymous namespace
39 
TEST(TransformArrayRef,ConstRefAdd1)40 TEST(TransformArrayRef, ConstRefAdd1) {
41   auto add1 = [](const ValueHolder& h) { return h.value + 1; };  // NOLINT [readability/braces]
42   std::vector<ValueHolder> input({ 7, 6, 4, 0 });
43   std::vector<int> output;
44 
45   auto taref = MakeTransformArrayRef(input, add1);
46   using TarefIter = decltype(taref)::iterator;
47   using ConstTarefIter = decltype(taref)::const_iterator;
48   static_assert(std::is_same<int, decltype(taref)::value_type>::value, "value_type");
49   static_assert(std::is_same<TarefIter, decltype(taref)::pointer>::value, "pointer");
50   static_assert(std::is_same<int, decltype(taref)::reference>::value, "reference");
51   static_assert(std::is_same<ConstTarefIter, decltype(taref)::const_pointer>::value,
52                 "const_pointer");
53   static_assert(std::is_same<int, decltype(taref)::const_reference>::value, "const_reference");
54 
55   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
56   ASSERT_EQ(std::vector<int>({ 8, 7, 5, 1 }), output);
57   output.clear();
58 
59   std::copy(taref.cbegin(), taref.cend(), std::back_inserter(output));
60   ASSERT_EQ(std::vector<int>({ 8, 7, 5, 1 }), output);
61   output.clear();
62 
63   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
64   ASSERT_EQ(std::vector<int>({ 1, 5, 7, 8 }), output);
65   output.clear();
66 
67   std::copy(taref.crbegin(), taref.crend(), std::back_inserter(output));
68   ASSERT_EQ(std::vector<int>({ 1, 5, 7, 8 }), output);
69   output.clear();
70 
71   ASSERT_EQ(input.size(), taref.size());
72   ASSERT_EQ(input.empty(), taref.empty());
73   ASSERT_EQ(input.front().value + 1, taref.front());
74   ASSERT_EQ(input.back().value + 1, taref.back());
75 
76   for (size_t i = 0; i != input.size(); ++i) {
77     ASSERT_EQ(input[i].value + 1, taref[i]);
78   }
79 }
80 
TEST(TransformArrayRef,NonConstRefSub1)81 TEST(TransformArrayRef, NonConstRefSub1) {
82   auto sub1 = [](ValueHolder& h) { return h.value - 1; };  // NOLINT [readability/braces]
83   std::vector<ValueHolder> input({ 4, 4, 5, 7, 10 });
84   std::vector<int> output;
85 
86   auto taref = MakeTransformArrayRef(input, sub1);
87   using TarefIter = decltype(taref)::iterator;
88   static_assert(std::is_same<void, decltype(taref)::const_iterator>::value, "const_iterator");
89   static_assert(std::is_same<int, decltype(taref)::value_type>::value, "value_type");
90   static_assert(std::is_same<TarefIter, decltype(taref)::pointer>::value, "pointer");
91   static_assert(std::is_same<int, decltype(taref)::reference>::value, "reference");
92   static_assert(std::is_same<void, decltype(taref)::const_pointer>::value, "const_pointer");
93   static_assert(std::is_same<void, decltype(taref)::const_reference>::value, "const_reference");
94 
95   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
96   ASSERT_EQ(std::vector<int>({ 3, 3, 4, 6, 9 }), output);
97   output.clear();
98 
99   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
100   ASSERT_EQ(std::vector<int>({ 9, 6, 4, 3, 3 }), output);
101   output.clear();
102 
103   ASSERT_EQ(input.size(), taref.size());
104   ASSERT_EQ(input.empty(), taref.empty());
105   ASSERT_EQ(input.front().value - 1, taref.front());
106   ASSERT_EQ(input.back().value - 1, taref.back());
107 
108   for (size_t i = 0; i != input.size(); ++i) {
109     ASSERT_EQ(input[i].value - 1, taref[i]);
110   }
111 }
112 
TEST(TransformArrayRef,ConstAndNonConstRef)113 TEST(TransformArrayRef, ConstAndNonConstRef) {
114   struct Ref {
115     int& operator()(ValueHolder& h) const { return h.value; }
116     const int& operator()(const ValueHolder& h) const { return h.value; }
117   };
118   Ref ref;
119   std::vector<ValueHolder> input({ 1, 0, 1, 0, 3, 1 });
120   std::vector<int> output;
121 
122   auto taref = MakeTransformArrayRef(input, ref);
123   static_assert(std::is_same<int, decltype(taref)::value_type>::value, "value_type");
124   static_assert(std::is_same<int*, decltype(taref)::pointer>::value, "pointer");
125   static_assert(std::is_same<int&, decltype(taref)::reference>::value, "reference");
126   static_assert(std::is_same<const int*, decltype(taref)::const_pointer>::value, "const_pointer");
127   static_assert(std::is_same<const int&, decltype(taref)::const_reference>::value,
128                 "const_reference");
129 
130   std::copy(taref.begin(), taref.end(), std::back_inserter(output));
131   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
132   output.clear();
133 
134   std::copy(taref.cbegin(), taref.cend(), std::back_inserter(output));
135   ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output);
136   output.clear();
137 
138   std::copy(taref.rbegin(), taref.rend(), std::back_inserter(output));
139   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
140   output.clear();
141 
142   std::copy(taref.crbegin(), taref.crend(), std::back_inserter(output));
143   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
144   output.clear();
145 
146   ASSERT_EQ(input.size(), taref.size());
147   ASSERT_EQ(input.empty(), taref.empty());
148   ASSERT_EQ(input.front().value, taref.front());
149   ASSERT_EQ(input.back().value, taref.back());
150 
151   for (size_t i = 0; i != input.size(); ++i) {
152     ASSERT_EQ(input[i].value, taref[i]);
153   }
154 
155   // Test writing through the transform iterator.
156   std::vector<int> transform_input({ 24, 37, 11, 71 });
157   std::vector<ValueHolder> transformed(transform_input.size(), 0);
158   taref = MakeTransformArrayRef(transformed, ref);
159   for (size_t i = 0; i != transform_input.size(); ++i) {
160     taref[i] = transform_input[i];
161   }
162   ASSERT_EQ(std::vector<ValueHolder>({ 24, 37, 11, 71 }), transformed);
163 
164   const std::vector<ValueHolder>& cinput = input;
165 
166   auto ctaref = MakeTransformArrayRef(cinput, ref);
167   static_assert(std::is_same<int, decltype(ctaref)::value_type>::value, "value_type");
168   static_assert(std::is_same<const int*, decltype(ctaref)::pointer>::value, "pointer");
169   static_assert(std::is_same<const int&, decltype(ctaref)::reference>::value, "reference");
170   static_assert(std::is_same<const int*, decltype(ctaref)::const_pointer>::value, "const_pointer");
171   static_assert(std::is_same<const int&, decltype(ctaref)::const_reference>::value,
172                 "const_reference");
173 
174   std::copy(ctaref.begin(), ctaref.end(), 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(ctaref.rbegin(), ctaref.rend(), std::back_inserter(output));
183   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
184   output.clear();
185 
186   std::copy(ctaref.crbegin(), ctaref.crend(), std::back_inserter(output));
187   ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output);
188   output.clear();
189 
190   ASSERT_EQ(cinput.size(), ctaref.size());
191   ASSERT_EQ(cinput.empty(), ctaref.empty());
192   ASSERT_EQ(cinput.front().value, ctaref.front());
193   ASSERT_EQ(cinput.back().value, ctaref.back());
194 
195   for (size_t i = 0; i != cinput.size(); ++i) {
196     ASSERT_EQ(cinput[i].value, ctaref[i]);
197   }
198 
199   // Test conversion adding const.
200   decltype(ctaref) ctaref2 = taref;
201   ASSERT_EQ(taref.size(), ctaref2.size());
202   for (size_t i = 0; i != taref.size(); ++i) {
203     ASSERT_EQ(taref[i], ctaref2[i]);
204   }
205 }
206 
207 }  // namespace art
208