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