xref: /aosp_15_r20/external/vixl/test/test-invalset.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2014, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi //     and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi //     used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi //     specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi 
27*f5c631daSSadaf Ebrahimi #include "invalset-vixl.h"
28*f5c631daSSadaf Ebrahimi #include "test-runner.h"
29*f5c631daSSadaf Ebrahimi 
30*f5c631daSSadaf Ebrahimi namespace vixl {
31*f5c631daSSadaf Ebrahimi 
32*f5c631daSSadaf Ebrahimi // This file contains tests for the `InvalSet` and `InvalSetIterator` classes.
33*f5c631daSSadaf Ebrahimi 
34*f5c631daSSadaf Ebrahimi #define TEST(name) TEST_(INVALSET_##name)
35*f5c631daSSadaf Ebrahimi 
36*f5c631daSSadaf Ebrahimi typedef ptrdiff_t KeyType;
37*f5c631daSSadaf Ebrahimi typedef ptrdiff_t ValType;
38*f5c631daSSadaf Ebrahimi 
39*f5c631daSSadaf Ebrahimi // We test with an object for which the key and the value are distinct.
40*f5c631daSSadaf Ebrahimi class Obj {
41*f5c631daSSadaf Ebrahimi  public:
Obj()42*f5c631daSSadaf Ebrahimi   Obj() {}
Obj(KeyType key,ValType val)43*f5c631daSSadaf Ebrahimi   Obj(KeyType key, ValType val) : key_(key), val_(val) {}
44*f5c631daSSadaf Ebrahimi   KeyType key_;
45*f5c631daSSadaf Ebrahimi   ValType val_;
46*f5c631daSSadaf Ebrahimi 
operator ==(const Obj & other) const47*f5c631daSSadaf Ebrahimi   bool operator==(const Obj& other) const {
48*f5c631daSSadaf Ebrahimi     return (key_ == other.key_) && (val_ == other.val_);
49*f5c631daSSadaf Ebrahimi   }
operator <(const Obj & other) const50*f5c631daSSadaf Ebrahimi   bool operator<(const Obj& other) const {
51*f5c631daSSadaf Ebrahimi     return (key_ < other.key_) || ((key_ == other.key_) && (val_ < other.val_));
52*f5c631daSSadaf Ebrahimi   }
operator <=(const Obj & other) const53*f5c631daSSadaf Ebrahimi   bool operator<=(const Obj& other) const {
54*f5c631daSSadaf Ebrahimi     return (key_ <= other.key_) ||
55*f5c631daSSadaf Ebrahimi            ((key_ == other.key_) && (val_ <= other.val_));
56*f5c631daSSadaf Ebrahimi   }
operator >(const Obj & other) const57*f5c631daSSadaf Ebrahimi   bool operator>(const Obj& other) const {
58*f5c631daSSadaf Ebrahimi     return (key_ > other.key_) || ((key_ == other.key_) && (val_ > other.val_));
59*f5c631daSSadaf Ebrahimi   }
60*f5c631daSSadaf Ebrahimi };
61*f5c631daSSadaf Ebrahimi 
62*f5c631daSSadaf Ebrahimi static const unsigned kNPreallocatedElements = 8;
63*f5c631daSSadaf Ebrahimi static const KeyType kInvalidKey = PTRDIFF_MAX;
64*f5c631daSSadaf Ebrahimi static const size_t kReclaimFrom = 1000;
65*f5c631daSSadaf Ebrahimi static const unsigned kReclaimFactor = 10;
66*f5c631daSSadaf Ebrahimi 
67*f5c631daSSadaf Ebrahimi typedef InvalSet<Obj,
68*f5c631daSSadaf Ebrahimi                  kNPreallocatedElements,
69*f5c631daSSadaf Ebrahimi                  KeyType,
70*f5c631daSSadaf Ebrahimi                  kInvalidKey,
71*f5c631daSSadaf Ebrahimi                  kReclaimFrom,
72*f5c631daSSadaf Ebrahimi                  kReclaimFactor>
73*f5c631daSSadaf Ebrahimi     TestSet;
74*f5c631daSSadaf Ebrahimi 
75*f5c631daSSadaf Ebrahimi template <>
76*f5c631daSSadaf Ebrahimi inline KeyType InvalSet<Obj,
77*f5c631daSSadaf Ebrahimi                         kNPreallocatedElements,
78*f5c631daSSadaf Ebrahimi                         KeyType,
79*f5c631daSSadaf Ebrahimi                         kInvalidKey,
80*f5c631daSSadaf Ebrahimi                         kReclaimFrom,
GetKey(const Obj & obj)81*f5c631daSSadaf Ebrahimi                         kReclaimFactor>::GetKey(const Obj& obj) {
82*f5c631daSSadaf Ebrahimi   return obj.key_;
83*f5c631daSSadaf Ebrahimi }
84*f5c631daSSadaf Ebrahimi template <>
85*f5c631daSSadaf Ebrahimi inline void InvalSet<Obj,
86*f5c631daSSadaf Ebrahimi                      kNPreallocatedElements,
87*f5c631daSSadaf Ebrahimi                      KeyType,
88*f5c631daSSadaf Ebrahimi                      kInvalidKey,
89*f5c631daSSadaf Ebrahimi                      kReclaimFrom,
SetKey(Obj * obj,KeyType key)90*f5c631daSSadaf Ebrahimi                      kReclaimFactor>::SetKey(Obj* obj, KeyType key) {
91*f5c631daSSadaf Ebrahimi   obj->key_ = key;
92*f5c631daSSadaf Ebrahimi }
93*f5c631daSSadaf Ebrahimi 
94*f5c631daSSadaf Ebrahimi 
TEST(basic_test)95*f5c631daSSadaf Ebrahimi TEST(basic_test) {
96*f5c631daSSadaf Ebrahimi   TestSet set;
97*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
98*f5c631daSSadaf Ebrahimi 
99*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < kNPreallocatedElements; i++) {
100*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
101*f5c631daSSadaf Ebrahimi   }
102*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == kNPreallocatedElements);
103*f5c631daSSadaf Ebrahimi 
104*f5c631daSSadaf Ebrahimi   set.insert(Obj(-123, 456));
105*f5c631daSSadaf Ebrahimi   set.insert(Obj(2718, 2871828));
106*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == kNPreallocatedElements + 2);
107*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement() == Obj(-123, 456));
108*f5c631daSSadaf Ebrahimi 
109*f5c631daSSadaf Ebrahimi   set.erase(Obj(-123, 456));
110*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElementKey() == 0);
111*f5c631daSSadaf Ebrahimi 
112*f5c631daSSadaf Ebrahimi   set.clear();
113*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
114*f5c631daSSadaf Ebrahimi }
115*f5c631daSSadaf Ebrahimi 
116*f5c631daSSadaf Ebrahimi 
TEST(valid_element)117*f5c631daSSadaf Ebrahimi TEST(valid_element) {
118*f5c631daSSadaf Ebrahimi   VIXL_CHECK(TestSet::IsValid(Obj(0, 0)));
119*f5c631daSSadaf Ebrahimi   VIXL_CHECK(TestSet::IsValid(Obj(-1, 0)));
120*f5c631daSSadaf Ebrahimi   VIXL_CHECK(TestSet::IsValid(Obj(kInvalidKey - 1, 0)));
121*f5c631daSSadaf Ebrahimi   VIXL_CHECK(!TestSet::IsValid(Obj(kInvalidKey, 0)));
122*f5c631daSSadaf Ebrahimi }
123*f5c631daSSadaf Ebrahimi 
124*f5c631daSSadaf Ebrahimi 
TEST(insert)125*f5c631daSSadaf Ebrahimi TEST(insert) {
126*f5c631daSSadaf Ebrahimi   TestSet set;
127*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
128*f5c631daSSadaf Ebrahimi 
129*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < kNPreallocatedElements; i++) {
130*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
131*f5c631daSSadaf Ebrahimi   }
132*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == kNPreallocatedElements);
133*f5c631daSSadaf Ebrahimi   set.insert(Obj(-123, 1));
134*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == kNPreallocatedElements + 1);
135*f5c631daSSadaf Ebrahimi   set.insert(Obj(-123, 2));
136*f5c631daSSadaf Ebrahimi   set.insert(Obj(-123, 3));
137*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == kNPreallocatedElements + 3);
138*f5c631daSSadaf Ebrahimi 
139*f5c631daSSadaf Ebrahimi   set.clear();
140*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
141*f5c631daSSadaf Ebrahimi }
142*f5c631daSSadaf Ebrahimi 
143*f5c631daSSadaf Ebrahimi 
TEST(erase)144*f5c631daSSadaf Ebrahimi TEST(erase) {
145*f5c631daSSadaf Ebrahimi   TestSet set;
146*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
147*f5c631daSSadaf Ebrahimi 
148*f5c631daSSadaf Ebrahimi   // Test with only preallocated elements in the set.
149*f5c631daSSadaf Ebrahimi   VIXL_STATIC_ASSERT(kNPreallocatedElements >= 2);
150*f5c631daSSadaf Ebrahimi   set.insert(Obj(2718, 0));
151*f5c631daSSadaf Ebrahimi   set.erase(Obj(2718, 0));
152*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
153*f5c631daSSadaf Ebrahimi   set.insert(Obj(2718, 0));
154*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == 1);
155*f5c631daSSadaf Ebrahimi   set.insert(Obj(2718, 1));
156*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == 2);
157*f5c631daSSadaf Ebrahimi   set.erase(Obj(2718, 0));
158*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == 1);
159*f5c631daSSadaf Ebrahimi 
160*f5c631daSSadaf Ebrahimi   // Test with more elements.
161*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < 100 * kNPreallocatedElements; i++) {
162*f5c631daSSadaf Ebrahimi     set.insert(Obj(i * i, i % 30));
163*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, -1));
164*f5c631daSSadaf Ebrahimi   }
165*f5c631daSSadaf Ebrahimi   size_t max_size = set.size();
166*f5c631daSSadaf Ebrahimi   set.erase(Obj(100, -1));
167*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.size() == max_size - 1);
168*f5c631daSSadaf Ebrahimi   for (size_t i = 2; i <= max_size; i++) {
169*f5c631daSSadaf Ebrahimi     set.erase(set.GetMinElement());
170*f5c631daSSadaf Ebrahimi     VIXL_CHECK(set.size() == max_size - i);
171*f5c631daSSadaf Ebrahimi   }
172*f5c631daSSadaf Ebrahimi 
173*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
174*f5c631daSSadaf Ebrahimi }
175*f5c631daSSadaf Ebrahimi 
176*f5c631daSSadaf Ebrahimi 
TEST(min)177*f5c631daSSadaf Ebrahimi TEST(min) {
178*f5c631daSSadaf Ebrahimi   TestSet set;
179*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
180*f5c631daSSadaf Ebrahimi 
181*f5c631daSSadaf Ebrahimi   // Test with only preallocated elements in the set.
182*f5c631daSSadaf Ebrahimi   VIXL_STATIC_ASSERT(kNPreallocatedElements >= 4);
183*f5c631daSSadaf Ebrahimi   set.insert(Obj(-1, -1));
184*f5c631daSSadaf Ebrahimi   set.insert(Obj(-1, 0));
185*f5c631daSSadaf Ebrahimi   set.insert(Obj(0, 0));
186*f5c631daSSadaf Ebrahimi   set.insert(Obj(1, 0));
187*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement() == Obj(-1, -1));
188*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElementKey() == -1);
189*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement().key_ == set.GetMinElementKey());
190*f5c631daSSadaf Ebrahimi 
191*f5c631daSSadaf Ebrahimi   // Test with more elements.
192*f5c631daSSadaf Ebrahimi   set.clear();
193*f5c631daSSadaf Ebrahimi   int max_index = 100 * kNPreallocatedElements;
194*f5c631daSSadaf Ebrahimi   for (int i = 0; i <= max_index; i++) {
195*f5c631daSSadaf Ebrahimi     // Insert elements out of order.
196*f5c631daSSadaf Ebrahimi     int sign = ((i % 2) == 0) ? -1 : 1;
197*f5c631daSSadaf Ebrahimi     set.insert(Obj(sign * i, i));
198*f5c631daSSadaf Ebrahimi   }
199*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement() == Obj(-max_index, max_index));
200*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement().key_ == set.GetMinElementKey());
201*f5c631daSSadaf Ebrahimi 
202*f5c631daSSadaf Ebrahimi   set.erase(Obj(0, 0));
203*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement() == Obj(-max_index, max_index));
204*f5c631daSSadaf Ebrahimi   set.erase(set.GetMinElement());
205*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.GetMinElement() == Obj(-(max_index - 2), max_index - 2));
206*f5c631daSSadaf Ebrahimi 
207*f5c631daSSadaf Ebrahimi   set.clear();
208*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
209*f5c631daSSadaf Ebrahimi }
210*f5c631daSSadaf Ebrahimi 
211*f5c631daSSadaf Ebrahimi 
TEST(iterator)212*f5c631daSSadaf Ebrahimi TEST(iterator) {
213*f5c631daSSadaf Ebrahimi   TestSet set;
214*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
215*f5c631daSSadaf Ebrahimi 
216*f5c631daSSadaf Ebrahimi   // Ensure that set.begin() == set.end() for the empty set.
217*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.begin() == set.end());
218*f5c631daSSadaf Ebrahimi 
219*f5c631daSSadaf Ebrahimi   // Test with only preallocated elements in the set.
220*f5c631daSSadaf Ebrahimi   size_t expected_total = 0;
221*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < kNPreallocatedElements; i++) {
222*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
223*f5c631daSSadaf Ebrahimi     expected_total += i;
224*f5c631daSSadaf Ebrahimi   }
225*f5c631daSSadaf Ebrahimi 
226*f5c631daSSadaf Ebrahimi   size_t size = 0;
227*f5c631daSSadaf Ebrahimi   size_t total = 0;
228*f5c631daSSadaf Ebrahimi   for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
229*f5c631daSSadaf Ebrahimi     total += it->val_;
230*f5c631daSSadaf Ebrahimi     size++;
231*f5c631daSSadaf Ebrahimi   }
232*f5c631daSSadaf Ebrahimi   VIXL_CHECK(size == set.size());
233*f5c631daSSadaf Ebrahimi   VIXL_CHECK(total == expected_total);
234*f5c631daSSadaf Ebrahimi 
235*f5c631daSSadaf Ebrahimi   // Test with more elements.
236*f5c631daSSadaf Ebrahimi   for (unsigned i = kNPreallocatedElements; i < 4 * kNPreallocatedElements;
237*f5c631daSSadaf Ebrahimi        i++) {
238*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
239*f5c631daSSadaf Ebrahimi     expected_total += i;
240*f5c631daSSadaf Ebrahimi   }
241*f5c631daSSadaf Ebrahimi 
242*f5c631daSSadaf Ebrahimi   size = 0;
243*f5c631daSSadaf Ebrahimi   total = 0;
244*f5c631daSSadaf Ebrahimi   for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
245*f5c631daSSadaf Ebrahimi     total += it->val_;
246*f5c631daSSadaf Ebrahimi     size++;
247*f5c631daSSadaf Ebrahimi   }
248*f5c631daSSadaf Ebrahimi   VIXL_CHECK(size == set.size());
249*f5c631daSSadaf Ebrahimi   VIXL_CHECK(total == expected_total);
250*f5c631daSSadaf Ebrahimi 
251*f5c631daSSadaf Ebrahimi   // Test after elements have been deleted.
252*f5c631daSSadaf Ebrahimi   // - Select an interesting list of elements to erase.
253*f5c631daSSadaf Ebrahimi   std::vector<Obj> to_erase;
254*f5c631daSSadaf Ebrahimi   unsigned step = 0;
255*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < set.size(); i += step, step++) {
256*f5c631daSSadaf Ebrahimi     to_erase.push_back(Obj(i, i));
257*f5c631daSSadaf Ebrahimi   }
258*f5c631daSSadaf Ebrahimi   to_erase.push_back(Obj(set.size() - 1, set.size() - 1));  // The last element.
259*f5c631daSSadaf Ebrahimi   to_erase.push_back(Obj(set.size(), set.size()));          // Not in the set.
260*f5c631daSSadaf Ebrahimi 
261*f5c631daSSadaf Ebrahimi   // - Erase one at a time, retesting after each one.
262*f5c631daSSadaf Ebrahimi   while (!to_erase.empty()) {
263*f5c631daSSadaf Ebrahimi     size_t erased = set.erase(to_erase.back());
264*f5c631daSSadaf Ebrahimi     if (erased > 0) {
265*f5c631daSSadaf Ebrahimi       VIXL_CHECK(erased == 1);
266*f5c631daSSadaf Ebrahimi       expected_total -= to_erase.back().val_;
267*f5c631daSSadaf Ebrahimi     } else {
268*f5c631daSSadaf Ebrahimi     }
269*f5c631daSSadaf Ebrahimi     to_erase.pop_back();
270*f5c631daSSadaf Ebrahimi 
271*f5c631daSSadaf Ebrahimi     size = 0;
272*f5c631daSSadaf Ebrahimi     total = 0;
273*f5c631daSSadaf Ebrahimi     for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
274*f5c631daSSadaf Ebrahimi       total += it->val_;
275*f5c631daSSadaf Ebrahimi       size++;
276*f5c631daSSadaf Ebrahimi     }
277*f5c631daSSadaf Ebrahimi     VIXL_CHECK(size == set.size());
278*f5c631daSSadaf Ebrahimi     VIXL_CHECK(total == expected_total);
279*f5c631daSSadaf Ebrahimi   }
280*f5c631daSSadaf Ebrahimi }
281*f5c631daSSadaf Ebrahimi 
282*f5c631daSSadaf Ebrahimi 
283*f5c631daSSadaf Ebrahimi #if __cplusplus >= 201103L
TEST(iterator_cxx11)284*f5c631daSSadaf Ebrahimi TEST(iterator_cxx11) {
285*f5c631daSSadaf Ebrahimi   TestSet set;
286*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set.empty() && (set.size() == 0));
287*f5c631daSSadaf Ebrahimi 
288*f5c631daSSadaf Ebrahimi   // Test with only preallocated elements in the set.
289*f5c631daSSadaf Ebrahimi   size_t expected_total = 0;
290*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < kNPreallocatedElements; i++) {
291*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
292*f5c631daSSadaf Ebrahimi     expected_total += i;
293*f5c631daSSadaf Ebrahimi   }
294*f5c631daSSadaf Ebrahimi 
295*f5c631daSSadaf Ebrahimi   size_t size = 0;
296*f5c631daSSadaf Ebrahimi   size_t total = 0;
297*f5c631daSSadaf Ebrahimi   for (auto object : set) {
298*f5c631daSSadaf Ebrahimi     total += object.val_;
299*f5c631daSSadaf Ebrahimi     size++;
300*f5c631daSSadaf Ebrahimi   }
301*f5c631daSSadaf Ebrahimi   VIXL_CHECK(size == set.size());
302*f5c631daSSadaf Ebrahimi   VIXL_CHECK(total == expected_total);
303*f5c631daSSadaf Ebrahimi 
304*f5c631daSSadaf Ebrahimi   // Test with more elements.
305*f5c631daSSadaf Ebrahimi   for (unsigned i = kNPreallocatedElements; i < 4 * kNPreallocatedElements;
306*f5c631daSSadaf Ebrahimi        i++) {
307*f5c631daSSadaf Ebrahimi     set.insert(Obj(i, i));
308*f5c631daSSadaf Ebrahimi     expected_total += i;
309*f5c631daSSadaf Ebrahimi   }
310*f5c631daSSadaf Ebrahimi 
311*f5c631daSSadaf Ebrahimi   size = 0;
312*f5c631daSSadaf Ebrahimi   total = 0;
313*f5c631daSSadaf Ebrahimi   for (auto object : set) {
314*f5c631daSSadaf Ebrahimi     total += object.val_;
315*f5c631daSSadaf Ebrahimi     size++;
316*f5c631daSSadaf Ebrahimi   }
317*f5c631daSSadaf Ebrahimi   VIXL_CHECK(size == set.size());
318*f5c631daSSadaf Ebrahimi   VIXL_CHECK(total == expected_total);
319*f5c631daSSadaf Ebrahimi 
320*f5c631daSSadaf Ebrahimi   // Test after elements have been deleted.
321*f5c631daSSadaf Ebrahimi   // - Select an interesting list of elements to erase.
322*f5c631daSSadaf Ebrahimi   std::vector<Obj> to_erase;
323*f5c631daSSadaf Ebrahimi   unsigned step = 0;
324*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < set.size(); i += step, step++) {
325*f5c631daSSadaf Ebrahimi     to_erase.push_back(Obj(i, i));
326*f5c631daSSadaf Ebrahimi   }
327*f5c631daSSadaf Ebrahimi   to_erase.push_back(Obj(set.size() - 1, set.size() - 1));  // The last element.
328*f5c631daSSadaf Ebrahimi   to_erase.push_back(Obj(set.size(), set.size()));          // Not in the set.
329*f5c631daSSadaf Ebrahimi 
330*f5c631daSSadaf Ebrahimi   // - Erase one at a time, retesting after each one.
331*f5c631daSSadaf Ebrahimi   while (!to_erase.empty()) {
332*f5c631daSSadaf Ebrahimi     size_t erased = set.erase(to_erase.back());
333*f5c631daSSadaf Ebrahimi     if (erased > 0) {
334*f5c631daSSadaf Ebrahimi       VIXL_CHECK(erased == 1);
335*f5c631daSSadaf Ebrahimi       expected_total -= to_erase.back().val_;
336*f5c631daSSadaf Ebrahimi     } else {
337*f5c631daSSadaf Ebrahimi     }
338*f5c631daSSadaf Ebrahimi     to_erase.pop_back();
339*f5c631daSSadaf Ebrahimi 
340*f5c631daSSadaf Ebrahimi     size = 0;
341*f5c631daSSadaf Ebrahimi     total = 0;
342*f5c631daSSadaf Ebrahimi     for (auto object : set) {
343*f5c631daSSadaf Ebrahimi       total += object.val_;
344*f5c631daSSadaf Ebrahimi       size++;
345*f5c631daSSadaf Ebrahimi     }
346*f5c631daSSadaf Ebrahimi     VIXL_CHECK(size == set.size());
347*f5c631daSSadaf Ebrahimi     VIXL_CHECK(total == expected_total);
348*f5c631daSSadaf Ebrahimi   }
349*f5c631daSSadaf Ebrahimi }
350*f5c631daSSadaf Ebrahimi #endif
351*f5c631daSSadaf Ebrahimi 
352*f5c631daSSadaf Ebrahimi 
TEST(stl_forward_iterator)353*f5c631daSSadaf Ebrahimi TEST(stl_forward_iterator) {
354*f5c631daSSadaf Ebrahimi   {
355*f5c631daSSadaf Ebrahimi     TestSet::iterator default_it;           // Default-constructible.
356*f5c631daSSadaf Ebrahimi     TestSet::iterator copy_it(default_it);  // Copy-constructible.
357*f5c631daSSadaf Ebrahimi     copy_it = default_it;                   // Copy-assignable.
358*f5c631daSSadaf Ebrahimi   }                                         // Destructible.
359*f5c631daSSadaf Ebrahimi 
360*f5c631daSSadaf Ebrahimi   TestSet set1;
361*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set1.empty() && (set1.size() == 0));
362*f5c631daSSadaf Ebrahimi 
363*f5c631daSSadaf Ebrahimi   TestSet set2;
364*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set2.empty() && (set2.size() == 0));
365*f5c631daSSadaf Ebrahimi 
366*f5c631daSSadaf Ebrahimi   // Test with only preallocated elements in the set.
367*f5c631daSSadaf Ebrahimi   for (unsigned i = 0; i < kNPreallocatedElements; i++) {
368*f5c631daSSadaf Ebrahimi     set1.insert(Obj(i, 1));
369*f5c631daSSadaf Ebrahimi     set2.insert(Obj(i, 2));
370*f5c631daSSadaf Ebrahimi   }
371*f5c631daSSadaf Ebrahimi 
372*f5c631daSSadaf Ebrahimi   TestSet::iterator it1_a = set1.begin();
373*f5c631daSSadaf Ebrahimi   TestSet::iterator it1_b = set1.begin();
374*f5c631daSSadaf Ebrahimi 
375*f5c631daSSadaf Ebrahimi   // Incrementable (whilst valid).
376*f5c631daSSadaf Ebrahimi   it1_a++;
377*f5c631daSSadaf Ebrahimi   ++it1_b;
378*f5c631daSSadaf Ebrahimi 
379*f5c631daSSadaf Ebrahimi   // Testable for equivalence.
380*f5c631daSSadaf Ebrahimi   VIXL_CHECK(it1_a == it1_b);
381*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set1.begin() != set1.end());
382*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set2.begin() != set2.end());
383*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set1.begin() != set2.begin());
384*f5c631daSSadaf Ebrahimi   VIXL_CHECK(set1.end() != set2.end());
385*f5c631daSSadaf Ebrahimi 
386*f5c631daSSadaf Ebrahimi   // Dereferencable.
387*f5c631daSSadaf Ebrahimi   VIXL_CHECK((*it1_a++).key_ == 1);
388*f5c631daSSadaf Ebrahimi   VIXL_CHECK(((*it1_a).key_ == 2) && ((*it1_a).val_ == 1));
389*f5c631daSSadaf Ebrahimi   *it1_b = Obj(42, 1);
390*f5c631daSSadaf Ebrahimi   VIXL_CHECK((it1_b->key_ == 42) && (it1_b->val_ == 1));
391*f5c631daSSadaf Ebrahimi 
392*f5c631daSSadaf Ebrahimi #if __cplusplus >= 201103L
393*f5c631daSSadaf Ebrahimi   // Swappable.
394*f5c631daSSadaf Ebrahimi   std::swap(it1_a, it1_b);
395*f5c631daSSadaf Ebrahimi   VIXL_CHECK(it1_a->key_ == 42);
396*f5c631daSSadaf Ebrahimi   VIXL_CHECK(it1_b->key_ == 2);
397*f5c631daSSadaf Ebrahimi #endif
398*f5c631daSSadaf Ebrahimi }
399*f5c631daSSadaf Ebrahimi 
400*f5c631daSSadaf Ebrahimi 
401*f5c631daSSadaf Ebrahimi }  // namespace vixl
402