36 #include <array> |
36 #include <array> |
37 #include <vector> |
37 #include <vector> |
38 #include <unordered_set> |
38 #include <unordered_set> |
39 #include <algorithm> |
39 #include <algorithm> |
40 |
40 |
41 struct node { |
|
42 node *next = NULL; |
|
43 node *prev = NULL; |
|
44 int data = 0; |
|
45 }; |
|
46 |
|
47 const ptrdiff_t loc_prev = offsetof(struct node, prev); |
|
48 const ptrdiff_t loc_next = offsetof(struct node, next); |
|
49 const ptrdiff_t loc_data = offsetof(struct node, data); |
|
50 |
|
51 struct node_test_data { |
|
52 node *begin = NULL; |
|
53 |
|
54 explicit node_test_data(node *begin) : begin(begin) { |
|
55 auto n = begin; |
|
56 while (n != NULL) { |
|
57 nodes.push_back(n); |
|
58 n = n->next; |
|
59 } |
|
60 } |
|
61 |
|
62 node_test_data(node_test_data &) = delete; |
|
63 |
|
64 node_test_data(node_test_data &&) = default; |
|
65 |
|
66 ~node_test_data() { |
|
67 for (auto &&n: nodes) delete n; |
|
68 } |
|
69 |
|
70 private: |
|
71 std::vector<node *> nodes; |
|
72 }; |
|
73 |
|
74 static node_test_data create_nodes_test_data(size_t len) { |
|
75 if (len == 0) return node_test_data{NULL}; |
|
76 auto begin = new node; |
|
77 auto prev = begin; |
|
78 for (size_t i = 1; i < len; i++) { |
|
79 auto n = new node; |
|
80 cx_linked_list_link(prev, n, loc_prev, loc_next); |
|
81 prev = n; |
|
82 } |
|
83 return node_test_data{begin}; |
|
84 } |
|
85 |
|
86 template<typename InputIter> |
|
87 static node_test_data create_nodes_test_data( |
|
88 InputIter begin, |
|
89 InputIter end |
|
90 ) { |
|
91 if (begin == end) return node_test_data{NULL}; |
|
92 node *first = new node; |
|
93 first->data = *begin; |
|
94 node *prev = first; |
|
95 begin++; |
|
96 for (; begin != end; begin++) { |
|
97 auto n = new node; |
|
98 n->data = *begin; |
|
99 cx_linked_list_link(prev, n, loc_prev, loc_next); |
|
100 prev = n; |
|
101 } |
|
102 return node_test_data{first}; |
|
103 } |
|
104 |
|
105 static node_test_data create_nodes_test_data(std::initializer_list<int> data) { |
|
106 return create_nodes_test_data(data.begin(), data.end()); |
|
107 } |
|
108 |
|
109 template<size_t N> |
|
110 struct int_test_data { |
|
111 std::array<int, N> data; |
|
112 |
|
113 int_test_data() { |
|
114 cx_for_n (i, N) data[i] = ::rand(); // NOLINT(cert-msc50-cpp) |
|
115 } |
|
116 }; |
|
117 |
|
118 TEST(LinkedList_LowLevel, link_unlink) { |
|
119 node a, b, c; |
|
120 |
|
121 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
122 CX_TEST_ASSERT(a.prev == NULL); |
|
123 CX_TEST_ASSERT(a.next == &b); |
|
124 CX_TEST_ASSERT(b.prev == &a); |
|
125 CX_TEST_ASSERT(b.next == NULL); |
|
126 |
|
127 cx_linked_list_unlink(&a, &b, loc_prev, loc_next); |
|
128 CX_TEST_ASSERT(a.prev == NULL); |
|
129 CX_TEST_ASSERT(a.next == NULL); |
|
130 CX_TEST_ASSERT(b.prev == NULL); |
|
131 CX_TEST_ASSERT(b.next == NULL); |
|
132 |
|
133 cx_linked_list_link(&b, &c, loc_prev, loc_next); |
|
134 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
135 cx_linked_list_unlink(&b, &c, loc_prev, loc_next); |
|
136 CX_TEST_ASSERT(a.prev == NULL); |
|
137 CX_TEST_ASSERT(a.next == &b); |
|
138 CX_TEST_ASSERT(b.prev == &a); |
|
139 CX_TEST_ASSERT(b.next == NULL); |
|
140 CX_TEST_ASSERT(c.prev == NULL); |
|
141 CX_TEST_ASSERT(c.next == NULL); |
|
142 } |
|
143 |
|
144 TEST(LinkedList_LowLevel, cx_linked_list_at) { |
|
145 node a, b, c, d; |
|
146 cx_linked_list_link(&a, &b, loc_prev, loc_next); |
|
147 cx_linked_list_link(&b, &c, loc_prev, loc_next); |
|
148 cx_linked_list_link(&c, &d, loc_prev, loc_next); |
|
149 |
|
150 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 0), &a); |
|
151 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 1), &b); |
|
152 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 2), &c); |
|
153 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 3), &d); |
|
154 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 4), NULL); |
|
155 |
|
156 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_prev, 0), &a); |
|
157 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 1), &b); |
|
158 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 2), &c); |
|
159 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 3), &d); |
|
160 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 4), NULL); |
|
161 |
|
162 EXPECT_EQ(cx_linked_list_at(&d, 3, loc_prev, 0), &a); |
|
163 EXPECT_EQ(cx_linked_list_at(&d, 3, loc_prev, 1), &b); |
|
164 } |
|
165 |
|
166 TEST(LinkedList_LowLevel, cx_linked_list_find) { |
|
167 auto testdata = create_nodes_test_data({2, 4, 6, 8}); |
|
168 auto list = testdata.begin; |
|
169 int s; |
|
170 |
|
171 s = 2; |
|
172 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 0); |
|
173 s = 4; |
|
174 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 1); |
|
175 s = 6; |
|
176 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 2); |
|
177 s = 8; |
|
178 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 3); |
|
179 s = 10; |
|
180 EXPECT_LT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 0); |
|
181 s = -2; |
|
182 EXPECT_LT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s), 0); |
|
183 } |
|
184 |
|
185 TEST(LinkedList_LowLevel, cx_linked_list_compare) { |
|
186 auto ta = create_nodes_test_data({2, 4, 6, 8}); |
|
187 auto tb = create_nodes_test_data({2, 4, 6}); |
|
188 auto tc = create_nodes_test_data({2, 4, 6, 9}); |
|
189 auto la = ta.begin, lb = tb.begin, lc = tc.begin; |
|
190 |
|
191 EXPECT_GT(cx_linked_list_compare(la, lb, loc_next, loc_data, cx_cmp_int), 0); |
|
192 EXPECT_LT(cx_linked_list_compare(lb, la, loc_next, loc_data, cx_cmp_int), 0); |
|
193 EXPECT_GT(cx_linked_list_compare(lc, la, loc_next, loc_data, cx_cmp_int), 0); |
|
194 EXPECT_LT(cx_linked_list_compare(la, lc, loc_next, loc_data, cx_cmp_int), 0); |
|
195 EXPECT_EQ(cx_linked_list_compare(la, la, loc_next, loc_data, cx_cmp_int), 0); |
|
196 } |
|
197 |
|
198 TEST(LinkedList_LowLevel, cx_linked_list_add) { |
|
199 // test with begin, end / prev, next |
|
200 { |
|
201 node nodes[4]; |
|
202 void *begin = NULL, *end = NULL; |
|
203 |
|
204 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]); |
|
205 CX_TEST_ASSERT(begin == &nodes[0]); |
|
206 CX_TEST_ASSERT(end == &nodes[0]); |
|
207 CX_TEST_ASSERT(nodes[0].prev == NULL); |
|
208 CX_TEST_ASSERT(nodes[0].next == NULL); |
|
209 |
|
210 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]); |
|
211 CX_TEST_ASSERT(begin == &nodes[0]); |
|
212 CX_TEST_ASSERT(end == &nodes[1]); |
|
213 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); |
|
214 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); |
|
215 } |
|
216 |
|
217 // test with begin only / prev, next |
|
218 { |
|
219 node nodes[4]; |
|
220 void *begin = NULL; |
|
221 |
|
222 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]); |
|
223 CX_TEST_ASSERT(begin == &nodes[0]); |
|
224 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]); |
|
225 CX_TEST_ASSERT(begin == &nodes[0]); |
|
226 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); |
|
227 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); |
|
228 |
|
229 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]); |
|
230 CX_TEST_ASSERT(nodes[1].next == &nodes[2]); |
|
231 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]); |
|
232 } |
|
233 |
|
234 // test with end only / prev, next |
|
235 { |
|
236 node nodes[4]; |
|
237 void *end = NULL; |
|
238 |
|
239 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]); |
|
240 CX_TEST_ASSERT(end == &nodes[0]); |
|
241 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]); |
|
242 CX_TEST_ASSERT(end == &nodes[1]); |
|
243 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); |
|
244 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); |
|
245 |
|
246 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]); |
|
247 CX_TEST_ASSERT(end == &nodes[2]); |
|
248 CX_TEST_ASSERT(nodes[1].next == &nodes[2]); |
|
249 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]); |
|
250 } |
|
251 |
|
252 // test with begin, end / next |
|
253 { |
|
254 node nodes[4]; |
|
255 void *begin = NULL, *end = NULL; |
|
256 |
|
257 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]); |
|
258 CX_TEST_ASSERT(begin == &nodes[0]); |
|
259 CX_TEST_ASSERT(end == &nodes[0]); |
|
260 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]); |
|
261 CX_TEST_ASSERT(end == &nodes[1]); |
|
262 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); |
|
263 CX_TEST_ASSERT(nodes[1].prev == NULL); |
|
264 } |
|
265 } |
|
266 |
|
267 TEST(LinkedList_LowLevel, cx_linked_list_prepend) { |
|
268 // test with begin, end / prev, next |
|
269 { |
|
270 node nodes[4]; |
|
271 void *begin = NULL, *end = NULL; |
|
272 |
|
273 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]); |
|
274 CX_TEST_ASSERT(begin == &nodes[0]); |
|
275 CX_TEST_ASSERT(end == &nodes[0]); |
|
276 CX_TEST_ASSERT(nodes[0].prev == NULL); |
|
277 CX_TEST_ASSERT(nodes[0].next == NULL); |
|
278 |
|
279 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]); |
|
280 CX_TEST_ASSERT(begin == &nodes[1]); |
|
281 CX_TEST_ASSERT(end == &nodes[0]); |
|
282 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); |
|
283 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); |
|
284 } |
|
285 |
|
286 // test with begin only / prev, next |
|
287 { |
|
288 node nodes[4]; |
|
289 void *begin = NULL; |
|
290 |
|
291 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]); |
|
292 CX_TEST_ASSERT(begin == &nodes[0]); |
|
293 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]); |
|
294 CX_TEST_ASSERT(begin == &nodes[1]); |
|
295 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); |
|
296 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); |
|
297 |
|
298 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]); |
|
299 CX_TEST_ASSERT(begin == &nodes[2]); |
|
300 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); |
|
301 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]); |
|
302 } |
|
303 |
|
304 // test with end only / prev, next |
|
305 { |
|
306 node nodes[4]; |
|
307 void *end = NULL; |
|
308 |
|
309 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]); |
|
310 CX_TEST_ASSERT(end == &nodes[0]); |
|
311 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]); |
|
312 CX_TEST_ASSERT(end == &nodes[0]); |
|
313 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); |
|
314 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); |
|
315 |
|
316 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]); |
|
317 CX_TEST_ASSERT(end == &nodes[0]); |
|
318 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); |
|
319 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]); |
|
320 } |
|
321 |
|
322 // test with begin, end / next |
|
323 { |
|
324 node nodes[4]; |
|
325 void *begin = NULL, *end = NULL; |
|
326 |
|
327 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]); |
|
328 CX_TEST_ASSERT(begin == &nodes[0]); |
|
329 CX_TEST_ASSERT(end == &nodes[0]); |
|
330 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]); |
|
331 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]); |
|
332 CX_TEST_ASSERT(begin == &nodes[2]); |
|
333 CX_TEST_ASSERT(end == &nodes[0]); |
|
334 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); |
|
335 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); |
|
336 CX_TEST_ASSERT(nodes[1].prev == NULL); |
|
337 CX_TEST_ASSERT(nodes[0].prev == NULL); |
|
338 } |
|
339 } |
|
340 |
|
341 TEST(LinkedList_LowLevel, cx_linked_list_insert) { |
|
342 // insert mid list |
|
343 { |
|
344 node nodes[4]; |
|
345 void *begin = &nodes[0], *end = &nodes[2]; |
|
346 |
|
347 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
348 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
349 |
|
350 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]); |
|
351 CX_TEST_ASSERT(begin == &nodes[0]); |
|
352 CX_TEST_ASSERT(end == &nodes[2]); |
|
353 CX_TEST_ASSERT(nodes[1].next == &nodes[3]); |
|
354 CX_TEST_ASSERT(nodes[2].prev == &nodes[3]); |
|
355 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]); |
|
356 CX_TEST_ASSERT(nodes[3].next == &nodes[2]); |
|
357 } |
|
358 |
|
359 // insert end |
|
360 { |
|
361 node nodes[4]; |
|
362 void *begin = &nodes[0], *end = &nodes[2]; |
|
363 |
|
364 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
365 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
366 |
|
367 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]); |
|
368 CX_TEST_ASSERT(begin == &nodes[0]); |
|
369 CX_TEST_ASSERT(end == &nodes[3]); |
|
370 CX_TEST_ASSERT(nodes[2].next == &nodes[3]); |
|
371 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]); |
|
372 CX_TEST_ASSERT(nodes[3].next == NULL); |
|
373 } |
|
374 |
|
375 // insert begin |
|
376 { |
|
377 node nodes[4]; |
|
378 void *begin = &nodes[0], *end = &nodes[2]; |
|
379 |
|
380 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
381 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
382 |
|
383 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]); |
|
384 CX_TEST_ASSERT(begin == &nodes[3]); |
|
385 CX_TEST_ASSERT(end == &nodes[2]); |
|
386 CX_TEST_ASSERT(nodes[0].prev == &nodes[3]); |
|
387 CX_TEST_ASSERT(nodes[3].prev == NULL); |
|
388 CX_TEST_ASSERT(nodes[3].next == &nodes[0]); |
|
389 } |
|
390 } |
|
391 |
|
392 TEST(LinkedList_LowLevel, cx_linked_list_insert_chain) { |
|
393 // insert mid list |
|
394 { |
|
395 node nodes[5]; |
|
396 void *begin = &nodes[0], *end = &nodes[2]; |
|
397 |
|
398 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
399 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
400 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
401 |
|
402 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL); |
|
403 CX_TEST_ASSERT(begin == &nodes[0]); |
|
404 CX_TEST_ASSERT(end == &nodes[2]); |
|
405 CX_TEST_ASSERT(nodes[1].next == &nodes[3]); |
|
406 CX_TEST_ASSERT(nodes[2].prev == &nodes[4]); |
|
407 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]); |
|
408 CX_TEST_ASSERT(nodes[4].next == &nodes[2]); |
|
409 } |
|
410 |
|
411 // insert end |
|
412 { |
|
413 node nodes[5]; |
|
414 void *begin = &nodes[0], *end = &nodes[2]; |
|
415 |
|
416 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
417 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
418 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
419 |
|
420 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL); |
|
421 CX_TEST_ASSERT(begin == &nodes[0]); |
|
422 CX_TEST_ASSERT(end == &nodes[4]); |
|
423 CX_TEST_ASSERT(nodes[2].next == &nodes[3]); |
|
424 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]); |
|
425 CX_TEST_ASSERT(nodes[4].next == NULL); |
|
426 } |
|
427 |
|
428 // insert begin |
|
429 { |
|
430 node nodes[5]; |
|
431 void *begin = &nodes[0], *end = &nodes[2]; |
|
432 |
|
433 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); |
|
434 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); |
|
435 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); |
|
436 |
|
437 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL); |
|
438 CX_TEST_ASSERT(begin == &nodes[3]); |
|
439 CX_TEST_ASSERT(end == &nodes[2]); |
|
440 CX_TEST_ASSERT(nodes[0].prev == &nodes[4]); |
|
441 CX_TEST_ASSERT(nodes[3].prev == NULL); |
|
442 CX_TEST_ASSERT(nodes[4].next == &nodes[0]); |
|
443 } |
|
444 } |
|
445 |
|
446 TEST(LinkedList_LowLevel, cx_linked_list_first) { |
|
447 auto testdata = create_nodes_test_data(3); |
|
448 auto begin = testdata.begin; |
|
449 EXPECT_EQ(cx_linked_list_first(begin, loc_prev), begin); |
|
450 EXPECT_EQ(cx_linked_list_first(begin->next, loc_prev), begin); |
|
451 EXPECT_EQ(cx_linked_list_first(begin->next->next, loc_prev), begin); |
|
452 } |
|
453 |
|
454 TEST(LinkedList_LowLevel, cx_linked_list_last) { |
|
455 auto testdata = create_nodes_test_data(3); |
|
456 auto begin = testdata.begin; |
|
457 auto end = begin->next->next; |
|
458 EXPECT_EQ(cx_linked_list_last(begin, loc_next), end); |
|
459 EXPECT_EQ(cx_linked_list_last(begin->next, loc_next), end); |
|
460 EXPECT_EQ(cx_linked_list_last(begin->next->next, loc_next), end); |
|
461 } |
|
462 |
|
463 TEST(LinkedList_LowLevel, cx_linked_list_prev) { |
|
464 auto testdata = create_nodes_test_data(3); |
|
465 auto begin = testdata.begin; |
|
466 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin), NULL); |
|
467 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin->next), begin); |
|
468 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin->next->next), begin->next); |
|
469 } |
|
470 |
|
471 TEST(LinkedList_LowLevel, cx_linked_list_remove) { |
|
472 auto testdata = create_nodes_test_data({2, 4, 6}); |
|
473 auto begin = reinterpret_cast<void *>(testdata.begin); |
|
474 auto first = testdata.begin; |
|
475 auto second = first->next; |
|
476 auto third = second->next; |
|
477 auto end = reinterpret_cast<void *>(third); |
|
478 |
|
479 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second); |
|
480 CX_TEST_ASSERT(begin == first); |
|
481 CX_TEST_ASSERT(end == third); |
|
482 CX_TEST_ASSERT(first->prev == NULL); |
|
483 CX_TEST_ASSERT(first->next == third); |
|
484 CX_TEST_ASSERT(third->prev == first); |
|
485 CX_TEST_ASSERT(third->next == NULL); |
|
486 |
|
487 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third); |
|
488 CX_TEST_ASSERT(begin == first); |
|
489 CX_TEST_ASSERT(end == first); |
|
490 CX_TEST_ASSERT(first->prev == NULL); |
|
491 CX_TEST_ASSERT(first->next == NULL); |
|
492 |
|
493 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first); |
|
494 CX_TEST_ASSERT(begin == NULL); |
|
495 CX_TEST_ASSERT(end == NULL); |
|
496 } |
|
497 |
|
498 TEST(LinkedList_LowLevel, cx_linked_list_size) { |
|
499 EXPECT_EQ(cx_linked_list_size(NULL, loc_next), 0); |
|
500 |
|
501 { |
|
502 auto testdata = create_nodes_test_data(5); |
|
503 EXPECT_EQ(cx_linked_list_size(testdata.begin, loc_next), 5); |
|
504 } |
|
505 |
|
506 { |
|
507 auto testdata = create_nodes_test_data(13); |
|
508 EXPECT_EQ(cx_linked_list_size(testdata.begin, loc_next), 13); |
|
509 } |
|
510 } |
|
511 |
|
512 TEST(LinkedList_LowLevel, cx_linked_list_sort_empty) { |
|
513 void *begin = NULL; |
|
514 EXPECT_NO_FATAL_FAILURE( |
|
515 cx_linked_list_sort(&begin, NULL, loc_prev, loc_next, loc_data, cx_cmp_int); |
|
516 ); |
|
517 } |
|
518 |
|
519 TEST(LinkedList_LowLevel, cx_linked_list_sort) { |
|
520 int_test_data<1500> testdata; |
|
521 std::array<int, 1500> sorted{}; |
|
522 std::partial_sort_copy(testdata.data.begin(), testdata.data.end(), sorted.begin(), sorted.end()); |
|
523 |
|
524 auto scrambled = create_nodes_test_data(testdata.data.begin(), testdata.data.end()); |
|
525 void *begin = scrambled.begin; |
|
526 void *end = cx_linked_list_last(begin, loc_next); |
|
527 |
|
528 cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, cx_cmp_int); |
|
529 |
|
530 node *check = reinterpret_cast<node *>(begin); |
|
531 node *check_last = NULL; |
|
532 cx_for_n (i, sorted.size()) { |
|
533 CX_TEST_ASSERT(check->data == sorted[i]); |
|
534 CX_TEST_ASSERT(check->prev == check_last); |
|
535 if (i < sorted.size() - 1) { |
|
536 ASSERT_NE(check->next, NULL); |
|
537 } |
|
538 check_last = check; |
|
539 check = check->next; |
|
540 } |
|
541 CX_TEST_ASSERT(check == NULL); |
|
542 CX_TEST_ASSERT(end == check_last); |
|
543 } |
|
544 |
|
545 TEST(LinkedList_LowLevel, cx_linked_list_reverse) { |
|
546 auto testdata = create_nodes_test_data({2, 4, 6, 8}); |
|
547 auto expected = create_nodes_test_data({8, 6, 4, 2}); |
|
548 |
|
549 auto begin = reinterpret_cast<void *>(testdata.begin); |
|
550 auto end = cx_linked_list_last(begin, loc_next); |
|
551 auto orig_begin = begin, orig_end = end; |
|
552 |
|
553 cx_linked_list_reverse(&begin, &end, loc_prev, loc_next); |
|
554 CX_TEST_ASSERT(end == orig_begin); |
|
555 CX_TEST_ASSERT(begin == orig_end); |
|
556 EXPECT_EQ(cx_linked_list_compare(begin, expected.begin, loc_next, loc_data, cx_cmp_int), 0); |
|
557 } |
|
558 |
41 |
559 class HighLevelTest : public ::testing::Test { |
42 class HighLevelTest : public ::testing::Test { |
560 mutable std::unordered_set<CxList *> lists; |
43 mutable std::unordered_set<CxList *> lists; |
561 protected: |
44 protected: |
562 CxTestingAllocator testingAllocator; |
45 CxTestingAllocator testingAllocator; |