test/test_list.cpp

Tue, 04 Oct 2022 19:25:07 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 04 Oct 2022 19:25:07 +0200
changeset 591
7df0bcaecffa
parent 552
4373c2a90066
child 602
3b071ea0e9cf
permissions
-rw-r--r--

fix over-optimization of strstr

1. it's actually less performant to frequently read bytes
from an array instead of using the native word length
2. the SBO buffer should be local and not static to allow
multi-threading usage

universe@390 1 /*
universe@390 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@390 3 *
universe@390 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@390 5 *
universe@390 6 * Redistribution and use in source and binary forms, with or without
universe@390 7 * modification, are permitted provided that the following conditions are met:
universe@390 8 *
universe@390 9 * 1. Redistributions of source code must retain the above copyright
universe@390 10 * notice, this list of conditions and the following disclaimer.
universe@390 11 *
universe@390 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@390 13 * notice, this list of conditions and the following disclaimer in the
universe@390 14 * documentation and/or other materials provided with the distribution.
universe@390 15 *
universe@390 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@390 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@390 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@390 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@390 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@390 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@390 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@390 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@390 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@390 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@390 26 * POSSIBILITY OF SUCH DAMAGE.
universe@390 27 */
universe@390 28
universe@398 29 #include "cx/linked_list.h"
universe@509 30 #include "cx/utils.h"
universe@422 31 #include "util_allocator.h"
universe@398 32
universe@517 33 #include <gtest/gtest.h>
universe@517 34 #include <array>
universe@517 35 #include <vector>
universe@517 36 #include <unordered_set>
universe@517 37 #include <algorithm>
universe@517 38
universe@507 39 static int cmp_int_impl(
universe@486 40 int const *l,
universe@486 41 int const *r
universe@486 42 ) {
universe@412 43 int left = *l, right = *r;
universe@412 44 return left == right ? 0 : (left < right ? -1 : 1);
universe@412 45 }
universe@412 46
universe@492 47 #define cmp_int ((CxListComparator) cmp_int_impl)
universe@492 48
universe@486 49 struct node {
universe@517 50 node *next = nullptr;
universe@517 51 node *prev = nullptr;
universe@517 52 int data = 0;
universe@486 53 };
universe@486 54
universe@486 55 const ptrdiff_t loc_prev = offsetof(struct node, prev);
universe@486 56 const ptrdiff_t loc_next = offsetof(struct node, next);
universe@486 57 const ptrdiff_t loc_data = offsetof(struct node, data);
universe@486 58
universe@517 59 struct node_test_data {
universe@520 60 node *begin = nullptr;
universe@517 61
universe@520 62 explicit node_test_data(node *begin) : begin(begin) {
universe@520 63 auto n = begin;
universe@520 64 while (n != nullptr) {
universe@520 65 nodes.push_back(n);
universe@520 66 n = n->next;
universe@520 67 }
universe@520 68 }
universe@520 69
universe@520 70 node_test_data(node_test_data &) = delete;
universe@520 71
universe@520 72 node_test_data(node_test_data &&) = default;
universe@517 73
universe@517 74 ~node_test_data() {
universe@520 75 for (auto &&n: nodes) delete n;
universe@486 76 }
universe@520 77
universe@520 78 private:
universe@520 79 std::vector<node *> nodes;
universe@517 80 };
universe@517 81
universe@517 82 static node_test_data create_nodes_test_data(size_t len) {
universe@517 83 if (len == 0) return node_test_data{nullptr};
universe@517 84 auto begin = new node;
universe@517 85 auto prev = begin;
universe@517 86 for (size_t i = 1; i < len; i++) {
universe@517 87 auto n = new node;
universe@517 88 cx_linked_list_link(prev, n, loc_prev, loc_next);
universe@517 89 prev = n;
universe@517 90 }
universe@517 91 return node_test_data{begin};
universe@486 92 }
universe@486 93
universe@517 94 template<typename InputIter>
universe@528 95 static node_test_data create_nodes_test_data(
universe@528 96 InputIter begin,
universe@528 97 InputIter end
universe@528 98 ) {
universe@517 99 if (begin == end) return node_test_data{nullptr};
universe@517 100 node *first = new node;
universe@517 101 first->data = *begin;
universe@517 102 node *prev = first;
universe@517 103 begin++;
universe@517 104 for (; begin != end; begin++) {
universe@517 105 auto n = new node;
universe@517 106 n->data = *begin;
universe@517 107 cx_linked_list_link(prev, n, loc_prev, loc_next);
universe@517 108 prev = n;
universe@486 109 }
universe@517 110 return node_test_data{first};
universe@486 111 }
universe@486 112
universe@517 113 static node_test_data create_nodes_test_data(std::initializer_list<int> data) {
universe@517 114 return create_nodes_test_data(data.begin(), data.end());
universe@509 115 }
universe@509 116
universe@517 117 template<size_t N>
universe@517 118 struct int_test_data {
universe@517 119 std::array<int, N> data;
universe@482 120
universe@517 121 int_test_data() {
universe@517 122 cx_for_n (i, N) data[i] = ::rand(); // NOLINT(cert-msc50-cpp)
universe@517 123 }
universe@517 124 };
universe@517 125
universe@517 126 TEST(LinkedList_LowLevel, link_unlink) {
universe@517 127 node a, b, c;
universe@482 128
universe@482 129 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@517 130 EXPECT_EQ(a.prev, nullptr);
universe@517 131 EXPECT_EQ(a.next, &b);
universe@517 132 EXPECT_EQ(b.prev, &a);
universe@517 133 EXPECT_EQ(b.next, nullptr);
universe@482 134
universe@482 135 cx_linked_list_unlink(&a, &b, loc_prev, loc_next);
universe@517 136 EXPECT_EQ(a.prev, nullptr);
universe@517 137 EXPECT_EQ(a.next, nullptr);
universe@517 138 EXPECT_EQ(b.prev, nullptr);
universe@517 139 EXPECT_EQ(b.next, nullptr);
universe@482 140
universe@482 141 cx_linked_list_link(&b, &c, loc_prev, loc_next);
universe@482 142 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@482 143 cx_linked_list_unlink(&b, &c, loc_prev, loc_next);
universe@517 144 EXPECT_EQ(a.prev, nullptr);
universe@517 145 EXPECT_EQ(a.next, &b);
universe@517 146 EXPECT_EQ(b.prev, &a);
universe@517 147 EXPECT_EQ(b.next, nullptr);
universe@517 148 EXPECT_EQ(c.prev, nullptr);
universe@517 149 EXPECT_EQ(c.next, nullptr);
universe@482 150 }
universe@482 151
universe@517 152 TEST(LinkedList_LowLevel, cx_linked_list_at) {
universe@517 153 node a, b, c, d;
universe@486 154 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@486 155 cx_linked_list_link(&b, &c, loc_prev, loc_next);
universe@486 156 cx_linked_list_link(&c, &d, loc_prev, loc_next);
universe@438 157
universe@517 158 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 0), &a);
universe@517 159 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 1), &b);
universe@517 160 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 2), &c);
universe@517 161 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 3), &d);
universe@517 162 EXPECT_EQ(cx_linked_list_at(&a, 0, loc_next, 4), nullptr);
universe@438 163
universe@517 164 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_prev, 0), &a);
universe@517 165 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 1), &b);
universe@517 166 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 2), &c);
universe@517 167 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 3), &d);
universe@517 168 EXPECT_EQ(cx_linked_list_at(&b, 1, loc_next, 4), nullptr);
universe@438 169
universe@517 170 EXPECT_EQ(cx_linked_list_at(&d, 3, loc_prev, 0), &a);
universe@517 171 EXPECT_EQ(cx_linked_list_at(&d, 3, loc_prev, 1), &b);
universe@438 172 }
universe@438 173
universe@517 174 TEST(LinkedList_LowLevel, cx_linked_list_find) {
universe@517 175 auto testdata = create_nodes_test_data({2, 4, 6, 8});
universe@517 176 auto list = testdata.begin;
universe@487 177 int s;
universe@487 178
universe@487 179 s = 2;
universe@517 180 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 0);
universe@487 181 s = 4;
universe@517 182 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 1);
universe@487 183 s = 6;
universe@517 184 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 2);
universe@487 185 s = 8;
universe@517 186 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 3);
universe@487 187 s = 10;
universe@517 188 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 4);
universe@487 189 s = -2;
universe@517 190 EXPECT_EQ(cx_linked_list_find(list, loc_next, loc_data, false, cmp_int, &s), 4);
universe@487 191 }
universe@487 192
universe@517 193 TEST(LinkedList_LowLevel, cx_linked_list_compare) {
universe@517 194 auto ta = create_nodes_test_data({2, 4, 6, 8});
universe@517 195 auto tb = create_nodes_test_data({2, 4, 6});
universe@517 196 auto tc = create_nodes_test_data({2, 4, 6, 9});
universe@517 197 auto la = ta.begin, lb = tb.begin, lc = tc.begin;
universe@486 198
universe@552 199 EXPECT_GT(cx_linked_list_compare(la, lb, loc_next, loc_data, false, false, cmp_int), 0);
universe@552 200 EXPECT_LT(cx_linked_list_compare(lb, la, loc_next, loc_data, false, false, cmp_int), 0);
universe@552 201 EXPECT_GT(cx_linked_list_compare(lc, la, loc_next, loc_data, false, false, cmp_int), 0);
universe@552 202 EXPECT_LT(cx_linked_list_compare(la, lc, loc_next, loc_data, false, false, cmp_int), 0);
universe@552 203 EXPECT_EQ(cx_linked_list_compare(la, la, loc_next, loc_data, false, false, cmp_int), 0);
universe@486 204 }
universe@486 205
universe@517 206 TEST(LinkedList_LowLevel, cx_linked_list_add) {
universe@517 207 // test with begin, end / prev, next
universe@517 208 {
universe@517 209 node nodes[4];
universe@517 210 void *begin = nullptr, *end = nullptr;
universe@449 211
universe@517 212 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]);
universe@517 213 EXPECT_EQ(begin, &nodes[0]);
universe@517 214 EXPECT_EQ(end, &nodes[0]);
universe@517 215 EXPECT_EQ(nodes[0].prev, nullptr);
universe@517 216 EXPECT_EQ(nodes[0].next, nullptr);
universe@449 217
universe@517 218 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]);
universe@517 219 EXPECT_EQ(begin, &nodes[0]);
universe@517 220 EXPECT_EQ(end, &nodes[1]);
universe@517 221 EXPECT_EQ(nodes[0].next, &nodes[1]);
universe@517 222 EXPECT_EQ(nodes[1].prev, &nodes[0]);
universe@517 223 }
universe@449 224
olaf@442 225 // test with begin only / prev, next
universe@517 226 {
universe@517 227 node nodes[4];
universe@517 228 void *begin = nullptr;
universe@449 229
universe@517 230 cx_linked_list_add(&begin, nullptr, loc_prev, loc_next, &nodes[0]);
universe@517 231 EXPECT_EQ(begin, &nodes[0]);
universe@517 232 cx_linked_list_add(&begin, nullptr, loc_prev, loc_next, &nodes[1]);
universe@517 233 EXPECT_EQ(begin, &nodes[0]);
universe@517 234 EXPECT_EQ(nodes[0].next, &nodes[1]);
universe@517 235 EXPECT_EQ(nodes[1].prev, &nodes[0]);
universe@449 236
universe@517 237 cx_linked_list_add(&begin, nullptr, loc_prev, loc_next, &nodes[2]);
universe@517 238 EXPECT_EQ(nodes[1].next, &nodes[2]);
universe@517 239 EXPECT_EQ(nodes[2].prev, &nodes[1]);
universe@517 240 }
universe@449 241
universe@475 242 // test with end only / prev, next
universe@517 243 {
universe@517 244 node nodes[4];
universe@517 245 void *end = nullptr;
universe@475 246
universe@517 247 cx_linked_list_add(nullptr, &end, loc_prev, loc_next, &nodes[0]);
universe@517 248 EXPECT_EQ(end, &nodes[0]);
universe@517 249 cx_linked_list_add(nullptr, &end, loc_prev, loc_next, &nodes[1]);
universe@517 250 EXPECT_EQ(end, &nodes[1]);
universe@517 251 EXPECT_EQ(nodes[0].next, &nodes[1]);
universe@517 252 EXPECT_EQ(nodes[1].prev, &nodes[0]);
universe@475 253
universe@517 254 cx_linked_list_add(nullptr, &end, loc_prev, loc_next, &nodes[2]);
universe@517 255 EXPECT_EQ(end, &nodes[2]);
universe@517 256 EXPECT_EQ(nodes[1].next, &nodes[2]);
universe@517 257 EXPECT_EQ(nodes[2].prev, &nodes[1]);
universe@517 258 }
universe@475 259
olaf@442 260 // test with begin, end / next
universe@517 261 {
universe@517 262 node nodes[4];
universe@517 263 void *begin = nullptr, *end = nullptr;
universe@449 264
universe@517 265 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]);
universe@517 266 EXPECT_EQ(begin, &nodes[0]);
universe@517 267 EXPECT_EQ(end, &nodes[0]);
universe@517 268 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]);
universe@517 269 EXPECT_EQ(end, &nodes[1]);
universe@517 270 EXPECT_EQ(nodes[0].next, &nodes[1]);
universe@517 271 EXPECT_EQ(nodes[1].prev, nullptr);
universe@517 272 }
olaf@442 273 }
olaf@442 274
universe@517 275 TEST(LinkedList_LowLevel, cx_linked_list_prepend) {
universe@517 276 // test with begin, end / prev, next
universe@517 277 {
universe@517 278 node nodes[4];
universe@517 279 void *begin = nullptr, *end = nullptr;
universe@475 280
universe@517 281 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]);
universe@517 282 EXPECT_EQ(begin, &nodes[0]);
universe@517 283 EXPECT_EQ(end, &nodes[0]);
universe@517 284 EXPECT_EQ(nodes[0].prev, nullptr);
universe@517 285 EXPECT_EQ(nodes[0].next, nullptr);
universe@475 286
universe@517 287 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]);
universe@517 288 EXPECT_EQ(begin, &nodes[1]);
universe@517 289 EXPECT_EQ(end, &nodes[0]);
universe@517 290 EXPECT_EQ(nodes[1].next, &nodes[0]);
universe@517 291 EXPECT_EQ(nodes[0].prev, &nodes[1]);
universe@517 292 }
universe@475 293
universe@475 294 // test with begin only / prev, next
universe@517 295 {
universe@517 296 node nodes[4];
universe@517 297 void *begin = nullptr;
universe@475 298
universe@517 299 cx_linked_list_prepend(&begin, nullptr, loc_prev, loc_next, &nodes[0]);
universe@517 300 EXPECT_EQ(begin, &nodes[0]);
universe@517 301 cx_linked_list_prepend(&begin, nullptr, loc_prev, loc_next, &nodes[1]);
universe@517 302 EXPECT_EQ(begin, &nodes[1]);
universe@517 303 EXPECT_EQ(nodes[1].next, &nodes[0]);
universe@517 304 EXPECT_EQ(nodes[0].prev, &nodes[1]);
universe@475 305
universe@517 306 cx_linked_list_prepend(&begin, nullptr, loc_prev, loc_next, &nodes[2]);
universe@517 307 EXPECT_EQ(begin, &nodes[2]);
universe@517 308 EXPECT_EQ(nodes[2].next, &nodes[1]);
universe@517 309 EXPECT_EQ(nodes[1].prev, &nodes[2]);
universe@517 310 }
universe@475 311
universe@475 312 // test with end only / prev, next
universe@517 313 {
universe@517 314 node nodes[4];
universe@517 315 void *end = nullptr;
universe@475 316
universe@517 317 cx_linked_list_prepend(nullptr, &end, loc_prev, loc_next, &nodes[0]);
universe@517 318 EXPECT_EQ(end, &nodes[0]);
universe@517 319 cx_linked_list_prepend(nullptr, &end, loc_prev, loc_next, &nodes[1]);
universe@517 320 EXPECT_EQ(end, &nodes[0]);
universe@517 321 EXPECT_EQ(nodes[1].next, &nodes[0]);
universe@517 322 EXPECT_EQ(nodes[0].prev, &nodes[1]);
universe@475 323
universe@517 324 cx_linked_list_prepend(nullptr, &end, loc_prev, loc_next, &nodes[2]);
universe@517 325 EXPECT_EQ(end, &nodes[0]);
universe@517 326 EXPECT_EQ(nodes[2].next, &nodes[1]);
universe@517 327 EXPECT_EQ(nodes[1].prev, &nodes[2]);
universe@517 328 }
universe@475 329
universe@475 330 // test with begin, end / next
universe@517 331 {
universe@517 332 node nodes[4];
universe@517 333 void *begin = nullptr, *end = nullptr;
universe@475 334
universe@517 335 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]);
universe@517 336 EXPECT_EQ(begin, &nodes[0]);
universe@517 337 EXPECT_EQ(end, &nodes[0]);
universe@517 338 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]);
universe@517 339 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]);
universe@517 340 EXPECT_EQ(begin, &nodes[2]);
universe@517 341 EXPECT_EQ(end, &nodes[0]);
universe@517 342 EXPECT_EQ(nodes[1].next, &nodes[0]);
universe@517 343 EXPECT_EQ(nodes[2].next, &nodes[1]);
universe@517 344 EXPECT_EQ(nodes[1].prev, nullptr);
universe@517 345 EXPECT_EQ(nodes[0].prev, nullptr);
universe@517 346 }
universe@475 347 }
universe@475 348
universe@517 349 TEST(LinkedList_LowLevel, cx_linked_list_insert) {
universe@517 350 // insert mid list
universe@517 351 {
universe@517 352 node nodes[4];
universe@517 353 void *begin = &nodes[0], *end = &nodes[2];
universe@482 354
universe@517 355 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 356 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@482 357
universe@517 358 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]);
universe@517 359 EXPECT_EQ(begin, &nodes[0]);
universe@517 360 EXPECT_EQ(end, &nodes[2]);
universe@517 361 EXPECT_EQ(nodes[1].next, &nodes[3]);
universe@517 362 EXPECT_EQ(nodes[2].prev, &nodes[3]);
universe@517 363 EXPECT_EQ(nodes[3].prev, &nodes[1]);
universe@517 364 EXPECT_EQ(nodes[3].next, &nodes[2]);
universe@517 365 }
universe@482 366
universe@482 367 // insert end
universe@517 368 {
universe@517 369 node nodes[4];
universe@517 370 void *begin = &nodes[0], *end = &nodes[2];
universe@482 371
universe@517 372 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 373 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@482 374
universe@517 375 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]);
universe@517 376 EXPECT_EQ(begin, &nodes[0]);
universe@517 377 EXPECT_EQ(end, &nodes[3]);
universe@517 378 EXPECT_EQ(nodes[2].next, &nodes[3]);
universe@517 379 EXPECT_EQ(nodes[3].prev, &nodes[2]);
universe@517 380 EXPECT_EQ(nodes[3].next, nullptr);
universe@517 381 }
universe@482 382
universe@482 383 // insert begin
universe@517 384 {
universe@517 385 node nodes[4];
universe@517 386 void *begin = &nodes[0], *end = &nodes[2];
universe@482 387
universe@517 388 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 389 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@482 390
universe@517 391 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, nullptr, &nodes[3]);
universe@517 392 EXPECT_EQ(begin, &nodes[3]);
universe@517 393 EXPECT_EQ(end, &nodes[2]);
universe@517 394 EXPECT_EQ(nodes[0].prev, &nodes[3]);
universe@517 395 EXPECT_EQ(nodes[3].prev, nullptr);
universe@517 396 EXPECT_EQ(nodes[3].next, &nodes[0]);
universe@517 397 }
universe@482 398 }
universe@482 399
universe@517 400 TEST(LinkedList_LowLevel, cx_linked_list_insert_chain) {
universe@517 401 // insert mid list
universe@517 402 {
universe@517 403 node nodes[5];
universe@517 404 void *begin = &nodes[0], *end = &nodes[2];
universe@482 405
universe@517 406 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 407 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@517 408 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@482 409
universe@517 410 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], nullptr);
universe@517 411 EXPECT_EQ(begin, &nodes[0]);
universe@517 412 EXPECT_EQ(end, &nodes[2]);
universe@517 413 EXPECT_EQ(nodes[1].next, &nodes[3]);
universe@517 414 EXPECT_EQ(nodes[2].prev, &nodes[4]);
universe@517 415 EXPECT_EQ(nodes[3].prev, &nodes[1]);
universe@517 416 EXPECT_EQ(nodes[4].next, &nodes[2]);
universe@517 417 }
universe@482 418
universe@482 419 // insert end
universe@517 420 {
universe@517 421 node nodes[5];
universe@517 422 void *begin = &nodes[0], *end = &nodes[2];
universe@482 423
universe@517 424 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 425 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@517 426 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@482 427
universe@517 428 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], nullptr);
universe@517 429 EXPECT_EQ(begin, &nodes[0]);
universe@517 430 EXPECT_EQ(end, &nodes[4]);
universe@517 431 EXPECT_EQ(nodes[2].next, &nodes[3]);
universe@517 432 EXPECT_EQ(nodes[3].prev, &nodes[2]);
universe@517 433 EXPECT_EQ(nodes[4].next, nullptr);
universe@517 434 }
universe@482 435
universe@482 436 // insert begin
universe@517 437 {
universe@517 438 node nodes[5];
universe@517 439 void *begin = &nodes[0], *end = &nodes[2];
universe@482 440
universe@517 441 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@517 442 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@517 443 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@482 444
universe@517 445 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, nullptr, &nodes[3], nullptr);
universe@517 446 EXPECT_EQ(begin, &nodes[3]);
universe@517 447 EXPECT_EQ(end, &nodes[2]);
universe@517 448 EXPECT_EQ(nodes[0].prev, &nodes[4]);
universe@517 449 EXPECT_EQ(nodes[3].prev, nullptr);
universe@517 450 EXPECT_EQ(nodes[4].next, &nodes[0]);
universe@517 451 }
universe@482 452 }
universe@482 453
universe@517 454 TEST(LinkedList_LowLevel, cx_linked_list_first) {
universe@517 455 auto testdata = create_nodes_test_data(3);
universe@517 456 auto begin = testdata.begin;
universe@517 457 EXPECT_EQ(cx_linked_list_first(begin, loc_prev), begin);
universe@517 458 EXPECT_EQ(cx_linked_list_first(begin->next, loc_prev), begin);
universe@517 459 EXPECT_EQ(cx_linked_list_first(begin->next->next, loc_prev), begin);
universe@475 460 }
universe@475 461
universe@517 462 TEST(LinkedList_LowLevel, cx_linked_list_last) {
universe@517 463 auto testdata = create_nodes_test_data(3);
universe@517 464 auto begin = testdata.begin;
universe@517 465 auto end = begin->next->next;
universe@517 466 EXPECT_EQ(cx_linked_list_last(begin, loc_next), end);
universe@517 467 EXPECT_EQ(cx_linked_list_last(begin->next, loc_next), end);
universe@517 468 EXPECT_EQ(cx_linked_list_last(begin->next->next, loc_next), end);
universe@456 469 }
universe@456 470
universe@517 471 TEST(LinkedList_LowLevel, cx_linked_list_prev) {
universe@517 472 auto testdata = create_nodes_test_data(3);
universe@517 473 auto begin = testdata.begin;
universe@517 474 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin), nullptr);
universe@517 475 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin->next), begin);
universe@517 476 EXPECT_EQ(cx_linked_list_prev(begin, loc_next, begin->next->next), begin->next);
universe@473 477 }
universe@473 478
universe@517 479 TEST(LinkedList_LowLevel, cx_linked_list_remove) {
universe@517 480 auto testdata = create_nodes_test_data({2, 4, 6});
universe@517 481 auto begin = reinterpret_cast<void *>(testdata.begin);
universe@517 482 auto first = testdata.begin;
universe@517 483 auto second = first->next;
universe@517 484 auto third = second->next;
universe@517 485 auto end = reinterpret_cast<void *>(third);
universe@473 486
universe@486 487 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second);
universe@517 488 EXPECT_EQ(begin, first);
universe@517 489 EXPECT_EQ(end, third);
universe@517 490 EXPECT_EQ(first->prev, nullptr);
universe@517 491 EXPECT_EQ(first->next, third);
universe@517 492 EXPECT_EQ(third->prev, first);
universe@517 493 EXPECT_EQ(third->next, nullptr);
universe@473 494
universe@486 495 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third);
universe@517 496 EXPECT_EQ(begin, first);
universe@517 497 EXPECT_EQ(end, first);
universe@517 498 EXPECT_EQ(first->prev, nullptr);
universe@517 499 EXPECT_EQ(first->next, nullptr);
universe@473 500
universe@486 501 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first);
universe@517 502 EXPECT_EQ(begin, nullptr);
universe@517 503 EXPECT_EQ(end, nullptr);
universe@473 504 }
universe@473 505
universe@517 506 TEST(LinkedList_LowLevel, cx_linked_list_size) {
universe@517 507 EXPECT_EQ(cx_linked_list_size(nullptr, loc_next), 0);
universe@468 508
universe@517 509 {
universe@517 510 auto testdata = create_nodes_test_data(5);
universe@517 511 EXPECT_EQ(cx_linked_list_size(testdata.begin, loc_next), 5);
universe@517 512 }
universe@468 513
universe@517 514 {
universe@517 515 auto testdata = create_nodes_test_data(13);
universe@517 516 EXPECT_EQ(cx_linked_list_size(testdata.begin, loc_next), 13);
universe@517 517 }
universe@468 518 }
universe@468 519
universe@517 520 TEST(LinkedList_LowLevel, cx_linked_list_sort) {
universe@521 521 int_test_data<1500> testdata;
universe@521 522 std::array<int, 1500> sorted{};
universe@517 523 std::partial_sort_copy(testdata.data.begin(), testdata.data.end(), sorted.begin(), sorted.end());
universe@468 524
universe@517 525 auto scrambled = create_nodes_test_data(testdata.data.begin(), testdata.data.end());
universe@517 526 void *begin = scrambled.begin;
universe@486 527 void *end = cx_linked_list_last(begin, loc_next);
universe@468 528
universe@486 529 cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data,
universe@492 530 false, cmp_int);
universe@468 531
universe@517 532 node *check = reinterpret_cast<node *>(begin);
universe@517 533 node *check_last = nullptr;
universe@517 534 cx_for_n (i, sorted.size()) {
universe@517 535 EXPECT_EQ(check->data, sorted[i]);
universe@517 536 EXPECT_EQ(check->prev, check_last);
universe@517 537 if (i < sorted.size() - 1) {
universe@517 538 ASSERT_NE(check->next, nullptr);
universe@468 539 }
universe@468 540 check_last = check;
universe@468 541 check = check->next;
universe@468 542 }
universe@517 543 EXPECT_EQ(check, nullptr);
universe@517 544 EXPECT_EQ(end, check_last);
universe@468 545 }
universe@468 546
universe@517 547 TEST(LinkedList_LowLevel, cx_linked_list_reverse) {
universe@517 548 auto testdata = create_nodes_test_data({2, 4, 6, 8});
universe@517 549 auto expected = create_nodes_test_data({8, 6, 4, 2});
universe@473 550
universe@517 551 auto begin = reinterpret_cast<void *>(testdata.begin);
universe@517 552 auto end = cx_linked_list_last(begin, loc_next);
universe@517 553 auto orig_begin = begin, orig_end = end;
universe@473 554
universe@486 555 cx_linked_list_reverse(&begin, &end, loc_prev, loc_next);
universe@517 556 EXPECT_EQ(end, orig_begin);
universe@517 557 EXPECT_EQ(begin, orig_end);
universe@552 558 EXPECT_EQ(cx_linked_list_compare(begin, expected.begin, loc_next, loc_data, false, false, cmp_int), 0);
universe@473 559 }
universe@456 560
universe@517 561 class HighLevelTest : public ::testing::Test {
universe@517 562 mutable std::unordered_set<CxList *> lists;
universe@517 563 protected:
universe@518 564 CxTestingAllocator testingAllocator;
universe@455 565
universe@517 566 void TearDown() override {
universe@517 567 for (auto &&l: lists) cxListDestroy(l);
universe@518 568 EXPECT_TRUE(testingAllocator.verify());
universe@517 569 }
universe@517 570
universe@517 571 static constexpr size_t testdata_len = 250;
universe@517 572 int_test_data<testdata_len> testdata;
universe@517 573
universe@517 574 auto autofree(CxList *list) const -> CxList * {
universe@517 575 lists.insert(list);
universe@517 576 return list;
universe@517 577 }
universe@517 578
universe@517 579 auto linkedListFromTestData() const -> CxList * {
universe@517 580 return autofree(
universe@517 581 cxLinkedListFromArray(
universe@518 582 &testingAllocator,
universe@517 583 cmp_int,
universe@517 584 sizeof(int),
universe@517 585 testdata_len,
universe@517 586 testdata.data.data()
universe@517 587 )
universe@517 588 );
universe@517 589 }
universe@517 590
universe@517 591 auto pointerLinkedListFromTestData() const -> CxList * {
universe@518 592 auto list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
universe@517 593 cx_for_n(i, testdata_len) cxListAdd(list, &testdata.data[i]);
universe@517 594 return list;
universe@517 595 }
universe@517 596
universe@518 597 void verifyCreate(CxList *list) const {
universe@528 598 EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE);
universe@517 599 EXPECT_EQ(list->size, 0);
universe@517 600 EXPECT_EQ(list->capacity, (size_t) -1);
universe@518 601 EXPECT_EQ(list->allocator, &testingAllocator);
universe@517 602 EXPECT_EQ(list->cmpfunc, cmp_int);
universe@517 603 }
universe@517 604
universe@528 605 void verifyAdd(
universe@528 606 CxList *list,
universe@528 607 bool write_through
universe@528 608 ) {
universe@517 609 auto len = testdata_len;
universe@517 610 cx_for_n (i, len) EXPECT_EQ(cxListAdd(list, &testdata.data[i]), 0);
universe@517 611 EXPECT_EQ(list->size, len);
universe@517 612 EXPECT_GE(list->capacity, list->size);
universe@517 613 cx_for_n (i, len) EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i]);
universe@517 614 cx_for_n (i, len) ++testdata.data[i];
universe@517 615 if (write_through) {
universe@517 616 cx_for_n (i, len) EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i]);
universe@517 617 } else {
universe@517 618 cx_for_n (i, len) EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i] - 1);
universe@517 619 }
universe@517 620 }
universe@517 621
universe@517 622 static void verifyInsert(CxList *list) {
universe@517 623 int a = 5, b = 47, c = 13, d = 42;
universe@517 624
universe@517 625 EXPECT_NE(cxListInsert(list, 1, &a), 0);
universe@517 626 EXPECT_EQ(list->size, 0);
universe@517 627 EXPECT_EQ(cxListInsert(list, 0, &a), 0);
universe@517 628 EXPECT_EQ(list->size, 1);
universe@517 629 EXPECT_EQ(cxListInsert(list, 0, &b), 0);
universe@517 630 EXPECT_EQ(list->size, 2);
universe@517 631 EXPECT_EQ(cxListInsert(list, 1, &c), 0);
universe@517 632 EXPECT_EQ(list->size, 3);
universe@517 633 EXPECT_EQ(cxListInsert(list, 3, &d), 0);
universe@517 634
universe@517 635 EXPECT_EQ(list->size, 4);
universe@517 636 EXPECT_GE(list->capacity, list->size);
universe@517 637
universe@517 638 EXPECT_EQ(*(int *) cxListAt(list, 0), 47);
universe@517 639 EXPECT_EQ(*(int *) cxListAt(list, 1), 13);
universe@517 640 EXPECT_EQ(*(int *) cxListAt(list, 2), 5);
universe@517 641 EXPECT_EQ(*(int *) cxListAt(list, 3), 42);
universe@517 642 }
universe@517 643
universe@517 644 void verifyRemove(CxList *list) const {
universe@517 645 EXPECT_EQ(cxListRemove(list, 2), 0);
universe@517 646 EXPECT_EQ(cxListRemove(list, 4), 0);
universe@517 647 EXPECT_EQ(list->size, testdata_len - 2);
universe@517 648 EXPECT_GE(list->capacity, list->size);
universe@517 649 EXPECT_EQ(*(int *) cxListAt(list, 0), testdata.data[0]);
universe@517 650 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[1]);
universe@517 651 EXPECT_EQ(*(int *) cxListAt(list, 2), testdata.data[3]);
universe@517 652 EXPECT_EQ(*(int *) cxListAt(list, 3), testdata.data[4]);
universe@517 653 EXPECT_EQ(*(int *) cxListAt(list, 4), testdata.data[6]);
universe@517 654
universe@517 655 EXPECT_EQ(cxListRemove(list, 0), 0);
universe@517 656 EXPECT_EQ(list->size, testdata_len - 3);
universe@517 657 EXPECT_GE(list->capacity, list->size);
universe@517 658 EXPECT_EQ(*(int *) cxListAt(list, 0), testdata.data[1]);
universe@517 659 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[3]);
universe@517 660
universe@517 661 EXPECT_NE(cxListRemove(list, testdata_len), 0);
universe@517 662 }
universe@517 663
universe@517 664 void verifyAt(CxList *list) const {
universe@517 665 auto len = testdata_len;
universe@517 666 EXPECT_EQ(list->size, len);
universe@521 667 cx_for_n (i, len) {
universe@521 668 EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i]);
universe@521 669 }
universe@517 670 EXPECT_EQ(cxListAt(list, list->size), nullptr);
universe@517 671 }
universe@517 672
universe@517 673 void verifyFind(CxList *list) const {
universe@517 674 cx_for_n (attempt, 25) {
universe@517 675 size_t exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
universe@517 676 int val = testdata.data[exp];
universe@517 677 // randomly picked number could occur earlier in list - find first position
universe@517 678 cx_for_n (i, exp) {
universe@517 679 if (testdata.data[i] == val) {
universe@517 680 exp = i;
universe@517 681 break;
universe@517 682 }
universe@517 683 }
universe@517 684 EXPECT_EQ(cxListFind(list, &val), exp);
universe@517 685 }
universe@517 686 }
universe@517 687
universe@517 688 void verifySort(CxList *list) const {
universe@517 689 std::array<int, testdata_len> expected{};
universe@517 690 std::partial_sort_copy(testdata.data.begin(), testdata.data.end(), expected.begin(), expected.end());
universe@517 691 cxListSort(list);
universe@517 692 cx_for_n (i, testdata_len) ASSERT_EQ(*(int *) cxListAt(list, i), expected[i]);
universe@517 693 }
universe@517 694
universe@517 695 void verifyIterator(CxList *list) const {
universe@517 696 int i = 0;
universe@517 697 CxIterator iter = cxListBegin(list);
universe@517 698 cx_foreach(int*, x, iter) {
universe@517 699 ASSERT_EQ(iter.index, (size_t) (i + 1) / 2);
universe@517 700 ASSERT_EQ(*x, testdata.data[i]);
universe@517 701 if (i % 2 == 1) iter.remove = true;
universe@517 702 i++;
universe@517 703 }
universe@517 704 auto len = testdata_len;
universe@517 705 EXPECT_EQ(i, len);
universe@517 706 ASSERT_EQ(list->size, len / 2);
universe@517 707 cx_for_n(j, len / 2) ASSERT_EQ(*(int *) cxListAt(list, j), testdata.data[j * 2]);
universe@517 708 }
universe@517 709
universe@517 710 static void verifyInsertViaIterator(CxList *list) {
universe@517 711 int newdata[] = {10, 20, 30, 40, 50};
universe@517 712
universe@517 713 CxIterator iter = cxListIterator(list, 2);
universe@517 714 EXPECT_TRUE(cxIteratorValid(&iter));
universe@517 715 EXPECT_EQ(iter.index, 2);
universe@517 716 EXPECT_EQ(*(int *) cxIteratorCurrent(&iter), 2);
universe@517 717 cxListInsertAfter(&iter, &newdata[0]);
universe@517 718 EXPECT_TRUE(cxIteratorValid(&iter));
universe@517 719 EXPECT_EQ(iter.index, 2);
universe@517 720 EXPECT_EQ(*(int *) cxIteratorCurrent(&iter), 2);
universe@517 721 cxListInsertBefore(&iter, &newdata[1]);
universe@517 722 EXPECT_TRUE(cxIteratorValid(&iter));
universe@517 723 EXPECT_EQ(iter.index, 3);
universe@517 724 EXPECT_EQ(*(int *) cxIteratorCurrent(&iter), 2);
universe@517 725
universe@517 726 iter = cxListBegin(list);
universe@517 727 cxListInsertBefore(&iter, &newdata[2]);
universe@517 728 EXPECT_TRUE(cxIteratorValid(&iter));
universe@517 729 EXPECT_EQ(iter.index, 1);
universe@517 730 EXPECT_EQ(*(int *) cxIteratorCurrent(&iter), 0);
universe@517 731 iter = cxListIterator(list, list->size);
universe@517 732 cxListInsertBefore(&iter, &newdata[3]);
universe@517 733 EXPECT_FALSE(cxIteratorValid(&iter));
universe@517 734 EXPECT_EQ(iter.index, 9);
universe@517 735 iter = cxListIterator(list, list->size);
universe@517 736 cxListInsertAfter(&iter, &newdata[4]);
universe@517 737 EXPECT_FALSE(cxIteratorValid(&iter));
universe@517 738 EXPECT_EQ(iter.index, 10);
universe@517 739
universe@517 740 int expdata[] = {30, 0, 1, 20, 2, 10, 3, 4, 40, 50};
universe@517 741 cx_for_n (j, 10) EXPECT_EQ(*(int *) cxListAt(list, j), expdata[j]);
universe@517 742 }
universe@521 743
universe@521 744 void verifyReverse(CxList *list) const {
universe@521 745 cxListReverse(list);
universe@521 746 cx_for_n(i, testdata_len) {
universe@521 747 ASSERT_EQ(*(int *) cxListAt(list, i), testdata.data[testdata_len - 1 - i]);
universe@521 748 }
universe@521 749 }
universe@521 750
universe@528 751 static void verifyCompare(
universe@528 752 CxList *left,
universe@528 753 CxList *right
universe@528 754 ) {
universe@521 755 EXPECT_EQ(cxListCompare(left, right), 0);
universe@521 756 int x = 42;
universe@521 757 cxListAdd(left, &x);
universe@521 758 ASSERT_GT(left->size, right->size);
universe@521 759 EXPECT_GT(cxListCompare(left, right), 0);
universe@521 760 EXPECT_LT(cxListCompare(right, left), 0);
universe@521 761 cxListAdd(right, &x);
universe@521 762 ASSERT_EQ(left->size, right->size);
universe@521 763 EXPECT_EQ(cxListCompare(left, right), 0);
universe@521 764 int a = 5, b = 10;
universe@521 765 cxListInsert(left, 15, &a);
universe@521 766 cxListInsert(right, 15, &b);
universe@521 767 ASSERT_EQ(left->size, right->size);
universe@521 768 EXPECT_LT(cxListCompare(left, right), 0);
universe@521 769 EXPECT_GT(cxListCompare(right, left), 0);
universe@528 770 *(int *) cxListAt(left, 15) = 10;
universe@521 771 EXPECT_EQ(cxListCompare(left, right), 0);
universe@521 772 }
universe@517 773 };
universe@517 774
universe@517 775 class LinkedList : public HighLevelTest {
universe@517 776 };
universe@517 777
universe@517 778 class PointerLinkedList : public HighLevelTest {
universe@517 779 };
universe@517 780
universe@517 781 TEST_F(LinkedList, cxLinkedListCreate) {
universe@518 782 CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
universe@517 783 EXPECT_EQ(list->itemsize, sizeof(int));
universe@517 784 verifyCreate(list);
universe@506 785 }
universe@506 786
universe@517 787 TEST_F(PointerLinkedList, cxPointerLinkedListCreate) {
universe@518 788 CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
universe@517 789 EXPECT_EQ(list->itemsize, sizeof(void *));
universe@517 790 verifyCreate(list);
universe@455 791 }
universe@455 792
universe@517 793 TEST_F(LinkedList, cxLinkedListFromArray) {
universe@518 794 CxList *expected = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
universe@517 795 cx_for_n (i, testdata_len) cxListAdd(expected, &testdata.data[i]);
universe@518 796 CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cmp_int, sizeof(int),
universe@517 797 testdata_len, testdata.data.data()));
universe@517 798 EXPECT_EQ(cxListCompare(list, expected), 0);
universe@498 799 }
universe@498 800
universe@517 801 TEST_F(LinkedList, cxListAdd) {
universe@518 802 CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int)));
universe@517 803 verifyAdd(list, false);
universe@488 804 }
universe@488 805
universe@517 806 TEST_F(PointerLinkedList, cxListAdd) {
universe@518 807 CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
universe@517 808 verifyAdd(list, true);
universe@507 809 }
universe@507 810
universe@517 811 TEST_F(LinkedList, cxListInsert) {
universe@518 812 verifyInsert(autofree(cxLinkedListCreate(&testingAllocator, cmp_int, sizeof(int))));
universe@459 813 }
universe@459 814
universe@517 815 TEST_F(PointerLinkedList, cxListInsert) {
universe@518 816 verifyInsert(autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int)));
universe@498 817 }
universe@498 818
universe@517 819 TEST_F(LinkedList, cxListRemove) {
universe@517 820 verifyRemove(linkedListFromTestData());
universe@498 821 }
universe@498 822
universe@517 823 TEST_F(PointerLinkedList, cxListRemove) {
universe@517 824 verifyRemove(pointerLinkedListFromTestData());
universe@509 825 }
universe@459 826
universe@517 827 TEST_F(LinkedList, cxListAt) {
universe@517 828 verifyAt(linkedListFromTestData());
universe@509 829 }
universe@509 830
universe@517 831 TEST_F(PointerLinkedList, cxListAt) {
universe@517 832 verifyAt(pointerLinkedListFromTestData());
universe@459 833 }
universe@459 834
universe@517 835 TEST_F(LinkedList, cxListFind) {
universe@517 836 verifyFind(linkedListFromTestData());
universe@509 837 }
universe@509 838
universe@517 839 TEST_F(PointerLinkedList, cxListFind) {
universe@517 840 verifyFind(pointerLinkedListFromTestData());
universe@509 841 }
universe@498 842
universe@517 843 TEST_F(LinkedList, cxListSort) {
universe@517 844 verifySort(linkedListFromTestData());
universe@498 845 }
universe@498 846
universe@517 847 TEST_F(PointerLinkedList, cxListSort) {
universe@517 848 verifySort(pointerLinkedListFromTestData());
universe@479 849 }
universe@479 850
universe@517 851 TEST_F(LinkedList, Iterator) {
universe@517 852 verifyIterator(linkedListFromTestData());
universe@509 853 }
universe@498 854
universe@517 855 TEST_F(PointerLinkedList, Iterator) {
universe@517 856 verifyIterator(pointerLinkedListFromTestData());
universe@498 857 }
universe@498 858
universe@517 859 TEST_F(LinkedList, InsertViaIterator) {
universe@517 860 int fivenums[] = {0, 1, 2, 3, 4, 5};
universe@518 861 CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cmp_int, sizeof(int), 5, fivenums));
universe@517 862 verifyInsertViaIterator(list);
universe@459 863 }
universe@459 864
universe@517 865 TEST_F(PointerLinkedList, InsertViaIterator) {
universe@517 866 int fivenums[] = {0, 1, 2, 3, 4, 5};
universe@518 867 CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cmp_int));
universe@517 868 cx_for_n (i, 5) cxListAdd(list, &fivenums[i]);
universe@517 869 verifyInsertViaIterator(list);
universe@509 870 }
universe@521 871
universe@521 872 TEST_F(LinkedList, cxListReverse) {
universe@521 873 verifyReverse(linkedListFromTestData());
universe@521 874 }
universe@521 875
universe@521 876 TEST_F(PointerLinkedList, cxListReverse) {
universe@521 877 verifyReverse(pointerLinkedListFromTestData());
universe@521 878 }
universe@521 879
universe@521 880 TEST_F(LinkedList, cxListCompare) {
universe@521 881 auto left = linkedListFromTestData();
universe@521 882 auto right = linkedListFromTestData();
universe@521 883 verifyCompare(left, right);
universe@521 884 }
universe@521 885
universe@552 886 TEST_F(LinkedList, cxListCompareWithPtrList) {
universe@552 887 auto left = linkedListFromTestData();
universe@552 888 auto right = pointerLinkedListFromTestData();
universe@552 889 verifyCompare(left, right);
universe@552 890 }
universe@552 891
universe@521 892 TEST_F(PointerLinkedList, cxListCompare) {
universe@521 893 auto left = pointerLinkedListFromTestData();
universe@521 894 auto right = pointerLinkedListFromTestData();
universe@521 895 verifyCompare(left, right);
universe@521 896 }
universe@521 897
universe@552 898 TEST_F(PointerLinkedList, cxListCompareWithNormalList) {
universe@552 899 auto left = pointerLinkedListFromTestData();
universe@552 900 auto right = linkedListFromTestData();
universe@552 901 verifyCompare(left, right);
universe@552 902 }
universe@552 903
universe@528 904 TEST_F(PointerLinkedList, NoDestructor) {
universe@528 905 void *item = cxMalloc(&testingAllocator, sizeof(int));
universe@528 906 auto list = cxPointerLinkedListCreate(cxDefaultAllocator, cmp_int);
universe@528 907 cxListAdd(list, item);
universe@528 908 ASSERT_FALSE(testingAllocator.verify());
universe@528 909 cxListDestroy(list);
universe@528 910 EXPECT_FALSE(testingAllocator.verify());
universe@528 911 cxFree(&testingAllocator, item);
universe@528 912 EXPECT_TRUE(testingAllocator.verify());
universe@528 913 }
universe@528 914
universe@528 915 TEST_F(PointerLinkedList, SimpleDestructor) {
universe@528 916 int item = 0;
universe@528 917 auto list = cxPointerLinkedListCreate(cxDefaultAllocator, cmp_int);
universe@528 918 list->content_destructor_type = CX_DESTRUCTOR_SIMPLE;
universe@528 919 list->simple_destructor = [](void *elem) { *(int *) elem = 42; };
universe@528 920 cxListAdd(list, &item);
universe@528 921 cxListDestroy(list);
universe@528 922 EXPECT_EQ(item, 42);
universe@528 923 }
universe@528 924
universe@528 925 TEST_F(PointerLinkedList, AdvancedDestructor) {
universe@528 926 void *item = cxMalloc(&testingAllocator, sizeof(int));
universe@528 927 auto list = cxPointerLinkedListCreate(cxDefaultAllocator, cmp_int);
universe@528 928 list->content_destructor_type = CX_DESTRUCTOR_ADVANCED;
universe@528 929 list->advanced_destructor.data = &testingAllocator;
universe@528 930 list->advanced_destructor.func = (cx_destructor_func2) cxFree;
universe@528 931 cxListAdd(list, item);
universe@528 932 ASSERT_FALSE(testingAllocator.verify());
universe@528 933 cxListDestroy(list);
universe@528 934 EXPECT_TRUE(testingAllocator.verify());
universe@528 935 }

mercurial