tests/test_list.c

Sun, 18 Feb 2024 21:12:28 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 18 Feb 2024 21:12:28 +0100
changeset 834
04c53b3c8378
parent 832
97df2e4c68fb
permissions
-rw-r--r--

capitalize cx_array_declare()

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    29 #include "cx/test.h"
    30 #include "util_allocator.h"
    31 #include "cx/compare.h"
    32 #include "cx/utils.h"
    34 #include "cx/array_list.h"
    35 #include "cx/linked_list.h"
    37 #include <stdarg.h>
    39 CX_TEST(test_array_add) {
    40     int stackspace[5] = {1,1,2,3,5};
    41     int *stackarray = stackspace;
    42     size_t stackarray_size = 3;
    43     size_t stackarray_capacity = 5;
    44     CX_ARRAY_DECLARE(int, heaparray);
    45     heaparray = calloc(5, sizeof(int));
    46     heaparray[0] = 2;
    47     heaparray[1] = 3;
    48     heaparray[2] = 5;
    49     heaparray[3] = 7;
    50     heaparray[4] = 11;
    51     heaparray_size = 3;
    52     heaparray_capacity = 5;
    53     int elem = 8, elem2 = 47;
    54     enum cx_array_result result;
    55     CX_TEST_DO {
    56         result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem, NULL);
    57         CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
    58         CX_TEST_ASSERT(stackarray[0] == 1);
    59         CX_TEST_ASSERT(stackarray[1] == 1);
    60         CX_TEST_ASSERT(stackarray[2] == 2);
    61         CX_TEST_ASSERT(stackarray[3] == 8);
    62         CX_TEST_ASSERT(stackarray[4] == 5);
    63         CX_TEST_ASSERT(stackarray_size == 4);
    64         CX_TEST_ASSERT(stackarray_capacity == 5);
    66         stackarray_size = 5;
    67         result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem2, NULL);
    68         CX_TEST_ASSERT(result == CX_ARRAY_REALLOC_NOT_SUPPORTED);
    69         CX_TEST_ASSERT(stackarray[0] == 1);
    70         CX_TEST_ASSERT(stackarray[1] == 1);
    71         CX_TEST_ASSERT(stackarray[2] == 2);
    72         CX_TEST_ASSERT(stackarray[3] == 8);
    73         CX_TEST_ASSERT(stackarray[4] == 5);
    74         CX_TEST_ASSERT(stackarray_size == 5);
    75         CX_TEST_ASSERT(stackarray_capacity == 5);
    77         result = cx_array_simple_add(heaparray, elem);
    78         CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
    79         CX_TEST_ASSERT(heaparray[0] == 2);
    80         CX_TEST_ASSERT(heaparray[1] == 3);
    81         CX_TEST_ASSERT(heaparray[2] == 5);
    82         CX_TEST_ASSERT(heaparray[3] == 8);
    83         CX_TEST_ASSERT(heaparray[4] == 11);
    84         CX_TEST_ASSERT(heaparray_size == 4);
    85         CX_TEST_ASSERT(heaparray_capacity == 5);
    87         heaparray_size = 5;
    88         result = cx_array_simple_add(heaparray, elem2);
    89         CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
    90         CX_TEST_ASSERT(heaparray[0] == 2);
    91         CX_TEST_ASSERT(heaparray[1] == 3);
    92         CX_TEST_ASSERT(heaparray[2] == 5);
    93         CX_TEST_ASSERT(heaparray[3] == 8);
    94         CX_TEST_ASSERT(heaparray[4] == 11);
    95         CX_TEST_ASSERT(heaparray[5] == 47);
    96         CX_TEST_ASSERT(heaparray_size == 6);
    97         CX_TEST_ASSERT(heaparray_capacity >= 6);
    98     }
    99     free(heaparray);
   100 }
   102 typedef struct node {
   103     struct node *next;
   104     struct node *prev;
   105     int data;
   106 } node;
   108 const ptrdiff_t loc_prev = offsetof(struct node, prev);
   109 const ptrdiff_t loc_next = offsetof(struct node, next);
   110 const ptrdiff_t loc_data = offsetof(struct node, data);
   112 static node *create_nodes_test_data(size_t len) {
   113     node *begin = calloc(1, sizeof(node));
   114     void *prev = begin;
   115     for (size_t i = 1; i < len; i++) {
   116         node *n = calloc(1, sizeof(node));
   117         cx_linked_list_link(prev, n, loc_prev, loc_next);
   118         prev = n;
   119     }
   120     return begin;
   121 }
   123 void assign_nodes_test_data(node *n, ...) {
   124     va_list ap;
   125     va_start(ap, n);
   126     while (n != NULL) {
   127         n->data = va_arg(ap, int);
   128         n = n->next;
   129     }
   130     va_end(ap);
   131 }
   133 static void destroy_nodes_test_data(node *n) {
   134     while (n != NULL) {
   135         void *next = n->next;
   136         free(n);
   137         n = next;
   138     }
   139 }
   141 static int *int_test_data(size_t len) {
   142     int *data = malloc(len*sizeof(int));
   143     for (size_t i = 0 ; i < len ; i++) {
   144         data[i] = rand(); // NOLINT(*-msc50-cpp)
   145     }
   146     return data;
   147 }
   149 CX_TEST(test_linked_list_link_unlink) {
   150     node a = {0}, b = {0}, c = {0};
   152     CX_TEST_DO {
   153         cx_linked_list_link(&a, &b, loc_prev, loc_next);
   154         CX_TEST_ASSERT(a.prev == NULL);
   155         CX_TEST_ASSERT(a.next == &b);
   156         CX_TEST_ASSERT(b.prev == &a);
   157         CX_TEST_ASSERT(b.next == NULL);
   159         cx_linked_list_unlink(&a, &b, loc_prev, loc_next);
   160         CX_TEST_ASSERT(a.prev == NULL);
   161         CX_TEST_ASSERT(a.next == NULL);
   162         CX_TEST_ASSERT(b.prev == NULL);
   163         CX_TEST_ASSERT(b.next == NULL);
   165         cx_linked_list_link(&b, &c, loc_prev, loc_next);
   166         cx_linked_list_link(&a, &b, loc_prev, loc_next);
   167         cx_linked_list_unlink(&b, &c, loc_prev, loc_next);
   168         CX_TEST_ASSERT(a.prev == NULL);
   169         CX_TEST_ASSERT(a.next == &b);
   170         CX_TEST_ASSERT(b.prev == &a);
   171         CX_TEST_ASSERT(b.next == NULL);
   172         CX_TEST_ASSERT(c.prev == NULL);
   173         CX_TEST_ASSERT(c.next == NULL);
   174     }
   175 }
   177 CX_TEST(test_linked_list_at) {
   178     node a = {0}, b = {0}, c = {0}, d = {0};
   180     cx_linked_list_link(&a, &b, loc_prev, loc_next);
   181     cx_linked_list_link(&b, &c, loc_prev, loc_next);
   182     cx_linked_list_link(&c, &d, loc_prev, loc_next);
   184     CX_TEST_DO {
   185         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 0) == &a);
   186         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 1) == &b);
   187         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 2) == &c);
   188         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 3) == &d);
   189         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 4) == NULL);
   190         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_prev, 0) == &a);
   191         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 1) == &b);
   192         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 2) == &c);
   193         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 3) == &d);
   194         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 4) == NULL);
   195         CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 0) == &a);
   196         CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 1) == &b);
   197     }
   198 }
   200 CX_TEST(test_linked_list_find) {
   201     void *list = create_nodes_test_data(4);
   202     assign_nodes_test_data(list, 2, 4, 6, 8);
   203     CX_TEST_DO {
   204         int s;
   205         s = 2;
   206         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 0);
   207         s = 4;
   208         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 1);
   209         s = 6;
   210         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 2);
   211         s = 8;
   212         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 3);
   213         s = 10;
   214         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
   215         s = -2;
   216         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
   217     }
   218     destroy_nodes_test_data(list);
   219 }
   221 CX_TEST(test_linked_list_compare) {
   222     void *la = create_nodes_test_data(4);
   223     void *lb = create_nodes_test_data(3);
   224     void *lc = create_nodes_test_data(4);
   225     assign_nodes_test_data(la, 2, 4, 6, 8);
   226     assign_nodes_test_data(lb, 2, 4, 6);
   227     assign_nodes_test_data(lc, 2, 4, 6, 9);
   228     CX_TEST_DO {
   229         CX_TEST_ASSERT(cx_linked_list_compare(la, lb, loc_next, loc_data, cx_cmp_int) > 0);
   230         CX_TEST_ASSERT(cx_linked_list_compare(lb, la, loc_next, loc_data, cx_cmp_int) < 0);
   231         CX_TEST_ASSERT(cx_linked_list_compare(lc, la, loc_next, loc_data, cx_cmp_int) > 0);
   232         CX_TEST_ASSERT(cx_linked_list_compare(la, lc, loc_next, loc_data, cx_cmp_int) < 0);
   233         CX_TEST_ASSERT(cx_linked_list_compare(la, la, loc_next, loc_data, cx_cmp_int) == 0);
   234     }
   235     destroy_nodes_test_data(la);
   236     destroy_nodes_test_data(lb);
   237     destroy_nodes_test_data(lc);
   238 }
   240 CX_TEST(test_linked_list_add) {
   241     node nodes[4];
   242     void *begin, *end;
   243     CX_TEST_DO {
   244         // test with begin, end / prev, next
   245         memset(nodes, 0, sizeof(node)*4);
   246         end = begin = NULL;
   248         cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]);
   249         CX_TEST_ASSERT(begin == &nodes[0]);
   250         CX_TEST_ASSERT(end == &nodes[0]);
   251         CX_TEST_ASSERT(nodes[0].prev == NULL);
   252         CX_TEST_ASSERT(nodes[0].next == NULL);
   254         cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]);
   255         CX_TEST_ASSERT(begin == &nodes[0]);
   256         CX_TEST_ASSERT(end == &nodes[1]);
   257         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   258         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   260         // test with begin only / prev, next
   261         memset(nodes, 0, sizeof(node)*4);
   262         end = begin = NULL;
   264         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]);
   265         CX_TEST_ASSERT(begin == &nodes[0]);
   266         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]);
   267         CX_TEST_ASSERT(begin == &nodes[0]);
   268         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   269         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   271         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]);
   272         CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
   273         CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
   275         // test with end only / prev, next
   276         memset(nodes, 0, sizeof(node)*4);
   277         end = begin = NULL;
   279         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]);
   280         CX_TEST_ASSERT(end == &nodes[0]);
   281         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]);
   282         CX_TEST_ASSERT(end == &nodes[1]);
   283         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   284         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   286         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]);
   287         CX_TEST_ASSERT(end == &nodes[2]);
   288         CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
   289         CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
   291         // test with begin, end / next
   292         memset(nodes, 0, sizeof(node)*4);
   293         end = begin = NULL;
   295         cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]);
   296         CX_TEST_ASSERT(begin == &nodes[0]);
   297         CX_TEST_ASSERT(end == &nodes[0]);
   298         cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]);
   299         CX_TEST_ASSERT(end == &nodes[1]);
   300         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   301         CX_TEST_ASSERT(nodes[1].prev == NULL);
   302     }
   303 }
   305 CX_TEST(test_linked_list_prepend) {
   306     node nodes[4];
   307     void *begin, *end;
   308     CX_TEST_DO {
   309         // test with begin, end / prev, next
   310         memset(nodes, 0, sizeof(node) * 4);
   311         end = begin = NULL;
   313         cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]);
   314         CX_TEST_ASSERT(begin == &nodes[0]);
   315         CX_TEST_ASSERT(end == &nodes[0]);
   316         CX_TEST_ASSERT(nodes[0].prev == NULL);
   317         CX_TEST_ASSERT(nodes[0].next == NULL);
   319         cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]);
   320         CX_TEST_ASSERT(begin == &nodes[1]);
   321         CX_TEST_ASSERT(end == &nodes[0]);
   322         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   323         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   325         // test with begin only / prev, next
   326         memset(nodes, 0, sizeof(node) * 4);
   327         end = begin = NULL;
   329         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]);
   330         CX_TEST_ASSERT(begin == &nodes[0]);
   331         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]);
   332         CX_TEST_ASSERT(begin == &nodes[1]);
   333         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   334         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   336         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]);
   337         CX_TEST_ASSERT(begin == &nodes[2]);
   338         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   339         CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
   341         // test with end only / prev, next
   342         memset(nodes, 0, sizeof(node) * 4);
   343         end = begin = NULL;
   345         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]);
   346         CX_TEST_ASSERT(end == &nodes[0]);
   347         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]);
   348         CX_TEST_ASSERT(end == &nodes[0]);
   349         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   350         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   352         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]);
   353         CX_TEST_ASSERT(end == &nodes[0]);
   354         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   355         CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
   357         // test with begin, end / next
   358         memset(nodes, 0, sizeof(node) * 4);
   359         end = begin = NULL;
   361         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]);
   362         CX_TEST_ASSERT(begin == &nodes[0]);
   363         CX_TEST_ASSERT(end == &nodes[0]);
   364         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]);
   365         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]);
   366         CX_TEST_ASSERT(begin == &nodes[2]);
   367         CX_TEST_ASSERT(end == &nodes[0]);
   368         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   369         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   370         CX_TEST_ASSERT(nodes[1].prev == NULL);
   371         CX_TEST_ASSERT(nodes[0].prev == NULL);
   372     }
   373 }
   375 CX_TEST(test_linked_list_insert) {
   376     node nodes[4];
   377     void *begin, *end;
   378     CX_TEST_DO {
   379         // insert mid list
   380         memset(nodes, 0, sizeof(node) * 4);
   381         begin = &nodes[0];
   382         end = &nodes[2];
   384         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   385         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   387         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]);
   388         CX_TEST_ASSERT(begin == &nodes[0]);
   389         CX_TEST_ASSERT(end == &nodes[2]);
   390         CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
   391         CX_TEST_ASSERT(nodes[2].prev == &nodes[3]);
   392         CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
   393         CX_TEST_ASSERT(nodes[3].next == &nodes[2]);
   395         // insert end
   396         memset(nodes, 0, sizeof(node) * 4);
   397         begin = &nodes[0];
   398         end = &nodes[2];
   400         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   401         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   403         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]);
   404         CX_TEST_ASSERT(begin == &nodes[0]);
   405         CX_TEST_ASSERT(end == &nodes[3]);
   406         CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
   407         CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
   408         CX_TEST_ASSERT(nodes[3].next == NULL);
   410         // insert begin
   411         memset(nodes, 0, sizeof(node) * 4);
   412         begin = &nodes[0];
   413         end = &nodes[2];
   415         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   416         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   418         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]);
   419         CX_TEST_ASSERT(begin == &nodes[3]);
   420         CX_TEST_ASSERT(end == &nodes[2]);
   421         CX_TEST_ASSERT(nodes[0].prev == &nodes[3]);
   422         CX_TEST_ASSERT(nodes[3].prev == NULL);
   423         CX_TEST_ASSERT(nodes[3].next == &nodes[0]);
   424     }
   425 }
   427 CX_TEST(test_linked_list_insert_chain) {
   428     node nodes[5];
   429     void *begin, *end;
   430     CX_TEST_DO {
   431         // insert mid list
   432         memset(nodes, 0, sizeof(node) * 5);
   433         begin = &nodes[0]; end = &nodes[2];
   435         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   436         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   437         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   439         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL);
   440         CX_TEST_ASSERT(begin == &nodes[0]);
   441         CX_TEST_ASSERT(end == &nodes[2]);
   442         CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
   443         CX_TEST_ASSERT(nodes[2].prev == &nodes[4]);
   444         CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
   445         CX_TEST_ASSERT(nodes[4].next == &nodes[2]);
   447         // insert end
   448         memset(nodes, 0, sizeof(node) * 5);
   449         begin = &nodes[0]; end = &nodes[2];
   451         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   452         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   453         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   455         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL);
   456         CX_TEST_ASSERT(begin == &nodes[0]);
   457         CX_TEST_ASSERT(end == &nodes[4]);
   458         CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
   459         CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
   460         CX_TEST_ASSERT(nodes[4].next == NULL);
   462         // insert begin
   463         memset(nodes, 0, sizeof(node) * 5);
   464         begin = &nodes[0]; end = &nodes[2];
   466         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   467         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   468         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   470         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL);
   471         CX_TEST_ASSERT(begin == &nodes[3]);
   472         CX_TEST_ASSERT(end == &nodes[2]);
   473         CX_TEST_ASSERT(nodes[0].prev == &nodes[4]);
   474         CX_TEST_ASSERT(nodes[3].prev == NULL);
   475         CX_TEST_ASSERT(nodes[4].next == &nodes[0]);
   476     }
   477 }
   479 CX_TEST(test_linked_list_first) {
   480     node *testdata = create_nodes_test_data(3);
   481     void *begin = testdata;
   482     CX_TEST_DO {
   483         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata, loc_prev));
   484         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next, loc_prev));
   485         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next->next, loc_prev));
   486     }
   487     destroy_nodes_test_data(testdata);
   488 }
   490 CX_TEST(test_linked_list_last) {
   491     node *testdata = create_nodes_test_data(3);
   492     void *end = testdata->next->next;
   493     CX_TEST_DO {
   494         CX_TEST_ASSERT(end == cx_linked_list_last(testdata, loc_next));
   495         CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next, loc_next));
   496         CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next->next, loc_next));
   497     }
   498     destroy_nodes_test_data(testdata);
   499 }
   501 CX_TEST(test_linked_list_prev) {
   502     node *testdata = create_nodes_test_data(3);
   503     CX_TEST_DO {
   504         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata) == NULL);
   505         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next) == testdata);
   506         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next->next) == testdata->next);
   507     }
   508     destroy_nodes_test_data(testdata);
   509 }
   511 CX_TEST(test_linked_list_remove) {
   512     node *testdata = create_nodes_test_data(3);
   513     assign_nodes_test_data(testdata, 2, 4, 6);
   514     node *first = testdata;
   515     node *second = first->next;
   516     node *third = second->next;
   517     void *begin = testdata;
   518     void *end = third;
   520     CX_TEST_DO {
   521         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second);
   522         CX_TEST_ASSERT(begin == first);
   523         CX_TEST_ASSERT(end == third);
   524         CX_TEST_ASSERT(first->prev == NULL);
   525         CX_TEST_ASSERT(first->next == third);
   526         CX_TEST_ASSERT(third->prev == first);
   527         CX_TEST_ASSERT(third->next == NULL);
   529         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third);
   530         CX_TEST_ASSERT(begin == first);
   531         CX_TEST_ASSERT(end == first);
   532         CX_TEST_ASSERT(first->prev == NULL);
   533         CX_TEST_ASSERT(first->next == NULL);
   535         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first);
   536         CX_TEST_ASSERT(begin == NULL);
   537         CX_TEST_ASSERT(end == NULL);
   538     }
   539     // list is not intact anymore, we have to free nodes individually
   540     free(first);
   541     free(second);
   542     free(third);
   543 }
   545 CX_TEST(test_linked_list_size) {
   546     node *td5 = create_nodes_test_data(5);
   547     node *td13 = create_nodes_test_data(13);
   548     CX_TEST_DO {
   549         CX_TEST_ASSERT(cx_linked_list_size(NULL, loc_next) == 0);
   550         CX_TEST_ASSERT(cx_linked_list_size(td5, loc_next) == 5);
   551         CX_TEST_ASSERT(cx_linked_list_size(td13, loc_next) == 13);
   552     }
   553     destroy_nodes_test_data(td5);
   554     destroy_nodes_test_data(td13);
   555 }
   557 CX_TEST(test_linked_list_sort_empty) {
   558     void *begin = NULL;
   559     CX_TEST_DO {
   560         // cannot assert something, we can just test that it does not crash
   561         cx_linked_list_sort(&begin, NULL, loc_prev, loc_next, loc_data, cx_cmp_int);
   562         CX_TEST_ASSERT(true);
   563     }
   564 }
   566 CX_TEST(test_linked_list_sort) {
   567     const size_t len = 1500;
   568     int *testdata = int_test_data(len);
   569     void *scrambled = create_nodes_test_data(len);
   570     node *n = scrambled;
   571     for (size_t i = 0; i < len; i++) {
   572         n->data = testdata[i];
   573         n = n->next;
   574     }
   575     int *sorted = malloc(len*sizeof(int));
   576     memcpy(sorted, testdata, len*sizeof(int));
   577     qsort(sorted, len, sizeof(int), cx_cmp_int);
   579     void *begin = scrambled;
   580     void *end = cx_linked_list_last(begin, loc_next);
   582     CX_TEST_DO {
   583         cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, cx_cmp_int);
   584         node *check = begin;
   585         node *check_last = NULL;
   586         for (size_t i = 0; i < len; i++) {
   587             CX_TEST_ASSERT(check->data == sorted[i]);
   588             CX_TEST_ASSERT(check->prev == check_last);
   589             if (i < len - 1) {
   590                 CX_TEST_ASSERT(check->next != NULL);
   591             }
   592             check_last = check;
   593             check = check->next;
   594         }
   595         CX_TEST_ASSERT(check == NULL);
   596         CX_TEST_ASSERT(end == check_last);
   597     }
   598     destroy_nodes_test_data(begin);
   599     free(sorted);
   600     free(testdata);
   601 }
   603 CX_TEST(test_linked_list_reverse) {
   604     void *testdata = create_nodes_test_data(4);
   605     void *expected = create_nodes_test_data(4);
   606     assign_nodes_test_data(testdata, 2, 4, 6, 8);
   607     assign_nodes_test_data(expected, 8, 6, 4, 2);
   608     void *begin = testdata;
   609     CX_TEST_DO {
   610         void *end = cx_linked_list_last(begin, loc_next);
   611         void *orig_begin = begin, *orig_end = end;
   613         cx_linked_list_reverse(&begin, &end, loc_prev, loc_next);
   614         CX_TEST_ASSERT(end == orig_begin);
   615         CX_TEST_ASSERT(begin == orig_end);
   616         CX_TEST_ASSERT(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, cx_cmp_int));
   617     }
   618     destroy_nodes_test_data(begin);
   619     destroy_nodes_test_data(expected);
   620 }
   623 CX_TEST(test_empty_list_size) {
   624     CX_TEST_DO {
   625         CX_TEST_ASSERT(cxEmptyList->size == 0);
   626         CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0);
   627     }
   628 }
   630 CX_TEST(test_empty_list_iterator) {
   631     CxList *list = cxEmptyList;
   633     CxIterator it1 = cxListIterator(list);
   634     CxIterator it2 = cxListBackwardsIterator(list);
   635     CxMutIterator it3 = cxListMutIterator(list);
   636     CxMutIterator it4 = cxListMutBackwardsIterator(list);
   638     CX_TEST_DO {
   639         CX_TEST_ASSERT(!cxIteratorValid(it1));
   640         CX_TEST_ASSERT(!cxIteratorValid(it2));
   641         CX_TEST_ASSERT(!cxIteratorValid(it3));
   642         CX_TEST_ASSERT(!cxIteratorValid(it4));
   644         int c = 0;
   645         cx_foreach(void*, data, it1) c++;
   646         cx_foreach(void*, data, it2) c++;
   647         cx_foreach(void*, data, it3) c++;
   648         cx_foreach(void*, data, it4) c++;
   649         CX_TEST_ASSERT(c == 0);
   650     }
   651 }
   653 CX_TEST(test_empty_list_noops) {
   654     CX_TEST_DO {
   655         CxList copy = *cxEmptyList;
   656         cxListSort(cxEmptyList);
   657         cxListClear(cxEmptyList);
   658         cxListDestroy(cxEmptyList);
   659         CX_TEST_ASSERT(0 == memcmp(&copy, cxEmptyList, sizeof(CxList))); // NOLINT(*-suspicious-memory-comparison)
   660     }
   661 }
   663 CX_TEST(test_empty_list_at) {
   664     CX_TEST_DO {
   665         CX_TEST_ASSERT(cxListAt(cxEmptyList, 0) == NULL);
   666         CX_TEST_ASSERT(cxListAt(cxEmptyList, 1) == NULL);
   667     }
   668 }
   670 CX_TEST(test_empty_list_find) {
   671     int x = 42, y = 1337;
   672     CX_TEST_DO {
   673         CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) < 0);
   674         CX_TEST_ASSERT(cxListFind(cxEmptyList, &y) < 0);
   675     }
   676 }
   678 CX_TEST(test_empty_list_compare) {
   679     CxList *empty = cxEmptyList;
   680     CxList *ll = cxLinkedListCreateSimple(sizeof(int));
   681     CxList *al = cxArrayListCreateSimple(sizeof(int), 8);
   682     int x = 5;
   683     CX_TEST_DO {
   684         CX_TEST_ASSERT(0 == cxListCompare(empty, cxEmptyList));
   685         CX_TEST_ASSERT(0 == cxListCompare(ll, cxEmptyList));
   686         CX_TEST_ASSERT(0 == cxListCompare(al, cxEmptyList));
   687         CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, ll));
   688         CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, al));
   690         cxListAdd(ll, &x);
   691         cxListAdd(al, &x);
   693         CX_TEST_ASSERT(0 < cxListCompare(ll, cxEmptyList));
   694         CX_TEST_ASSERT(0 < cxListCompare(al, cxEmptyList));
   695         CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, ll));
   696         CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, al));
   697     }
   698     cxListDestroy(ll);
   699     cxListDestroy(al);
   700 }
   702 CX_TEST(test_list_ll_create) {
   703     CxTestingAllocator talloc;
   704     cx_testing_allocator_init(&talloc);
   705     CxAllocator *alloc = &talloc.base;
   706     CX_TEST_DO {
   707         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int));
   708         CX_TEST_ASSERT(list != NULL);
   709         CX_TEST_ASSERT(list->item_size == sizeof(int));
   710         CX_TEST_ASSERT(list->simple_destructor == NULL);
   711         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   712         CX_TEST_ASSERT(list->destructor_data == NULL);
   713         CX_TEST_ASSERT(cxListSize(list) == 0);
   714         CX_TEST_ASSERT(list->allocator == alloc);
   715         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
   716         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   717         cxListDestroy(list);
   718         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   719     }
   720     cx_testing_allocator_destroy(&talloc);
   721 }
   723 CX_TEST(test_list_ll_create_simple) {
   724     CxList *list = cxLinkedListCreateSimple(sizeof(int));
   725     CX_TEST_DO {
   726         CX_TEST_ASSERT(list != NULL);
   727         CX_TEST_ASSERT(list->item_size == sizeof(int));
   728         CX_TEST_ASSERT(list->simple_destructor == NULL);
   729         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   730         CX_TEST_ASSERT(list->destructor_data == NULL);
   731         CX_TEST_ASSERT(cxListSize(list) == 0);
   732         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   733         CX_TEST_ASSERT(list->cmpfunc == NULL);
   734         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   735     }
   736     cxListDestroy(list);
   737 }
   739 CX_TEST(test_list_ll_store_pointers) {
   740     CxList *list = cxLinkedListCreateSimple(47);
   741     CX_TEST_DO {
   742         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   743         cxListStorePointers(list);
   744         CX_TEST_ASSERT(list->item_size == sizeof(void *));
   745         CX_TEST_ASSERT(list->cl != NULL);
   746         CX_TEST_ASSERT(list->climpl != NULL);
   747         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   748         cxListStoreObjects(list);
   749         CX_TEST_ASSERT(list->cl != NULL);
   750         CX_TEST_ASSERT(list->climpl == NULL);
   751         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   752     }
   753     cxListDestroy(list);
   754 }
   756 CX_TEST(test_list_ll_create_simple_for_pointers) {
   757     CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
   758     CX_TEST_DO {
   759         CX_TEST_ASSERT(list != NULL);
   760         CX_TEST_ASSERT(list->item_size == sizeof(void*));
   761         CX_TEST_ASSERT(list->simple_destructor == NULL);
   762         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   763         CX_TEST_ASSERT(list->destructor_data == NULL);
   764         CX_TEST_ASSERT(cxListSize(list) == 0);
   765         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   766         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
   767         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   768     }
   769     cxListDestroy(list);
   770 }
   772 CX_TEST(test_list_arl_create) {
   773     CxTestingAllocator talloc;
   774     cx_testing_allocator_init(&talloc);
   775     CxAllocator *alloc = &talloc.base;
   776     CX_TEST_DO {
   777         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8);
   778         CX_TEST_ASSERT(list != NULL);
   779         CX_TEST_ASSERT(list->item_size == sizeof(int));
   780         CX_TEST_ASSERT(list->simple_destructor == NULL);
   781         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   782         CX_TEST_ASSERT(list->destructor_data == NULL);
   783         CX_TEST_ASSERT(cxListSize(list) == 0);
   784         CX_TEST_ASSERT(list->allocator == alloc);
   785         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
   786         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   787         cxListDestroy(list);
   788         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   789     }
   790     cx_testing_allocator_destroy(&talloc);
   791 }
   793 CX_TEST(test_list_arl_create_simple) {
   794     CxList *list = cxArrayListCreateSimple(sizeof(int), 8);
   795     CX_TEST_DO {
   796         CX_TEST_ASSERT(list != NULL);
   797         CX_TEST_ASSERT(list->item_size == sizeof(int));
   798         CX_TEST_ASSERT(list->simple_destructor == NULL);
   799         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   800         CX_TEST_ASSERT(list->destructor_data == NULL);
   801         CX_TEST_ASSERT(cxListSize(list) == 0);
   802         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   803         CX_TEST_ASSERT(list->cmpfunc == NULL);
   804         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   805     }
   806     cxListDestroy(list);
   807 }
   809 CX_TEST(test_list_arl_create_simple_for_pointers) {
   810     CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8);
   811     CX_TEST_DO {
   812         CX_TEST_ASSERT(list != NULL);
   813         CX_TEST_ASSERT(list->item_size == sizeof(void*));
   814         CX_TEST_ASSERT(list->simple_destructor == NULL);
   815         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   816         CX_TEST_ASSERT(list->destructor_data == NULL);
   817         CX_TEST_ASSERT(cxListSize(list) == 0);
   818         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   819         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
   820         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   821     }
   822     cxListDestroy(list);
   823 }
   825 static void test_fake_simple_int_destr(void *elem) {
   826     *(int *) elem = 42;
   827 }
   829 CX_TEST(test_list_pll_destroy_no_destr) {
   830     CxTestingAllocator talloc;
   831     cx_testing_allocator_init(&talloc);
   832     CxAllocator *alloc = &talloc.base;
   833     CX_TEST_DO {
   834         void *item = cxMalloc(alloc, sizeof(int));
   835         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   836         cxListAdd(list, item);
   837         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   838         cxListDestroy(list);
   839         // item is not yet freed
   840         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   841         cxFree(alloc, item);
   842         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   843     }
   844     cx_testing_allocator_destroy(&talloc);
   845 }
   847 CX_TEST(test_list_pll_destroy_simple_destr) {
   848     CX_TEST_DO {
   849         int item = 0;
   850         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   851         list->simple_destructor = test_fake_simple_int_destr;
   852         cxListAdd(list, &item);
   853         cxListDestroy(list);
   854         CX_TEST_ASSERT(item == 42);
   855     }
   856 }
   858 CX_TEST(test_list_pll_destroy_adv_destr) {
   859     CxTestingAllocator talloc;
   860     cx_testing_allocator_init(&talloc);
   861     CxAllocator *alloc = &talloc.base;
   862     CX_TEST_DO {
   863         void *item = cxMalloc(alloc, sizeof(int));
   864         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   865         list->destructor_data = alloc;
   866         list->advanced_destructor = (cx_destructor_func2) cxFree;
   867         cxListAdd(list, item);
   868         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   869         cxListDestroy(list);
   870         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   871     }
   872     cx_testing_allocator_destroy(&talloc);
   873 }
   875 CX_TEST(test_list_parl_destroy_no_destr) {
   876     CxTestingAllocator talloc;
   877     cx_testing_allocator_init(&talloc);
   878     CxAllocator *alloc = &talloc.base;
   879     CX_TEST_DO {
   880         void *item = cxMalloc(alloc, sizeof(int));
   881         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   882         cxListAdd(list, item);
   883         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   884         cxListDestroy(list);
   885         // item is not yet freed
   886         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   887         cxFree(alloc, item);
   888         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   889     }
   890     cx_testing_allocator_destroy(&talloc);
   891 }
   893 CX_TEST(test_list_parl_destroy_simple_destr) {
   894     CX_TEST_DO {
   895         int item = 0;
   896         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   897         list->simple_destructor = test_fake_simple_int_destr;
   898         cxListAdd(list, &item);
   899         cxListDestroy(list);
   900         CX_TEST_ASSERT(item == 42);
   901     }
   902 }
   904 CX_TEST(test_list_parl_destroy_adv_destr) {
   905     CxTestingAllocator talloc;
   906     cx_testing_allocator_init(&talloc);
   907     CxAllocator *alloc = &talloc.base;
   908     CX_TEST_DO {
   909         void *item = cxMalloc(alloc, sizeof(int));
   910         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   911         list->destructor_data = alloc;
   912         list->advanced_destructor = (cx_destructor_func2) cxFree;
   913         cxListAdd(list, item);
   914         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   915         cxListDestroy(list);
   916         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   917     }
   918     cx_testing_allocator_destroy(&talloc);
   919 }
   921 #define set_up_combo \
   922     CxTestingAllocator talloc; \
   923     cx_testing_allocator_init(&talloc); \
   924     CxAllocator *alloc = &talloc.base; \
   925     CX_TEST_DO {
   926 #define tear_down_combo \
   927         cxListDestroy(list); \
   928         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));\
   929     } \
   930     cx_testing_allocator_destroy(&talloc);
   931 #define roll_out_test_combos(name, body) \
   932 static CX_TEST_SUBROUTINE(test_list_verify_##name, CxList *list, \
   933     __attribute__((__unused__)) bool isptrlist) body \
   934 CX_TEST(test_list_ll_##name) { \
   935     set_up_combo \
   936         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); \
   937         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
   938     tear_down_combo \
   939 } \
   940 CX_TEST(test_list_arl_##name) { \
   941     set_up_combo \
   942         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); \
   943         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
   944     tear_down_combo \
   945 } \
   946 CX_TEST(test_list_pll_##name) { \
   947     set_up_combo \
   948         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \
   949         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
   950     tear_down_combo \
   951 } \
   952 CX_TEST(test_list_parl_##name) { \
   953     set_up_combo \
   954         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS, 8); \
   955         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
   956     tear_down_combo \
   957 }
   958 #define array_init(...) {__VA_ARGS__}
   960 static inline int *int_test_data_added_to_list(CxList *list, bool isptrlist, size_t len) {
   961     int *testdata = int_test_data(len);
   962     if (isptrlist) {
   963         cx_for_n(i, len) {
   964             cxListAdd(list, &testdata[i]);
   965         }
   966     } else {
   967         cxListAddArray(list, testdata, len);
   968     }
   969     return testdata;
   970 }
   972 roll_out_test_combos(add, {
   973     const size_t len = 250;
   974     int *testdata = int_test_data(len);
   975     cx_for_n (i, len) CX_TEST_ASSERT(cxListAdd(list, &testdata[i]) == 0);
   976     CX_TEST_ASSERT(cxListSize(list) == len);
   977     cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
   978     cx_for_n (i, len) ++testdata[i];
   979     if (isptrlist) {
   980         cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
   981     } else {
   982         cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i] - 1);
   983     }
   984     free(testdata);
   985 })
   987 roll_out_test_combos(insert, {
   988     int a = 5;
   989     int b = 47;
   990     int c = 13;
   991     int d = 42;
   992     CX_TEST_ASSERT(cxListInsert(list, 1, &a) != 0);
   993     CX_TEST_ASSERT(cxListSize(list) == 0);
   994     CX_TEST_ASSERT(cxListInsert(list, 0, &a) == 0);
   995     CX_TEST_ASSERT(cxListSize(list) == 1);
   996     CX_TEST_ASSERT(cxListInsert(list, 0, &b) == 0);
   997     CX_TEST_ASSERT(cxListSize(list) == 2);
   998     CX_TEST_ASSERT(cxListInsert(list, 1, &c) == 0);
   999     CX_TEST_ASSERT(cxListSize(list) == 3);
  1000     CX_TEST_ASSERT(cxListInsert(list, 3, &d) == 0);
  1001     CX_TEST_ASSERT(cxListSize(list) == 4);
  1002     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 47);
  1003     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 13);
  1004     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 5);
  1005     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 42);
  1006 })
  1008 roll_out_test_combos(insert_array, {
  1009     int a[5] = array_init(5, 47, 11, 13, 42);
  1010     int b[5] = array_init(9, 18, 72, 50, 7);
  1011     int *aptr[5];
  1012     int *bptr[5];
  1013     cx_for_n(i, 5) {
  1014         aptr[i] = &a[i];
  1015         bptr[i] = &b[i];
  1018     size_t inserted;
  1020     if (isptrlist) {
  1021         inserted = cxListInsertArray(list, 0, aptr, 5);
  1022     } else {
  1023         inserted = cxListInsertArray(list, 0, a, 5);
  1025     CX_TEST_ASSERT(inserted == 5);
  1026     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
  1027     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
  1028     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
  1029     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 13);
  1030     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 42);
  1031     if (isptrlist) {
  1032         inserted = cxListInsertArray(list, 3, bptr, 5);
  1033     } else {
  1034         inserted = cxListInsertArray(list, 3, b, 5);
  1036     CX_TEST_ASSERT(inserted == 5);
  1037     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
  1038     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
  1039     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
  1040     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 9);
  1041     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 18);
  1042     CX_TEST_ASSERT(*(int *) cxListAt(list, 5) == 72);
  1043     CX_TEST_ASSERT(*(int *) cxListAt(list, 6) == 50);
  1044     CX_TEST_ASSERT(*(int *) cxListAt(list, 7) == 7);
  1045     CX_TEST_ASSERT(*(int *) cxListAt(list, 8) == 13);
  1046     CX_TEST_ASSERT(*(int *) cxListAt(list, 9) == 42);
  1047 })
  1049 roll_out_test_combos(remove, {
  1050     const size_t testdata_len = 32;
  1051     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1053     CX_TEST_ASSERT(cxListRemove(list, 2) == 0);
  1054     CX_TEST_ASSERT(cxListRemove(list, 4) == 0);
  1055     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 2);
  1056     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[0]);
  1057     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[1]);
  1058     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == testdata[3]);
  1059     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == testdata[4]);
  1060     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == testdata[6]);
  1061     CX_TEST_ASSERT(cxListRemove(list, 0) == 0);
  1062     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 3);
  1063     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[1]);
  1064     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[3]);
  1065     CX_TEST_ASSERT(cxListRemove(list, testdata_len) != 0);
  1066     free(testdata);
  1067 })
  1069 roll_out_test_combos(find_remove, {
  1070     const size_t testdata_len = 250;
  1071     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1073     int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
  1074     int val = testdata[exp];
  1075     // randomly picked number could occur earlier in list - find first position
  1076     for (int i = 0 ; i < exp ; i++) {
  1077         if (testdata[i] == val) {
  1078             exp = i;
  1079             break;
  1082     CX_TEST_ASSERT(cxListSize(list) == testdata_len);
  1083     CX_TEST_ASSERT(cxListFind(list, &val) == exp);
  1084     CX_TEST_ASSERT(cxListFindRemove(list, &val) == exp);
  1085     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
  1086     CX_TEST_ASSERT(cxListFind(list, &val) != exp);
  1088     int notinlist = -1;
  1089     CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) < 0);
  1090     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
  1092     free(testdata);
  1093 })
  1095 roll_out_test_combos(clear, {
  1096     int *testdata = int_test_data_added_to_list(list, isptrlist, 8);
  1097     CX_TEST_ASSERT(cxListSize(list) > 0);
  1098     cxListClear(list);
  1099     CX_TEST_ASSERT(cxListSize(list) == 0);
  1100     free(testdata);
  1101 })
  1103 roll_out_test_combos(at, {
  1104     size_t len = 128;
  1105     int *testdata = int_test_data_added_to_list(list, isptrlist, 128);
  1106     CX_TEST_ASSERT(cxListSize(list) == len);
  1107     cx_for_n (i, len) {
  1108         CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
  1110     CX_TEST_ASSERT(cxListAt(list, cxListSize(list)) == NULL);
  1111     free(testdata);
  1112 })
  1114 roll_out_test_combos(swap, {
  1115     int original[16] = array_init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  1116     int swapped[16] = array_init(8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13);
  1118     cx_for_n(i, 16) {
  1119         cxListAdd(list, &original[i]);
  1122     CX_TEST_ASSERT(0 == cxListSwap(list, 1, 4));
  1123     CX_TEST_ASSERT(0 == cxListSwap(list, 2, 14));
  1124     CX_TEST_ASSERT(0 == cxListSwap(list, 9, 6));
  1125     CX_TEST_ASSERT(0 == cxListSwap(list, 3, 3));
  1126     CX_TEST_ASSERT(0 == cxListSwap(list, 10, 11));
  1127     CX_TEST_ASSERT(0 == cxListSwap(list, 8, 0));
  1128     CX_TEST_ASSERT(0 == cxListSwap(list, 7, 12));
  1129     CX_TEST_ASSERT(0 == cxListSwap(list, 13, 15));
  1131     CX_TEST_ASSERT(0 != cxListSwap(list, 5, 16));
  1132     CX_TEST_ASSERT(0 != cxListSwap(list, 16, 6));
  1133     CX_TEST_ASSERT(0 != cxListSwap(list, 16, 17));
  1135     CxIterator iter = cxListIterator(list);
  1136     cx_foreach(int*, e, iter) {
  1137         CX_TEST_ASSERT(*e == swapped[iter.index]);
  1139     iter = cxListBackwardsIterator(list);
  1140     cx_foreach(int*, e, iter) {
  1141         CX_TEST_ASSERT(*e == swapped[iter.index]);
  1143 })
  1145 CX_TEST(test_list_ll_swap_no_sbo) {
  1146     set_up_combo
  1147         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, 2*cx_linked_list_swap_sbo_size);
  1148         CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
  1149     tear_down_combo
  1151 CX_TEST(test_list_arl_swap_no_sbo) {
  1152     set_up_combo
  1153         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, 2*cx_array_swap_sbo_size, 8);
  1154         CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
  1155     tear_down_combo
  1158 roll_out_test_combos(find, {
  1159     const size_t testdata_len = 500;
  1160     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1162     cx_for_n (attempt, 25) {
  1163         int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
  1164         int val = testdata[exp];
  1165         // randomly picked number could occur earlier in list - find first position
  1166         for (int i = 0 ; i < exp ; i++) {
  1167             if (testdata[i] == val) {
  1168                 exp = i;
  1169                 break;
  1172         CX_TEST_ASSERT(cxListFind(list, &val) == exp);
  1175     int notinlist = -1;
  1176     CX_TEST_ASSERT(cxListFind(list, &notinlist) < 0);
  1178     free(testdata);
  1179 })
  1181 roll_out_test_combos(sort, {
  1182     const size_t testdata_len = 250;
  1183     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1184     int *expected = malloc(testdata_len*sizeof(int));
  1185     memcpy(expected, testdata, testdata_len*sizeof(int));
  1186     qsort(expected, testdata_len, sizeof(int), cx_cmp_int);
  1188     cxListSort(list);
  1189     cx_for_n (i, testdata_len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]);
  1191     free(expected);
  1192     free(testdata);
  1193 })
  1195 roll_out_test_combos(reverse, {
  1196     const size_t testdata_len = 50;
  1197     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1198     cxListReverse(list);
  1199     cx_for_n(i, testdata_len) {
  1200         CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[testdata_len - 1 - i]);
  1202     free(testdata);
  1203 })
  1205 roll_out_test_combos(iterator, {
  1206     const size_t len = 50;
  1207     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1209     CxIterator iter = cxListIterator(list);
  1210     size_t i = 0;
  1211     cx_foreach(int*, x, iter) {
  1212         CX_TEST_ASSERT(i == iter.index);
  1213         CX_TEST_ASSERT(*x == testdata[iter.index]);
  1214         i++;
  1216     CX_TEST_ASSERT(i == cxListSize(list));
  1217     iter = cxListBackwardsIterator(list);
  1218     cx_foreach(int*, x, iter) {
  1219         CX_TEST_ASSERT(i - 1 == iter.index);
  1220         CX_TEST_ASSERT(*x == testdata[iter.index]);
  1221         i--;
  1223     CX_TEST_ASSERT(i == 0);
  1224     i = len / 2;
  1225     CxMutIterator mut_iter = cxListMutIteratorAt(list, i);
  1226     size_t j = 0;
  1227     cx_foreach(int*, x, mut_iter) {
  1228         CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2);
  1229         CX_TEST_ASSERT(*x == testdata[i]);
  1230         if (i % 2 == 1) cxIteratorFlagRemoval(mut_iter);
  1231         i++;
  1232         j++;
  1234     CX_TEST_ASSERT(i == len);
  1235     i = len / 2;
  1236     j = 0;
  1237     mut_iter = cxListMutBackwardsIteratorAt(list, i - 1);
  1238     cx_foreach(int*, x, mut_iter) {
  1239         CX_TEST_ASSERT(mut_iter.index == len / 2 - 1 - j);
  1240         CX_TEST_ASSERT(*x == testdata[i - 1]);
  1241         if (i % 2 == 0) cxIteratorFlagRemoval(mut_iter);
  1242         i--;
  1243         j++;
  1245     CX_TEST_ASSERT(i == 0);
  1246     CX_TEST_ASSERT(cxListSize(list) == len / 2);
  1247     cx_for_n(k, len / 2) CX_TEST_ASSERT(*(int *) cxListAt(list, k) == testdata[k * 2]);
  1249     free(testdata);
  1250 })
  1252 roll_out_test_combos(insert_with_iterator, {
  1253     int fivenums[] = array_init(0, 1, 2, 3, 4);
  1254     cx_for_n(i, 5) cxListAdd(list, &fivenums[i]);
  1255     int newdata[] = array_init(10, 20, 30, 40, 50);
  1257     CxMutIterator iter = cxListMutIteratorAt(list, 2);
  1258     CX_TEST_ASSERT(cxIteratorValid(iter));
  1259     CX_TEST_ASSERT(iter.index == 2);
  1260     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1261     cxListInsertAfter(&iter, &newdata[0]);
  1262     CX_TEST_ASSERT(cxIteratorValid(iter));
  1263     CX_TEST_ASSERT(iter.index == 2);
  1264     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1265     cxListInsertBefore(&iter, &newdata[1]);
  1266     CX_TEST_ASSERT(cxIteratorValid(iter));
  1267     CX_TEST_ASSERT(iter.index == 3);
  1268     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1270     iter = cxListMutIterator(list);
  1271     cxListInsertBefore(&iter, &newdata[2]);
  1272     CX_TEST_ASSERT(cxIteratorValid(iter));
  1273     CX_TEST_ASSERT(iter.index == 1);
  1274     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 0);
  1275     iter = cxListMutIteratorAt(list, cxListSize(list));
  1276     cxListInsertBefore(&iter, &newdata[3]);
  1277     CX_TEST_ASSERT(!cxIteratorValid(iter));
  1278     CX_TEST_ASSERT(iter.index == 9);
  1279     iter = cxListMutIteratorAt(list, cxListSize(list));
  1280     cxListInsertAfter(&iter, &newdata[4]);
  1281     CX_TEST_ASSERT(!cxIteratorValid(iter));
  1282     CX_TEST_ASSERT(iter.index == 10);
  1284     int expdata[] = array_init(30, 0, 1, 20, 2, 10, 3, 4, 40, 50);
  1285     cx_for_n (j, 10) CX_TEST_ASSERT(*(int *) cxListAt(list, j) == expdata[j]);
  1286 })
  1288 static CX_TEST_SUBROUTINE(test_list_verify_compare, CxList *left, CxList *right) {
  1289     CX_TEST_ASSERTM(cxListCompare(left, right) == 0, "lists don't start identical");
  1290     int x = 42;
  1291     cxListAdd(left, &x);
  1292     CX_TEST_ASSERT(cxListSize(left) > cxListSize(right));
  1293     CX_TEST_ASSERT(cxListCompare(left, right) > 0);
  1294     CX_TEST_ASSERT(cxListCompare(right, left) < 0);
  1295     cxListAdd(right, &x);
  1296     CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
  1297     CX_TEST_ASSERT(cxListCompare(left, right) == 0);
  1298     int a = 5, b = 10;
  1299     cxListInsert(left, 15, &a);
  1300     cxListInsert(right, 15, &b);
  1301     CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
  1302     CX_TEST_ASSERT(cxListCompare(left, right) < 0);
  1303     CX_TEST_ASSERT(cxListCompare(right, left) > 0);
  1304     *(int *) cxListAt(left, 15) = 10;
  1305     CX_TEST_ASSERT(cxListCompare(left, right) == 0);
  1308 #define roll_out_compare_tests(suffix, otherctr) \
  1309 roll_out_test_combos(compare_##suffix, { \
  1310     const size_t len = 47; \
  1311     int *testdata = int_test_data_added_to_list(list, isptrlist, len); \
  1312     CxList *other = otherctr; \
  1313     cx_for_n(i, len) cxListAdd(other, &testdata[i]); \
  1314     CX_TEST_CALL_SUBROUTINE(test_list_verify_compare, list, other); \
  1315     cxListDestroy(other); \
  1316     free(testdata); \
  1317 })
  1319 roll_out_compare_tests(
  1320         ll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int))
  1323 roll_out_compare_tests(
  1324         pll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS)
  1327 roll_out_compare_tests(
  1328         arl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 50)
  1331 roll_out_compare_tests(
  1332         parl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 50)
  1335 static unsigned destr_test_ctr;
  1336 static int destr_last_value;
  1338 static void simple_destr_test_fun(void *data) {
  1339     int *ptr = data;
  1340     destr_last_value = *ptr;
  1341     *ptr = destr_last_value + 1;
  1342     destr_test_ctr++;
  1345 static void advanced_destr_test_fun(__attribute__((__unused__)) void *u, void *data) {
  1346     simple_destr_test_fun(data);
  1349 static CX_TEST_SUBROUTINE(test_list_verify_destructor, CxList *list,
  1350                           int const *testdata, size_t testdata_len) {
  1351     destr_test_ctr = 0;
  1353     int off = cxListIsStoringPointers(list) ? 1 : 0;
  1355     cxListRemove(list, 15);
  1356     CX_TEST_ASSERT(1 == destr_test_ctr);
  1357     CX_TEST_ASSERT(testdata[15] == destr_last_value + off);
  1358     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1359     cxListRemove(list, 47);
  1360     CX_TEST_ASSERT(2 == destr_test_ctr);
  1361     CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
  1362     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1364     CxMutIterator iter = cxListMutIteratorAt(list, 7);
  1365     cxIteratorNext(iter);
  1366     CX_TEST_ASSERT(2 == destr_test_ctr);
  1367     CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
  1368     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1369     cxIteratorFlagRemoval(iter);
  1370     cxIteratorNext(iter);
  1371     CX_TEST_ASSERT(3 == destr_test_ctr);
  1372     CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
  1373     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1375     iter = cxListMutBackwardsIteratorAt(list, 5);
  1376     cxIteratorNext(iter);
  1377     CX_TEST_ASSERT(3 == destr_test_ctr);
  1378     CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
  1379     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1380     cxIteratorFlagRemoval(iter);
  1381     cxIteratorNext(iter);
  1382     CX_TEST_ASSERT(4 == destr_test_ctr);
  1383     CX_TEST_ASSERT(testdata[4] == destr_last_value + off);
  1384     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1386     cxListClear(list);
  1387     CX_TEST_ASSERT(testdata_len == destr_test_ctr);
  1388     CX_TEST_ASSERT(testdata[testdata_len - 1] == destr_last_value + off);
  1391 roll_out_test_combos(simple_destr, {
  1392     const size_t len = 60;
  1393     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1394     list->simple_destructor = simple_destr_test_fun;
  1395     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  1396     free(testdata);
  1397 })
  1399 roll_out_test_combos(advanced_destr, {
  1400     const size_t len = 75;
  1401     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1402     list->advanced_destructor = advanced_destr_test_fun;
  1403     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  1404     free(testdata);
  1405 })
  1407 CxTestSuite *cx_test_suite_array_list(void) {
  1408     CxTestSuite *suite = cx_test_suite_new("array_list");
  1410     cx_test_register(suite, test_array_add);
  1412     cx_test_register(suite, test_list_arl_create);
  1413     cx_test_register(suite, test_list_arl_create_simple);
  1414     cx_test_register(suite, test_list_arl_create_simple_for_pointers);
  1415     cx_test_register(suite, test_list_parl_destroy_no_destr);
  1416     cx_test_register(suite, test_list_parl_destroy_simple_destr);
  1417     cx_test_register(suite, test_list_parl_destroy_adv_destr);
  1419     cx_test_register(suite, test_list_arl_add);
  1420     cx_test_register(suite, test_list_parl_add);
  1421     cx_test_register(suite, test_list_arl_insert);
  1422     cx_test_register(suite, test_list_parl_insert);
  1423     cx_test_register(suite, test_list_arl_insert_array);
  1424     cx_test_register(suite, test_list_parl_insert_array);
  1425     cx_test_register(suite, test_list_arl_remove);
  1426     cx_test_register(suite, test_list_parl_remove);
  1427     cx_test_register(suite, test_list_arl_find_remove);
  1428     cx_test_register(suite, test_list_parl_find_remove);
  1429     cx_test_register(suite, test_list_arl_clear);
  1430     cx_test_register(suite, test_list_parl_clear);
  1431     cx_test_register(suite, test_list_arl_at);
  1432     cx_test_register(suite, test_list_parl_at);
  1433     cx_test_register(suite, test_list_arl_swap);
  1434     cx_test_register(suite, test_list_parl_swap);
  1435     cx_test_register(suite, test_list_arl_swap_no_sbo);
  1436     cx_test_register(suite, test_list_arl_find);
  1437     cx_test_register(suite, test_list_parl_find);
  1438     cx_test_register(suite, test_list_arl_sort);
  1439     cx_test_register(suite, test_list_parl_sort);
  1440     cx_test_register(suite, test_list_arl_reverse);
  1441     cx_test_register(suite, test_list_parl_reverse);
  1442     cx_test_register(suite, test_list_arl_iterator);
  1443     cx_test_register(suite, test_list_parl_iterator);
  1444     cx_test_register(suite, test_list_arl_insert_with_iterator);
  1445     cx_test_register(suite, test_list_parl_insert_with_iterator);
  1446     cx_test_register(suite, test_list_arl_compare_ll);
  1447     cx_test_register(suite, test_list_arl_compare_arl);
  1448     cx_test_register(suite, test_list_arl_compare_pll);
  1449     cx_test_register(suite, test_list_arl_compare_parl);
  1450     cx_test_register(suite, test_list_parl_compare_ll);
  1451     cx_test_register(suite, test_list_parl_compare_arl);
  1452     cx_test_register(suite, test_list_parl_compare_pll);
  1453     cx_test_register(suite, test_list_parl_compare_parl);
  1454     cx_test_register(suite, test_list_arl_simple_destr);
  1455     cx_test_register(suite, test_list_parl_simple_destr);
  1456     cx_test_register(suite, test_list_arl_advanced_destr);
  1457     cx_test_register(suite, test_list_parl_advanced_destr);
  1459     return suite;
  1462 CxTestSuite *cx_test_suite_linked_list(void) {
  1463     CxTestSuite *suite = cx_test_suite_new("linked_list");
  1465     cx_test_register(suite, test_linked_list_link_unlink);
  1466     cx_test_register(suite, test_linked_list_at);
  1467     cx_test_register(suite, test_linked_list_find);
  1468     cx_test_register(suite, test_linked_list_compare);
  1469     cx_test_register(suite, test_linked_list_add);
  1470     cx_test_register(suite, test_linked_list_prepend);
  1471     cx_test_register(suite, test_linked_list_insert);
  1472     cx_test_register(suite, test_linked_list_insert_chain);
  1473     cx_test_register(suite, test_linked_list_first);
  1474     cx_test_register(suite, test_linked_list_last);
  1475     cx_test_register(suite, test_linked_list_prev);
  1476     cx_test_register(suite, test_linked_list_remove);
  1477     cx_test_register(suite, test_linked_list_size);
  1478     cx_test_register(suite, test_linked_list_sort_empty);
  1479     cx_test_register(suite, test_linked_list_sort);
  1480     cx_test_register(suite, test_linked_list_reverse);
  1482     cx_test_register(suite, test_list_ll_create);
  1483     cx_test_register(suite, test_list_ll_create_simple);
  1484     cx_test_register(suite, test_list_ll_store_pointers);
  1485     cx_test_register(suite, test_list_ll_create_simple_for_pointers);
  1486     cx_test_register(suite, test_list_pll_destroy_no_destr);
  1487     cx_test_register(suite, test_list_pll_destroy_simple_destr);
  1488     cx_test_register(suite, test_list_pll_destroy_adv_destr);
  1490     cx_test_register(suite, test_list_ll_add);
  1491     cx_test_register(suite, test_list_pll_add);
  1492     cx_test_register(suite, test_list_ll_insert);
  1493     cx_test_register(suite, test_list_pll_insert);
  1494     cx_test_register(suite, test_list_ll_insert_array);
  1495     cx_test_register(suite, test_list_pll_insert_array);
  1496     cx_test_register(suite, test_list_ll_remove);
  1497     cx_test_register(suite, test_list_pll_remove);
  1498     cx_test_register(suite, test_list_ll_find_remove);
  1499     cx_test_register(suite, test_list_pll_find_remove);
  1500     cx_test_register(suite, test_list_ll_clear);
  1501     cx_test_register(suite, test_list_pll_clear);
  1502     cx_test_register(suite, test_list_ll_at);
  1503     cx_test_register(suite, test_list_pll_at);
  1504     cx_test_register(suite, test_list_ll_swap);
  1505     cx_test_register(suite, test_list_pll_swap);
  1506     cx_test_register(suite, test_list_ll_swap_no_sbo);
  1507     cx_test_register(suite, test_list_ll_find);
  1508     cx_test_register(suite, test_list_pll_find);
  1509     cx_test_register(suite, test_list_ll_sort);
  1510     cx_test_register(suite, test_list_pll_sort);
  1511     cx_test_register(suite, test_list_ll_reverse);
  1512     cx_test_register(suite, test_list_pll_reverse);
  1513     cx_test_register(suite, test_list_ll_iterator);
  1514     cx_test_register(suite, test_list_pll_iterator);
  1515     cx_test_register(suite, test_list_ll_insert_with_iterator);
  1516     cx_test_register(suite, test_list_pll_insert_with_iterator);
  1517     cx_test_register(suite, test_list_ll_compare_ll);
  1518     cx_test_register(suite, test_list_ll_compare_arl);
  1519     cx_test_register(suite, test_list_ll_compare_pll);
  1520     cx_test_register(suite, test_list_ll_compare_parl);
  1521     cx_test_register(suite, test_list_pll_compare_ll);
  1522     cx_test_register(suite, test_list_pll_compare_arl);
  1523     cx_test_register(suite, test_list_pll_compare_pll);
  1524     cx_test_register(suite, test_list_pll_compare_parl);
  1525     cx_test_register(suite, test_list_ll_simple_destr);
  1526     cx_test_register(suite, test_list_pll_simple_destr);
  1527     cx_test_register(suite, test_list_ll_advanced_destr);
  1528     cx_test_register(suite, test_list_pll_advanced_destr);
  1530     return suite;
  1533 CxTestSuite *cx_test_suite_empty_list(void) {
  1534     CxTestSuite *suite = cx_test_suite_new("empty list dummy");
  1536     cx_test_register(suite, test_empty_list_size);
  1537     cx_test_register(suite, test_empty_list_iterator);
  1538     cx_test_register(suite, test_empty_list_noops);
  1539     cx_test_register(suite, test_empty_list_at);
  1540     cx_test_register(suite, test_empty_list_find);
  1541     cx_test_register(suite, test_empty_list_compare);
  1543     return suite;

mercurial