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