tests/test_list.c

Thu, 25 Jan 2024 22:01:12 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 25 Jan 2024 22:01:12 +0100
changeset 818
2be8fe3d5a2d
parent 807
c8d692131b1e
child 819
5da2ead43077
permissions
-rw-r--r--

add cx_array_add() + fix type of cx_array_default_reallocator

     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     int *heaparray = calloc(5, sizeof(int));
    45     heaparray[0] = 2;
    46     heaparray[1] = 3;
    47     heaparray[2] = 5;
    48     heaparray[3] = 7;
    49     heaparray[4] = 11;
    50     size_t heaparray_size = 3;
    51     size_t heaparray_capacity = 5;
    52     int elem = 8, elem2 = 47;
    53     enum cx_array_copy_result result;
    54     CX_TEST_DO {
    55         result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem, NULL);
    56         CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS);
    57         CX_TEST_ASSERT(stackarray[0] == 1);
    58         CX_TEST_ASSERT(stackarray[1] == 1);
    59         CX_TEST_ASSERT(stackarray[2] == 2);
    60         CX_TEST_ASSERT(stackarray[3] == 8);
    61         CX_TEST_ASSERT(stackarray[4] == 5);
    62         CX_TEST_ASSERT(stackarray_size == 4);
    63         CX_TEST_ASSERT(stackarray_capacity == 5);
    65         stackarray_size = 5;
    66         result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem2, NULL);
    67         CX_TEST_ASSERT(result == CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED);
    68         CX_TEST_ASSERT(stackarray[0] == 1);
    69         CX_TEST_ASSERT(stackarray[1] == 1);
    70         CX_TEST_ASSERT(stackarray[2] == 2);
    71         CX_TEST_ASSERT(stackarray[3] == 8);
    72         CX_TEST_ASSERT(stackarray[4] == 5);
    73         CX_TEST_ASSERT(stackarray_size == 5);
    74         CX_TEST_ASSERT(stackarray_capacity == 5);
    76         result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem, cx_array_default_reallocator);
    77         CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS);
    78         CX_TEST_ASSERT(heaparray[0] == 2);
    79         CX_TEST_ASSERT(heaparray[1] == 3);
    80         CX_TEST_ASSERT(heaparray[2] == 5);
    81         CX_TEST_ASSERT(heaparray[3] == 8);
    82         CX_TEST_ASSERT(heaparray[4] == 11);
    83         CX_TEST_ASSERT(heaparray_size == 4);
    84         CX_TEST_ASSERT(heaparray_capacity == 5);
    86         heaparray_size = 5;
    87         result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem2, cx_array_default_reallocator);
    88         CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS);
    89         CX_TEST_ASSERT(heaparray[0] == 2);
    90         CX_TEST_ASSERT(heaparray[1] == 3);
    91         CX_TEST_ASSERT(heaparray[2] == 5);
    92         CX_TEST_ASSERT(heaparray[3] == 8);
    93         CX_TEST_ASSERT(heaparray[4] == 11);
    94         CX_TEST_ASSERT(heaparray[5] == 47);
    95         CX_TEST_ASSERT(heaparray_size == 6);
    96         CX_TEST_ASSERT(heaparray_capacity >= 6);
    97     }
    98     free(heaparray);
    99 }
   101 typedef struct node {
   102     struct node *next;
   103     struct node *prev;
   104     int data;
   105 } node;
   107 const ptrdiff_t loc_prev = offsetof(struct node, prev);
   108 const ptrdiff_t loc_next = offsetof(struct node, next);
   109 const ptrdiff_t loc_data = offsetof(struct node, data);
   111 static node *create_nodes_test_data(size_t len) {
   112     node *begin = calloc(1, sizeof(node));
   113     void *prev = begin;
   114     for (size_t i = 1; i < len; i++) {
   115         node *n = calloc(1, sizeof(node));
   116         cx_linked_list_link(prev, n, loc_prev, loc_next);
   117         prev = n;
   118     }
   119     return begin;
   120 }
   122 void assign_nodes_test_data(node *n, ...) {
   123     va_list ap;
   124     va_start(ap, n);
   125     while (n != NULL) {
   126         n->data = va_arg(ap, int);
   127         n = n->next;
   128     }
   129     va_end(ap);
   130 }
   132 static void destroy_nodes_test_data(node *n) {
   133     while (n != NULL) {
   134         void *next = n->next;
   135         free(n);
   136         n = next;
   137     }
   138 }
   140 static int *int_test_data(size_t len) {
   141     int *data = malloc(len*sizeof(int));
   142     for (size_t i = 0 ; i < len ; i++) {
   143         data[i] = rand(); // NOLINT(*-msc50-cpp)
   144     }
   145     return data;
   146 }
   148 CX_TEST(test_linked_list_link_unlink) {
   149     node a = {0}, b = {0}, c = {0};
   151     CX_TEST_DO {
   152         cx_linked_list_link(&a, &b, loc_prev, loc_next);
   153         CX_TEST_ASSERT(a.prev == NULL);
   154         CX_TEST_ASSERT(a.next == &b);
   155         CX_TEST_ASSERT(b.prev == &a);
   156         CX_TEST_ASSERT(b.next == NULL);
   158         cx_linked_list_unlink(&a, &b, loc_prev, loc_next);
   159         CX_TEST_ASSERT(a.prev == NULL);
   160         CX_TEST_ASSERT(a.next == NULL);
   161         CX_TEST_ASSERT(b.prev == NULL);
   162         CX_TEST_ASSERT(b.next == NULL);
   164         cx_linked_list_link(&b, &c, loc_prev, loc_next);
   165         cx_linked_list_link(&a, &b, loc_prev, loc_next);
   166         cx_linked_list_unlink(&b, &c, loc_prev, loc_next);
   167         CX_TEST_ASSERT(a.prev == NULL);
   168         CX_TEST_ASSERT(a.next == &b);
   169         CX_TEST_ASSERT(b.prev == &a);
   170         CX_TEST_ASSERT(b.next == NULL);
   171         CX_TEST_ASSERT(c.prev == NULL);
   172         CX_TEST_ASSERT(c.next == NULL);
   173     }
   174 }
   176 CX_TEST(test_linked_list_at) {
   177     node a = {0}, b = {0}, c = {0}, d = {0};
   179     cx_linked_list_link(&a, &b, loc_prev, loc_next);
   180     cx_linked_list_link(&b, &c, loc_prev, loc_next);
   181     cx_linked_list_link(&c, &d, loc_prev, loc_next);
   183     CX_TEST_DO {
   184         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 0) == &a);
   185         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 1) == &b);
   186         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 2) == &c);
   187         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 3) == &d);
   188         CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 4) == NULL);
   189         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_prev, 0) == &a);
   190         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 1) == &b);
   191         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 2) == &c);
   192         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 3) == &d);
   193         CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 4) == NULL);
   194         CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 0) == &a);
   195         CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 1) == &b);
   196     }
   197 }
   199 CX_TEST(test_linked_list_find) {
   200     void *list = create_nodes_test_data(4);
   201     assign_nodes_test_data(list, 2, 4, 6, 8);
   202     CX_TEST_DO {
   203         int s;
   204         s = 2;
   205         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 0);
   206         s = 4;
   207         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 1);
   208         s = 6;
   209         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 2);
   210         s = 8;
   211         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 3);
   212         s = 10;
   213         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
   214         s = -2;
   215         CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
   216     }
   217     destroy_nodes_test_data(list);
   218 }
   220 CX_TEST(test_linked_list_compare) {
   221     void *la = create_nodes_test_data(4);
   222     void *lb = create_nodes_test_data(3);
   223     void *lc = create_nodes_test_data(4);
   224     assign_nodes_test_data(la, 2, 4, 6, 8);
   225     assign_nodes_test_data(lb, 2, 4, 6);
   226     assign_nodes_test_data(lc, 2, 4, 6, 9);
   227     CX_TEST_DO {
   228         CX_TEST_ASSERT(cx_linked_list_compare(la, lb, loc_next, loc_data, cx_cmp_int) > 0);
   229         CX_TEST_ASSERT(cx_linked_list_compare(lb, la, loc_next, loc_data, cx_cmp_int) < 0);
   230         CX_TEST_ASSERT(cx_linked_list_compare(lc, la, loc_next, loc_data, cx_cmp_int) > 0);
   231         CX_TEST_ASSERT(cx_linked_list_compare(la, lc, loc_next, loc_data, cx_cmp_int) < 0);
   232         CX_TEST_ASSERT(cx_linked_list_compare(la, la, loc_next, loc_data, cx_cmp_int) == 0);
   233     }
   234     destroy_nodes_test_data(la);
   235     destroy_nodes_test_data(lb);
   236     destroy_nodes_test_data(lc);
   237 }
   239 CX_TEST(test_linked_list_add) {
   240     node nodes[4];
   241     void *begin, *end;
   242     CX_TEST_DO {
   243         // test with begin, end / prev, next
   244         memset(nodes, 0, sizeof(node)*4);
   245         end = begin = NULL;
   247         cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]);
   248         CX_TEST_ASSERT(begin == &nodes[0]);
   249         CX_TEST_ASSERT(end == &nodes[0]);
   250         CX_TEST_ASSERT(nodes[0].prev == NULL);
   251         CX_TEST_ASSERT(nodes[0].next == NULL);
   253         cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]);
   254         CX_TEST_ASSERT(begin == &nodes[0]);
   255         CX_TEST_ASSERT(end == &nodes[1]);
   256         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   257         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   259         // test with begin only / prev, next
   260         memset(nodes, 0, sizeof(node)*4);
   261         end = begin = NULL;
   263         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]);
   264         CX_TEST_ASSERT(begin == &nodes[0]);
   265         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]);
   266         CX_TEST_ASSERT(begin == &nodes[0]);
   267         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   268         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   270         cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]);
   271         CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
   272         CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
   274         // test with end only / prev, next
   275         memset(nodes, 0, sizeof(node)*4);
   276         end = begin = NULL;
   278         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]);
   279         CX_TEST_ASSERT(end == &nodes[0]);
   280         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]);
   281         CX_TEST_ASSERT(end == &nodes[1]);
   282         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   283         CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
   285         cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]);
   286         CX_TEST_ASSERT(end == &nodes[2]);
   287         CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
   288         CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
   290         // test with begin, end / next
   291         memset(nodes, 0, sizeof(node)*4);
   292         end = begin = NULL;
   294         cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]);
   295         CX_TEST_ASSERT(begin == &nodes[0]);
   296         CX_TEST_ASSERT(end == &nodes[0]);
   297         cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]);
   298         CX_TEST_ASSERT(end == &nodes[1]);
   299         CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
   300         CX_TEST_ASSERT(nodes[1].prev == NULL);
   301     }
   302 }
   304 CX_TEST(test_linked_list_prepend) {
   305     node nodes[4];
   306     void *begin, *end;
   307     CX_TEST_DO {
   308         // test with begin, end / prev, next
   309         memset(nodes, 0, sizeof(node) * 4);
   310         end = begin = NULL;
   312         cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]);
   313         CX_TEST_ASSERT(begin == &nodes[0]);
   314         CX_TEST_ASSERT(end == &nodes[0]);
   315         CX_TEST_ASSERT(nodes[0].prev == NULL);
   316         CX_TEST_ASSERT(nodes[0].next == NULL);
   318         cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]);
   319         CX_TEST_ASSERT(begin == &nodes[1]);
   320         CX_TEST_ASSERT(end == &nodes[0]);
   321         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   322         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   324         // test with begin only / prev, next
   325         memset(nodes, 0, sizeof(node) * 4);
   326         end = begin = NULL;
   328         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]);
   329         CX_TEST_ASSERT(begin == &nodes[0]);
   330         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]);
   331         CX_TEST_ASSERT(begin == &nodes[1]);
   332         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   333         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   335         cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]);
   336         CX_TEST_ASSERT(begin == &nodes[2]);
   337         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   338         CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
   340         // test with end only / prev, next
   341         memset(nodes, 0, sizeof(node) * 4);
   342         end = begin = NULL;
   344         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]);
   345         CX_TEST_ASSERT(end == &nodes[0]);
   346         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]);
   347         CX_TEST_ASSERT(end == &nodes[0]);
   348         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   349         CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
   351         cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]);
   352         CX_TEST_ASSERT(end == &nodes[0]);
   353         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   354         CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
   356         // test with begin, end / next
   357         memset(nodes, 0, sizeof(node) * 4);
   358         end = begin = NULL;
   360         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]);
   361         CX_TEST_ASSERT(begin == &nodes[0]);
   362         CX_TEST_ASSERT(end == &nodes[0]);
   363         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]);
   364         cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]);
   365         CX_TEST_ASSERT(begin == &nodes[2]);
   366         CX_TEST_ASSERT(end == &nodes[0]);
   367         CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
   368         CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
   369         CX_TEST_ASSERT(nodes[1].prev == NULL);
   370         CX_TEST_ASSERT(nodes[0].prev == NULL);
   371     }
   372 }
   374 CX_TEST(test_linked_list_insert) {
   375     node nodes[4];
   376     void *begin, *end;
   377     CX_TEST_DO {
   378         // insert mid list
   379         memset(nodes, 0, sizeof(node) * 4);
   380         begin = &nodes[0];
   381         end = &nodes[2];
   383         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   384         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   386         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]);
   387         CX_TEST_ASSERT(begin == &nodes[0]);
   388         CX_TEST_ASSERT(end == &nodes[2]);
   389         CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
   390         CX_TEST_ASSERT(nodes[2].prev == &nodes[3]);
   391         CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
   392         CX_TEST_ASSERT(nodes[3].next == &nodes[2]);
   394         // insert end
   395         memset(nodes, 0, sizeof(node) * 4);
   396         begin = &nodes[0];
   397         end = &nodes[2];
   399         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   400         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   402         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]);
   403         CX_TEST_ASSERT(begin == &nodes[0]);
   404         CX_TEST_ASSERT(end == &nodes[3]);
   405         CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
   406         CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
   407         CX_TEST_ASSERT(nodes[3].next == NULL);
   409         // insert begin
   410         memset(nodes, 0, sizeof(node) * 4);
   411         begin = &nodes[0];
   412         end = &nodes[2];
   414         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   415         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   417         cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]);
   418         CX_TEST_ASSERT(begin == &nodes[3]);
   419         CX_TEST_ASSERT(end == &nodes[2]);
   420         CX_TEST_ASSERT(nodes[0].prev == &nodes[3]);
   421         CX_TEST_ASSERT(nodes[3].prev == NULL);
   422         CX_TEST_ASSERT(nodes[3].next == &nodes[0]);
   423     }
   424 }
   426 CX_TEST(test_linked_list_insert_chain) {
   427     node nodes[5];
   428     void *begin, *end;
   429     CX_TEST_DO {
   430         // insert mid list
   431         memset(nodes, 0, sizeof(node) * 5);
   432         begin = &nodes[0]; end = &nodes[2];
   434         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   435         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   436         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   438         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL);
   439         CX_TEST_ASSERT(begin == &nodes[0]);
   440         CX_TEST_ASSERT(end == &nodes[2]);
   441         CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
   442         CX_TEST_ASSERT(nodes[2].prev == &nodes[4]);
   443         CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
   444         CX_TEST_ASSERT(nodes[4].next == &nodes[2]);
   446         // insert end
   447         memset(nodes, 0, sizeof(node) * 5);
   448         begin = &nodes[0]; end = &nodes[2];
   450         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   451         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   452         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   454         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL);
   455         CX_TEST_ASSERT(begin == &nodes[0]);
   456         CX_TEST_ASSERT(end == &nodes[4]);
   457         CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
   458         CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
   459         CX_TEST_ASSERT(nodes[4].next == NULL);
   461         // insert begin
   462         memset(nodes, 0, sizeof(node) * 5);
   463         begin = &nodes[0]; end = &nodes[2];
   465         cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
   466         cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
   467         cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
   469         cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL);
   470         CX_TEST_ASSERT(begin == &nodes[3]);
   471         CX_TEST_ASSERT(end == &nodes[2]);
   472         CX_TEST_ASSERT(nodes[0].prev == &nodes[4]);
   473         CX_TEST_ASSERT(nodes[3].prev == NULL);
   474         CX_TEST_ASSERT(nodes[4].next == &nodes[0]);
   475     }
   476 }
   478 CX_TEST(test_linked_list_first) {
   479     node *testdata = create_nodes_test_data(3);
   480     void *begin = testdata;
   481     CX_TEST_DO {
   482         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata, loc_prev));
   483         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next, loc_prev));
   484         CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next->next, loc_prev));
   485     }
   486     destroy_nodes_test_data(testdata);
   487 }
   489 CX_TEST(test_linked_list_last) {
   490     node *testdata = create_nodes_test_data(3);
   491     void *end = testdata->next->next;
   492     CX_TEST_DO {
   493         CX_TEST_ASSERT(end == cx_linked_list_last(testdata, loc_next));
   494         CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next, loc_next));
   495         CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next->next, loc_next));
   496     }
   497     destroy_nodes_test_data(testdata);
   498 }
   500 CX_TEST(test_linked_list_prev) {
   501     node *testdata = create_nodes_test_data(3);
   502     CX_TEST_DO {
   503         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata) == NULL);
   504         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next) == testdata);
   505         CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next->next) == testdata->next);
   506     }
   507     destroy_nodes_test_data(testdata);
   508 }
   510 CX_TEST(test_linked_list_remove) {
   511     node *testdata = create_nodes_test_data(3);
   512     assign_nodes_test_data(testdata, 2, 4, 6);
   513     node *first = testdata;
   514     node *second = first->next;
   515     node *third = second->next;
   516     void *begin = testdata;
   517     void *end = third;
   519     CX_TEST_DO {
   520         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second);
   521         CX_TEST_ASSERT(begin == first);
   522         CX_TEST_ASSERT(end == third);
   523         CX_TEST_ASSERT(first->prev == NULL);
   524         CX_TEST_ASSERT(first->next == third);
   525         CX_TEST_ASSERT(third->prev == first);
   526         CX_TEST_ASSERT(third->next == NULL);
   528         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third);
   529         CX_TEST_ASSERT(begin == first);
   530         CX_TEST_ASSERT(end == first);
   531         CX_TEST_ASSERT(first->prev == NULL);
   532         CX_TEST_ASSERT(first->next == NULL);
   534         cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first);
   535         CX_TEST_ASSERT(begin == NULL);
   536         CX_TEST_ASSERT(end == NULL);
   537     }
   538     // list is not intact anymore, we have to free nodes individually
   539     free(first);
   540     free(second);
   541     free(third);
   542 }
   544 CX_TEST(test_linked_list_size) {
   545     node *td5 = create_nodes_test_data(5);
   546     node *td13 = create_nodes_test_data(13);
   547     CX_TEST_DO {
   548         CX_TEST_ASSERT(cx_linked_list_size(NULL, loc_next) == 0);
   549         CX_TEST_ASSERT(cx_linked_list_size(td5, loc_next) == 5);
   550         CX_TEST_ASSERT(cx_linked_list_size(td13, loc_next) == 13);
   551     }
   552     destroy_nodes_test_data(td5);
   553     destroy_nodes_test_data(td13);
   554 }
   556 CX_TEST(test_linked_list_sort_empty) {
   557     void *begin = NULL;
   558     CX_TEST_DO {
   559         // cannot assert something, we can just test that it does not crash
   560         cx_linked_list_sort(&begin, NULL, loc_prev, loc_next, loc_data, cx_cmp_int);
   561         CX_TEST_ASSERT(true);
   562     }
   563 }
   565 CX_TEST(test_linked_list_sort) {
   566     const size_t len = 1500;
   567     int *testdata = int_test_data(len);
   568     void *scrambled = create_nodes_test_data(len);
   569     node *n = scrambled;
   570     for (size_t i = 0; i < len; i++) {
   571         n->data = testdata[i];
   572         n = n->next;
   573     }
   574     int *sorted = malloc(len*sizeof(int));
   575     memcpy(sorted, testdata, len*sizeof(int));
   576     qsort(sorted, len, sizeof(int), cx_cmp_int);
   578     void *begin = scrambled;
   579     void *end = cx_linked_list_last(begin, loc_next);
   581     CX_TEST_DO {
   582         cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, cx_cmp_int);
   583         node *check = begin;
   584         node *check_last = NULL;
   585         for (size_t i = 0; i < len; i++) {
   586             CX_TEST_ASSERT(check->data == sorted[i]);
   587             CX_TEST_ASSERT(check->prev == check_last);
   588             if (i < len - 1) {
   589                 CX_TEST_ASSERT(check->next != NULL);
   590             }
   591             check_last = check;
   592             check = check->next;
   593         }
   594         CX_TEST_ASSERT(check == NULL);
   595         CX_TEST_ASSERT(end == check_last);
   596     }
   597     destroy_nodes_test_data(begin);
   598     free(sorted);
   599     free(testdata);
   600 }
   602 CX_TEST(test_linked_list_reverse) {
   603     void *testdata = create_nodes_test_data(4);
   604     void *expected = create_nodes_test_data(4);
   605     assign_nodes_test_data(testdata, 2, 4, 6, 8);
   606     assign_nodes_test_data(expected, 8, 6, 4, 2);
   607     void *begin = testdata;
   608     CX_TEST_DO {
   609         void *end = cx_linked_list_last(begin, loc_next);
   610         void *orig_begin = begin, *orig_end = end;
   612         cx_linked_list_reverse(&begin, &end, loc_prev, loc_next);
   613         CX_TEST_ASSERT(end == orig_begin);
   614         CX_TEST_ASSERT(begin == orig_end);
   615         CX_TEST_ASSERT(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, cx_cmp_int));
   616     }
   617     destroy_nodes_test_data(begin);
   618     destroy_nodes_test_data(expected);
   619 }
   622 CX_TEST(test_empty_list_size) {
   623     CX_TEST_DO {
   624         CX_TEST_ASSERT(cxEmptyList->size == 0);
   625         CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0);
   626     }
   627 }
   629 CX_TEST(test_empty_list_iterator) {
   630     CxList *list = cxEmptyList;
   632     CxIterator it1 = cxListIterator(list);
   633     CxIterator it2 = cxListBackwardsIterator(list);
   634     CxMutIterator it3 = cxListMutIterator(list);
   635     CxMutIterator it4 = cxListMutBackwardsIterator(list);
   637     CX_TEST_DO {
   638         CX_TEST_ASSERT(!cxIteratorValid(it1));
   639         CX_TEST_ASSERT(!cxIteratorValid(it2));
   640         CX_TEST_ASSERT(!cxIteratorValid(it3));
   641         CX_TEST_ASSERT(!cxIteratorValid(it4));
   643         int c = 0;
   644         cx_foreach(void*, data, it1) c++;
   645         cx_foreach(void*, data, it2) c++;
   646         cx_foreach(void*, data, it3) c++;
   647         cx_foreach(void*, data, it4) c++;
   648         CX_TEST_ASSERT(c == 0);
   649     }
   650 }
   652 CX_TEST(test_empty_list_noops) {
   653     CX_TEST_DO {
   654         CxList copy = *cxEmptyList;
   655         cxListSort(cxEmptyList);
   656         cxListClear(cxEmptyList);
   657         cxListDestroy(cxEmptyList);
   658         CX_TEST_ASSERT(0 == memcmp(&copy, cxEmptyList, sizeof(CxList))); // NOLINT(*-suspicious-memory-comparison)
   659     }
   660 }
   662 CX_TEST(test_empty_list_at) {
   663     CX_TEST_DO {
   664         CX_TEST_ASSERT(cxListAt(cxEmptyList, 0) == NULL);
   665         CX_TEST_ASSERT(cxListAt(cxEmptyList, 1) == NULL);
   666     }
   667 }
   669 CX_TEST(test_empty_list_find) {
   670     int x = 42, y = 1337;
   671     CX_TEST_DO {
   672         CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) < 0);
   673         CX_TEST_ASSERT(cxListFind(cxEmptyList, &y) < 0);
   674     }
   675 }
   677 CX_TEST(test_empty_list_compare) {
   678     CxList *empty = cxEmptyList;
   679     CxList *ll = cxLinkedListCreateSimple(sizeof(int));
   680     CxList *al = cxArrayListCreateSimple(sizeof(int), 8);
   681     int x = 5;
   682     CX_TEST_DO {
   683         CX_TEST_ASSERT(0 == cxListCompare(empty, cxEmptyList));
   684         CX_TEST_ASSERT(0 == cxListCompare(ll, cxEmptyList));
   685         CX_TEST_ASSERT(0 == cxListCompare(al, cxEmptyList));
   686         CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, ll));
   687         CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, al));
   689         cxListAdd(ll, &x);
   690         cxListAdd(al, &x);
   692         CX_TEST_ASSERT(0 < cxListCompare(ll, cxEmptyList));
   693         CX_TEST_ASSERT(0 < cxListCompare(al, cxEmptyList));
   694         CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, ll));
   695         CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, al));
   696     }
   697     cxListDestroy(ll);
   698     cxListDestroy(al);
   699 }
   701 CX_TEST(test_list_ll_create) {
   702     CxTestingAllocator talloc;
   703     cx_testing_allocator_init(&talloc);
   704     CxAllocator *alloc = &talloc.base;
   705     CX_TEST_DO {
   706         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int));
   707         CX_TEST_ASSERT(list != NULL);
   708         CX_TEST_ASSERT(list->item_size == sizeof(int));
   709         CX_TEST_ASSERT(list->simple_destructor == NULL);
   710         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   711         CX_TEST_ASSERT(list->destructor_data == NULL);
   712         CX_TEST_ASSERT(cxListSize(list) == 0);
   713         CX_TEST_ASSERT(list->allocator == alloc);
   714         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
   715         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   716         cxListDestroy(list);
   717         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   718     }
   719     cx_testing_allocator_destroy(&talloc);
   720 }
   722 CX_TEST(test_list_ll_create_simple) {
   723     CxList *list = cxLinkedListCreateSimple(sizeof(int));
   724     CX_TEST_DO {
   725         CX_TEST_ASSERT(list != NULL);
   726         CX_TEST_ASSERT(list->item_size == sizeof(int));
   727         CX_TEST_ASSERT(list->simple_destructor == NULL);
   728         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   729         CX_TEST_ASSERT(list->destructor_data == NULL);
   730         CX_TEST_ASSERT(cxListSize(list) == 0);
   731         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   732         CX_TEST_ASSERT(list->cmpfunc == NULL);
   733         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   734     }
   735     cxListDestroy(list);
   736 }
   738 CX_TEST(test_list_ll_store_pointers) {
   739     CxList *list = cxLinkedListCreateSimple(47);
   740     CX_TEST_DO {
   741         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   742         cxListStorePointers(list);
   743         CX_TEST_ASSERT(list->item_size == sizeof(void *));
   744         CX_TEST_ASSERT(list->cl != NULL);
   745         CX_TEST_ASSERT(list->climpl != NULL);
   746         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   747         cxListStoreObjects(list);
   748         CX_TEST_ASSERT(list->cl != NULL);
   749         CX_TEST_ASSERT(list->climpl == NULL);
   750         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   751     }
   752     cxListDestroy(list);
   753 }
   755 CX_TEST(test_list_ll_create_simple_for_pointers) {
   756     CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
   757     CX_TEST_DO {
   758         CX_TEST_ASSERT(list != NULL);
   759         CX_TEST_ASSERT(list->item_size == sizeof(void*));
   760         CX_TEST_ASSERT(list->simple_destructor == NULL);
   761         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   762         CX_TEST_ASSERT(list->destructor_data == NULL);
   763         CX_TEST_ASSERT(cxListSize(list) == 0);
   764         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   765         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
   766         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   767     }
   768     cxListDestroy(list);
   769 }
   771 CX_TEST(test_list_arl_create) {
   772     CxTestingAllocator talloc;
   773     cx_testing_allocator_init(&talloc);
   774     CxAllocator *alloc = &talloc.base;
   775     CX_TEST_DO {
   776         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8);
   777         CX_TEST_ASSERT(list != NULL);
   778         CX_TEST_ASSERT(list->item_size == sizeof(int));
   779         CX_TEST_ASSERT(list->simple_destructor == NULL);
   780         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   781         CX_TEST_ASSERT(list->destructor_data == NULL);
   782         CX_TEST_ASSERT(cxListSize(list) == 0);
   783         CX_TEST_ASSERT(list->allocator == alloc);
   784         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
   785         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   786         cxListDestroy(list);
   787         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   788     }
   789     cx_testing_allocator_destroy(&talloc);
   790 }
   792 CX_TEST(test_list_arl_create_simple) {
   793     CxList *list = cxArrayListCreateSimple(sizeof(int), 8);
   794     CX_TEST_DO {
   795         CX_TEST_ASSERT(list != NULL);
   796         CX_TEST_ASSERT(list->item_size == sizeof(int));
   797         CX_TEST_ASSERT(list->simple_destructor == NULL);
   798         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   799         CX_TEST_ASSERT(list->destructor_data == NULL);
   800         CX_TEST_ASSERT(cxListSize(list) == 0);
   801         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   802         CX_TEST_ASSERT(list->cmpfunc == NULL);
   803         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   804     }
   805     cxListDestroy(list);
   806 }
   808 CX_TEST(test_list_arl_create_simple_for_pointers) {
   809     CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8);
   810     CX_TEST_DO {
   811         CX_TEST_ASSERT(list != NULL);
   812         CX_TEST_ASSERT(list->item_size == sizeof(void*));
   813         CX_TEST_ASSERT(list->simple_destructor == NULL);
   814         CX_TEST_ASSERT(list->advanced_destructor == NULL);
   815         CX_TEST_ASSERT(list->destructor_data == NULL);
   816         CX_TEST_ASSERT(cxListSize(list) == 0);
   817         CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
   818         CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
   819         CX_TEST_ASSERT(cxListIsStoringPointers(list));
   820     }
   821     cxListDestroy(list);
   822 }
   824 static void test_fake_simple_int_destr(void *elem) {
   825     *(int *) elem = 42;
   826 }
   828 CX_TEST(test_list_pll_destroy_no_destr) {
   829     CxTestingAllocator talloc;
   830     cx_testing_allocator_init(&talloc);
   831     CxAllocator *alloc = &talloc.base;
   832     CX_TEST_DO {
   833         void *item = cxMalloc(alloc, sizeof(int));
   834         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   835         cxListAdd(list, item);
   836         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   837         cxListDestroy(list);
   838         // item is not yet freed
   839         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   840         cxFree(alloc, item);
   841         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   842     }
   843     cx_testing_allocator_destroy(&talloc);
   844 }
   846 CX_TEST(test_list_pll_destroy_simple_destr) {
   847     CX_TEST_DO {
   848         int item = 0;
   849         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   850         list->simple_destructor = test_fake_simple_int_destr;
   851         cxListAdd(list, &item);
   852         cxListDestroy(list);
   853         CX_TEST_ASSERT(item == 42);
   854     }
   855 }
   857 CX_TEST(test_list_pll_destroy_adv_destr) {
   858     CxTestingAllocator talloc;
   859     cx_testing_allocator_init(&talloc);
   860     CxAllocator *alloc = &talloc.base;
   861     CX_TEST_DO {
   862         void *item = cxMalloc(alloc, sizeof(int));
   863         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
   864         list->destructor_data = alloc;
   865         list->advanced_destructor = (cx_destructor_func2) cxFree;
   866         cxListAdd(list, item);
   867         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   868         cxListDestroy(list);
   869         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   870     }
   871     cx_testing_allocator_destroy(&talloc);
   872 }
   874 CX_TEST(test_list_parl_destroy_no_destr) {
   875     CxTestingAllocator talloc;
   876     cx_testing_allocator_init(&talloc);
   877     CxAllocator *alloc = &talloc.base;
   878     CX_TEST_DO {
   879         void *item = cxMalloc(alloc, sizeof(int));
   880         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   881         cxListAdd(list, item);
   882         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   883         cxListDestroy(list);
   884         // item is not yet freed
   885         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   886         cxFree(alloc, item);
   887         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   888     }
   889     cx_testing_allocator_destroy(&talloc);
   890 }
   892 CX_TEST(test_list_parl_destroy_simple_destr) {
   893     CX_TEST_DO {
   894         int item = 0;
   895         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   896         list->simple_destructor = test_fake_simple_int_destr;
   897         cxListAdd(list, &item);
   898         cxListDestroy(list);
   899         CX_TEST_ASSERT(item == 42);
   900     }
   901 }
   903 CX_TEST(test_list_parl_destroy_adv_destr) {
   904     CxTestingAllocator talloc;
   905     cx_testing_allocator_init(&talloc);
   906     CxAllocator *alloc = &talloc.base;
   907     CX_TEST_DO {
   908         void *item = cxMalloc(alloc, sizeof(int));
   909         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
   910         list->destructor_data = alloc;
   911         list->advanced_destructor = (cx_destructor_func2) cxFree;
   912         cxListAdd(list, item);
   913         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
   914         cxListDestroy(list);
   915         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   916     }
   917     cx_testing_allocator_destroy(&talloc);
   918 }
   920 #define set_up_combo \
   921     CxTestingAllocator talloc; \
   922     cx_testing_allocator_init(&talloc); \
   923     CxAllocator *alloc = &talloc.base; \
   924     CX_TEST_DO {
   925 #define tear_down_combo \
   926         cxListDestroy(list); \
   927         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));\
   928     } \
   929     cx_testing_allocator_destroy(&talloc);
   930 #define roll_out_test_combos(name, body) \
   931 static CX_TEST_SUBROUTINE(test_list_verify_##name, CxList *list, \
   932     __attribute__((__unused__)) bool isptrlist) body \
   933 CX_TEST(test_list_ll_##name) { \
   934     set_up_combo \
   935         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); \
   936         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
   937     tear_down_combo \
   938 } \
   939 CX_TEST(test_list_arl_##name) { \
   940     set_up_combo \
   941         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); \
   942         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
   943     tear_down_combo \
   944 } \
   945 CX_TEST(test_list_pll_##name) { \
   946     set_up_combo \
   947         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \
   948         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
   949     tear_down_combo \
   950 } \
   951 CX_TEST(test_list_parl_##name) { \
   952     set_up_combo \
   953         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS, 8); \
   954         CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
   955     tear_down_combo \
   956 }
   957 #define array_init(...) {__VA_ARGS__}
   959 static inline int *int_test_data_added_to_list(CxList *list, bool isptrlist, size_t len) {
   960     int *testdata = int_test_data(len);
   961     if (isptrlist) {
   962         cx_for_n(i, len) {
   963             cxListAdd(list, &testdata[i]);
   964         }
   965     } else {
   966         cxListAddArray(list, testdata, len);
   967     }
   968     return testdata;
   969 }
   971 roll_out_test_combos(add, {
   972     const size_t len = 250;
   973     int *testdata = int_test_data(len);
   974     cx_for_n (i, len) CX_TEST_ASSERT(cxListAdd(list, &testdata[i]) == 0);
   975     CX_TEST_ASSERT(cxListSize(list) == len);
   976     cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
   977     cx_for_n (i, len) ++testdata[i];
   978     if (isptrlist) {
   979         cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
   980     } else {
   981         cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i] - 1);
   982     }
   983     free(testdata);
   984 })
   986 roll_out_test_combos(insert, {
   987     int a = 5;
   988     int b = 47;
   989     int c = 13;
   990     int d = 42;
   991     CX_TEST_ASSERT(cxListInsert(list, 1, &a) != 0);
   992     CX_TEST_ASSERT(cxListSize(list) == 0);
   993     CX_TEST_ASSERT(cxListInsert(list, 0, &a) == 0);
   994     CX_TEST_ASSERT(cxListSize(list) == 1);
   995     CX_TEST_ASSERT(cxListInsert(list, 0, &b) == 0);
   996     CX_TEST_ASSERT(cxListSize(list) == 2);
   997     CX_TEST_ASSERT(cxListInsert(list, 1, &c) == 0);
   998     CX_TEST_ASSERT(cxListSize(list) == 3);
   999     CX_TEST_ASSERT(cxListInsert(list, 3, &d) == 0);
  1000     CX_TEST_ASSERT(cxListSize(list) == 4);
  1001     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 47);
  1002     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 13);
  1003     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 5);
  1004     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 42);
  1005 })
  1007 roll_out_test_combos(insert_array, {
  1008     int a[5] = array_init(5, 47, 11, 13, 42);
  1009     int b[5] = array_init(9, 18, 72, 50, 7);
  1010     int *aptr[5];
  1011     int *bptr[5];
  1012     cx_for_n(i, 5) {
  1013         aptr[i] = &a[i];
  1014         bptr[i] = &b[i];
  1017     size_t inserted;
  1019     if (isptrlist) {
  1020         inserted = cxListInsertArray(list, 0, aptr, 5);
  1021     } else {
  1022         inserted = cxListInsertArray(list, 0, a, 5);
  1024     CX_TEST_ASSERT(inserted == 5);
  1025     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
  1026     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
  1027     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
  1028     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 13);
  1029     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 42);
  1030     if (isptrlist) {
  1031         inserted = cxListInsertArray(list, 3, bptr, 5);
  1032     } else {
  1033         inserted = cxListInsertArray(list, 3, b, 5);
  1035     CX_TEST_ASSERT(inserted == 5);
  1036     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
  1037     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
  1038     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
  1039     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 9);
  1040     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 18);
  1041     CX_TEST_ASSERT(*(int *) cxListAt(list, 5) == 72);
  1042     CX_TEST_ASSERT(*(int *) cxListAt(list, 6) == 50);
  1043     CX_TEST_ASSERT(*(int *) cxListAt(list, 7) == 7);
  1044     CX_TEST_ASSERT(*(int *) cxListAt(list, 8) == 13);
  1045     CX_TEST_ASSERT(*(int *) cxListAt(list, 9) == 42);
  1046 })
  1048 roll_out_test_combos(remove, {
  1049     const size_t testdata_len = 32;
  1050     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1052     CX_TEST_ASSERT(cxListRemove(list, 2) == 0);
  1053     CX_TEST_ASSERT(cxListRemove(list, 4) == 0);
  1054     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 2);
  1055     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[0]);
  1056     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[1]);
  1057     CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == testdata[3]);
  1058     CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == testdata[4]);
  1059     CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == testdata[6]);
  1060     CX_TEST_ASSERT(cxListRemove(list, 0) == 0);
  1061     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 3);
  1062     CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[1]);
  1063     CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[3]);
  1064     CX_TEST_ASSERT(cxListRemove(list, testdata_len) != 0);
  1065     free(testdata);
  1066 })
  1068 roll_out_test_combos(find_remove, {
  1069     const size_t testdata_len = 250;
  1070     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1072     int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
  1073     int val = testdata[exp];
  1074     // randomly picked number could occur earlier in list - find first position
  1075     for (int i = 0 ; i < exp ; i++) {
  1076         if (testdata[i] == val) {
  1077             exp = i;
  1078             break;
  1081     CX_TEST_ASSERT(cxListSize(list) == testdata_len);
  1082     CX_TEST_ASSERT(cxListFind(list, &val) == exp);
  1083     CX_TEST_ASSERT(cxListFindRemove(list, &val) == exp);
  1084     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
  1085     CX_TEST_ASSERT(cxListFind(list, &val) != exp);
  1087     int notinlist = -1;
  1088     CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) < 0);
  1089     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
  1091     free(testdata);
  1092 })
  1094 roll_out_test_combos(clear, {
  1095     int *testdata = int_test_data_added_to_list(list, isptrlist, 8);
  1096     CX_TEST_ASSERT(cxListSize(list) > 0);
  1097     cxListClear(list);
  1098     CX_TEST_ASSERT(cxListSize(list) == 0);
  1099     free(testdata);
  1100 })
  1102 roll_out_test_combos(at, {
  1103     size_t len = 128;
  1104     int *testdata = int_test_data_added_to_list(list, isptrlist, 128);
  1105     CX_TEST_ASSERT(cxListSize(list) == len);
  1106     cx_for_n (i, len) {
  1107         CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
  1109     CX_TEST_ASSERT(cxListAt(list, cxListSize(list)) == NULL);
  1110     free(testdata);
  1111 })
  1113 roll_out_test_combos(swap, {
  1114     int original[16] = array_init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
  1115     int swapped[16] = array_init(8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13);
  1117     cx_for_n(i, 16) {
  1118         cxListAdd(list, &original[i]);
  1121     CX_TEST_ASSERT(0 == cxListSwap(list, 1, 4));
  1122     CX_TEST_ASSERT(0 == cxListSwap(list, 2, 14));
  1123     CX_TEST_ASSERT(0 == cxListSwap(list, 9, 6));
  1124     CX_TEST_ASSERT(0 == cxListSwap(list, 3, 3));
  1125     CX_TEST_ASSERT(0 == cxListSwap(list, 10, 11));
  1126     CX_TEST_ASSERT(0 == cxListSwap(list, 8, 0));
  1127     CX_TEST_ASSERT(0 == cxListSwap(list, 7, 12));
  1128     CX_TEST_ASSERT(0 == cxListSwap(list, 13, 15));
  1130     CX_TEST_ASSERT(0 != cxListSwap(list, 5, 16));
  1131     CX_TEST_ASSERT(0 != cxListSwap(list, 16, 6));
  1132     CX_TEST_ASSERT(0 != cxListSwap(list, 16, 17));
  1134     CxIterator iter = cxListIterator(list);
  1135     cx_foreach(int*, e, iter) {
  1136         CX_TEST_ASSERT(*e == swapped[iter.index]);
  1138     iter = cxListBackwardsIterator(list);
  1139     cx_foreach(int*, e, iter) {
  1140         CX_TEST_ASSERT(*e == swapped[iter.index]);
  1142 })
  1144 CX_TEST(test_list_ll_swap_no_sbo) {
  1145     set_up_combo
  1146         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, 2*cx_linked_list_swap_sbo_size);
  1147         CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
  1148     tear_down_combo
  1150 CX_TEST(test_list_arl_swap_no_sbo) {
  1151     set_up_combo
  1152         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, 2*cx_array_swap_sbo_size, 8);
  1153         CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
  1154     tear_down_combo
  1157 roll_out_test_combos(find, {
  1158     const size_t testdata_len = 500;
  1159     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1161     cx_for_n (attempt, 25) {
  1162         int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
  1163         int val = testdata[exp];
  1164         // randomly picked number could occur earlier in list - find first position
  1165         for (int i = 0 ; i < exp ; i++) {
  1166             if (testdata[i] == val) {
  1167                 exp = i;
  1168                 break;
  1171         CX_TEST_ASSERT(cxListFind(list, &val) == exp);
  1174     int notinlist = -1;
  1175     CX_TEST_ASSERT(cxListFind(list, &notinlist) < 0);
  1177     free(testdata);
  1178 })
  1180 roll_out_test_combos(sort, {
  1181     const size_t testdata_len = 250;
  1182     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1183     int *expected = malloc(testdata_len*sizeof(int));
  1184     memcpy(expected, testdata, testdata_len*sizeof(int));
  1185     qsort(expected, testdata_len, sizeof(int), cx_cmp_int);
  1187     cxListSort(list);
  1188     cx_for_n (i, testdata_len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]);
  1190     free(expected);
  1191     free(testdata);
  1192 })
  1194 roll_out_test_combos(reverse, {
  1195     const size_t testdata_len = 50;
  1196     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
  1197     cxListReverse(list);
  1198     cx_for_n(i, testdata_len) {
  1199         CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[testdata_len - 1 - i]);
  1201     free(testdata);
  1202 })
  1204 roll_out_test_combos(iterator, {
  1205     const size_t len = 50;
  1206     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1208     CxIterator iter = cxListIterator(list);
  1209     size_t i = 0;
  1210     cx_foreach(int*, x, iter) {
  1211         CX_TEST_ASSERT(i == iter.index);
  1212         CX_TEST_ASSERT(*x == testdata[iter.index]);
  1213         i++;
  1215     CX_TEST_ASSERT(i == cxListSize(list));
  1216     iter = cxListBackwardsIterator(list);
  1217     cx_foreach(int*, x, iter) {
  1218         CX_TEST_ASSERT(i - 1 == iter.index);
  1219         CX_TEST_ASSERT(*x == testdata[iter.index]);
  1220         i--;
  1222     CX_TEST_ASSERT(i == 0);
  1223     i = len / 2;
  1224     CxMutIterator mut_iter = cxListMutIteratorAt(list, i);
  1225     size_t j = 0;
  1226     cx_foreach(int*, x, mut_iter) {
  1227         CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2);
  1228         CX_TEST_ASSERT(*x == testdata[i]);
  1229         if (i % 2 == 1) cxIteratorFlagRemoval(mut_iter);
  1230         i++;
  1231         j++;
  1233     CX_TEST_ASSERT(i == len);
  1234     i = len / 2;
  1235     j = 0;
  1236     mut_iter = cxListMutBackwardsIteratorAt(list, i - 1);
  1237     cx_foreach(int*, x, mut_iter) {
  1238         CX_TEST_ASSERT(mut_iter.index == len / 2 - 1 - j);
  1239         CX_TEST_ASSERT(*x == testdata[i - 1]);
  1240         if (i % 2 == 0) cxIteratorFlagRemoval(mut_iter);
  1241         i--;
  1242         j++;
  1244     CX_TEST_ASSERT(i == 0);
  1245     CX_TEST_ASSERT(cxListSize(list) == len / 2);
  1246     cx_for_n(k, len / 2) CX_TEST_ASSERT(*(int *) cxListAt(list, k) == testdata[k * 2]);
  1248     free(testdata);
  1249 })
  1251 roll_out_test_combos(insert_with_iterator, {
  1252     int fivenums[] = array_init(0, 1, 2, 3, 4);
  1253     cx_for_n(i, 5) cxListAdd(list, &fivenums[i]);
  1254     int newdata[] = array_init(10, 20, 30, 40, 50);
  1256     CxMutIterator iter = cxListMutIteratorAt(list, 2);
  1257     CX_TEST_ASSERT(cxIteratorValid(iter));
  1258     CX_TEST_ASSERT(iter.index == 2);
  1259     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1260     cxListInsertAfter(&iter, &newdata[0]);
  1261     CX_TEST_ASSERT(cxIteratorValid(iter));
  1262     CX_TEST_ASSERT(iter.index == 2);
  1263     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1264     cxListInsertBefore(&iter, &newdata[1]);
  1265     CX_TEST_ASSERT(cxIteratorValid(iter));
  1266     CX_TEST_ASSERT(iter.index == 3);
  1267     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
  1269     iter = cxListMutIterator(list);
  1270     cxListInsertBefore(&iter, &newdata[2]);
  1271     CX_TEST_ASSERT(cxIteratorValid(iter));
  1272     CX_TEST_ASSERT(iter.index == 1);
  1273     CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 0);
  1274     iter = cxListMutIteratorAt(list, cxListSize(list));
  1275     cxListInsertBefore(&iter, &newdata[3]);
  1276     CX_TEST_ASSERT(!cxIteratorValid(iter));
  1277     CX_TEST_ASSERT(iter.index == 9);
  1278     iter = cxListMutIteratorAt(list, cxListSize(list));
  1279     cxListInsertAfter(&iter, &newdata[4]);
  1280     CX_TEST_ASSERT(!cxIteratorValid(iter));
  1281     CX_TEST_ASSERT(iter.index == 10);
  1283     int expdata[] = array_init(30, 0, 1, 20, 2, 10, 3, 4, 40, 50);
  1284     cx_for_n (j, 10) CX_TEST_ASSERT(*(int *) cxListAt(list, j) == expdata[j]);
  1285 })
  1287 static CX_TEST_SUBROUTINE(test_list_verify_compare, CxList *left, CxList *right) {
  1288     CX_TEST_ASSERTM(cxListCompare(left, right) == 0, "lists don't start identical");
  1289     int x = 42;
  1290     cxListAdd(left, &x);
  1291     CX_TEST_ASSERT(cxListSize(left) > cxListSize(right));
  1292     CX_TEST_ASSERT(cxListCompare(left, right) > 0);
  1293     CX_TEST_ASSERT(cxListCompare(right, left) < 0);
  1294     cxListAdd(right, &x);
  1295     CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
  1296     CX_TEST_ASSERT(cxListCompare(left, right) == 0);
  1297     int a = 5, b = 10;
  1298     cxListInsert(left, 15, &a);
  1299     cxListInsert(right, 15, &b);
  1300     CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
  1301     CX_TEST_ASSERT(cxListCompare(left, right) < 0);
  1302     CX_TEST_ASSERT(cxListCompare(right, left) > 0);
  1303     *(int *) cxListAt(left, 15) = 10;
  1304     CX_TEST_ASSERT(cxListCompare(left, right) == 0);
  1307 #define roll_out_compare_tests(suffix, otherctr) \
  1308 roll_out_test_combos(compare_##suffix, { \
  1309     const size_t len = 47; \
  1310     int *testdata = int_test_data_added_to_list(list, isptrlist, len); \
  1311     CxList *other = otherctr; \
  1312     cx_for_n(i, len) cxListAdd(other, &testdata[i]); \
  1313     CX_TEST_CALL_SUBROUTINE(test_list_verify_compare, list, other); \
  1314     cxListDestroy(other); \
  1315     free(testdata); \
  1316 })
  1318 roll_out_compare_tests(
  1319         ll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int))
  1322 roll_out_compare_tests(
  1323         pll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS)
  1326 roll_out_compare_tests(
  1327         arl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 50)
  1330 roll_out_compare_tests(
  1331         parl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 50)
  1334 static unsigned destr_test_ctr;
  1335 static int destr_last_value;
  1337 static void simple_destr_test_fun(void *data) {
  1338     int *ptr = data;
  1339     destr_last_value = *ptr;
  1340     *ptr = destr_last_value + 1;
  1341     destr_test_ctr++;
  1344 static void advanced_destr_test_fun(__attribute__((__unused__)) void *u, void *data) {
  1345     simple_destr_test_fun(data);
  1348 static CX_TEST_SUBROUTINE(test_list_verify_destructor, CxList *list,
  1349                           int const *testdata, size_t testdata_len) {
  1350     destr_test_ctr = 0;
  1352     int off = cxListIsStoringPointers(list) ? 1 : 0;
  1354     cxListRemove(list, 15);
  1355     CX_TEST_ASSERT(1 == destr_test_ctr);
  1356     CX_TEST_ASSERT(testdata[15] == destr_last_value + off);
  1357     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1358     cxListRemove(list, 47);
  1359     CX_TEST_ASSERT(2 == destr_test_ctr);
  1360     CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
  1361     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1363     CxMutIterator iter = cxListMutIteratorAt(list, 7);
  1364     cxIteratorNext(iter);
  1365     CX_TEST_ASSERT(2 == destr_test_ctr);
  1366     CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
  1367     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1368     cxIteratorFlagRemoval(iter);
  1369     cxIteratorNext(iter);
  1370     CX_TEST_ASSERT(3 == destr_test_ctr);
  1371     CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
  1372     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1374     iter = cxListMutBackwardsIteratorAt(list, 5);
  1375     cxIteratorNext(iter);
  1376     CX_TEST_ASSERT(3 == destr_test_ctr);
  1377     CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
  1378     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1379     cxIteratorFlagRemoval(iter);
  1380     cxIteratorNext(iter);
  1381     CX_TEST_ASSERT(4 == destr_test_ctr);
  1382     CX_TEST_ASSERT(testdata[4] == destr_last_value + off);
  1383     CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
  1385     cxListClear(list);
  1386     CX_TEST_ASSERT(testdata_len == destr_test_ctr);
  1387     CX_TEST_ASSERT(testdata[testdata_len - 1] == destr_last_value + off);
  1390 roll_out_test_combos(simple_destr, {
  1391     const size_t len = 60;
  1392     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1393     list->simple_destructor = simple_destr_test_fun;
  1394     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  1395     free(testdata);
  1396 })
  1398 roll_out_test_combos(advanced_destr, {
  1399     const size_t len = 75;
  1400     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  1401     list->advanced_destructor = advanced_destr_test_fun;
  1402     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  1403     free(testdata);
  1404 })
  1406 CxTestSuite *cx_test_suite_array_list(void) {
  1407     CxTestSuite *suite = cx_test_suite_new("array_list");
  1409     cx_test_register(suite, test_array_add);
  1411     cx_test_register(suite, test_list_arl_create);
  1412     cx_test_register(suite, test_list_arl_create_simple);
  1413     cx_test_register(suite, test_list_arl_create_simple_for_pointers);
  1414     cx_test_register(suite, test_list_parl_destroy_no_destr);
  1415     cx_test_register(suite, test_list_parl_destroy_simple_destr);
  1416     cx_test_register(suite, test_list_parl_destroy_adv_destr);
  1418     cx_test_register(suite, test_list_arl_add);
  1419     cx_test_register(suite, test_list_parl_add);
  1420     cx_test_register(suite, test_list_arl_insert);
  1421     cx_test_register(suite, test_list_parl_insert);
  1422     cx_test_register(suite, test_list_arl_insert_array);
  1423     cx_test_register(suite, test_list_parl_insert_array);
  1424     cx_test_register(suite, test_list_arl_remove);
  1425     cx_test_register(suite, test_list_parl_remove);
  1426     cx_test_register(suite, test_list_arl_find_remove);
  1427     cx_test_register(suite, test_list_parl_find_remove);
  1428     cx_test_register(suite, test_list_arl_clear);
  1429     cx_test_register(suite, test_list_parl_clear);
  1430     cx_test_register(suite, test_list_arl_at);
  1431     cx_test_register(suite, test_list_parl_at);
  1432     cx_test_register(suite, test_list_arl_swap);
  1433     cx_test_register(suite, test_list_parl_swap);
  1434     cx_test_register(suite, test_list_arl_swap_no_sbo);
  1435     cx_test_register(suite, test_list_arl_find);
  1436     cx_test_register(suite, test_list_parl_find);
  1437     cx_test_register(suite, test_list_arl_sort);
  1438     cx_test_register(suite, test_list_parl_sort);
  1439     cx_test_register(suite, test_list_arl_reverse);
  1440     cx_test_register(suite, test_list_parl_reverse);
  1441     cx_test_register(suite, test_list_arl_iterator);
  1442     cx_test_register(suite, test_list_parl_iterator);
  1443     cx_test_register(suite, test_list_arl_insert_with_iterator);
  1444     cx_test_register(suite, test_list_parl_insert_with_iterator);
  1445     cx_test_register(suite, test_list_arl_compare_ll);
  1446     cx_test_register(suite, test_list_arl_compare_arl);
  1447     cx_test_register(suite, test_list_arl_compare_pll);
  1448     cx_test_register(suite, test_list_arl_compare_parl);
  1449     cx_test_register(suite, test_list_parl_compare_ll);
  1450     cx_test_register(suite, test_list_parl_compare_arl);
  1451     cx_test_register(suite, test_list_parl_compare_pll);
  1452     cx_test_register(suite, test_list_parl_compare_parl);
  1453     cx_test_register(suite, test_list_arl_simple_destr);
  1454     cx_test_register(suite, test_list_parl_simple_destr);
  1455     cx_test_register(suite, test_list_arl_advanced_destr);
  1456     cx_test_register(suite, test_list_parl_advanced_destr);
  1458     return suite;
  1461 CxTestSuite *cx_test_suite_linked_list(void) {
  1462     CxTestSuite *suite = cx_test_suite_new("linked_list");
  1464     cx_test_register(suite, test_linked_list_link_unlink);
  1465     cx_test_register(suite, test_linked_list_at);
  1466     cx_test_register(suite, test_linked_list_find);
  1467     cx_test_register(suite, test_linked_list_compare);
  1468     cx_test_register(suite, test_linked_list_add);
  1469     cx_test_register(suite, test_linked_list_prepend);
  1470     cx_test_register(suite, test_linked_list_insert);
  1471     cx_test_register(suite, test_linked_list_insert_chain);
  1472     cx_test_register(suite, test_linked_list_first);
  1473     cx_test_register(suite, test_linked_list_last);
  1474     cx_test_register(suite, test_linked_list_prev);
  1475     cx_test_register(suite, test_linked_list_remove);
  1476     cx_test_register(suite, test_linked_list_size);
  1477     cx_test_register(suite, test_linked_list_sort_empty);
  1478     cx_test_register(suite, test_linked_list_sort);
  1479     cx_test_register(suite, test_linked_list_reverse);
  1481     cx_test_register(suite, test_list_ll_create);
  1482     cx_test_register(suite, test_list_ll_create_simple);
  1483     cx_test_register(suite, test_list_ll_store_pointers);
  1484     cx_test_register(suite, test_list_ll_create_simple_for_pointers);
  1485     cx_test_register(suite, test_list_pll_destroy_no_destr);
  1486     cx_test_register(suite, test_list_pll_destroy_simple_destr);
  1487     cx_test_register(suite, test_list_pll_destroy_adv_destr);
  1489     cx_test_register(suite, test_list_ll_add);
  1490     cx_test_register(suite, test_list_pll_add);
  1491     cx_test_register(suite, test_list_ll_insert);
  1492     cx_test_register(suite, test_list_pll_insert);
  1493     cx_test_register(suite, test_list_ll_insert_array);
  1494     cx_test_register(suite, test_list_pll_insert_array);
  1495     cx_test_register(suite, test_list_ll_remove);
  1496     cx_test_register(suite, test_list_pll_remove);
  1497     cx_test_register(suite, test_list_ll_find_remove);
  1498     cx_test_register(suite, test_list_pll_find_remove);
  1499     cx_test_register(suite, test_list_ll_clear);
  1500     cx_test_register(suite, test_list_pll_clear);
  1501     cx_test_register(suite, test_list_ll_at);
  1502     cx_test_register(suite, test_list_pll_at);
  1503     cx_test_register(suite, test_list_ll_swap);
  1504     cx_test_register(suite, test_list_pll_swap);
  1505     cx_test_register(suite, test_list_ll_swap_no_sbo);
  1506     cx_test_register(suite, test_list_ll_find);
  1507     cx_test_register(suite, test_list_pll_find);
  1508     cx_test_register(suite, test_list_ll_sort);
  1509     cx_test_register(suite, test_list_pll_sort);
  1510     cx_test_register(suite, test_list_ll_reverse);
  1511     cx_test_register(suite, test_list_pll_reverse);
  1512     cx_test_register(suite, test_list_ll_iterator);
  1513     cx_test_register(suite, test_list_pll_iterator);
  1514     cx_test_register(suite, test_list_ll_insert_with_iterator);
  1515     cx_test_register(suite, test_list_pll_insert_with_iterator);
  1516     cx_test_register(suite, test_list_ll_compare_ll);
  1517     cx_test_register(suite, test_list_ll_compare_arl);
  1518     cx_test_register(suite, test_list_ll_compare_pll);
  1519     cx_test_register(suite, test_list_ll_compare_parl);
  1520     cx_test_register(suite, test_list_pll_compare_ll);
  1521     cx_test_register(suite, test_list_pll_compare_arl);
  1522     cx_test_register(suite, test_list_pll_compare_pll);
  1523     cx_test_register(suite, test_list_pll_compare_parl);
  1524     cx_test_register(suite, test_list_ll_simple_destr);
  1525     cx_test_register(suite, test_list_pll_simple_destr);
  1526     cx_test_register(suite, test_list_ll_advanced_destr);
  1527     cx_test_register(suite, test_list_pll_advanced_destr);
  1529     return suite;
  1532 CxTestSuite *cx_test_suite_empty_list(void) {
  1533     CxTestSuite *suite = cx_test_suite_new("empty list dummy");
  1535     cx_test_register(suite, test_empty_list_size);
  1536     cx_test_register(suite, test_empty_list_iterator);
  1537     cx_test_register(suite, test_empty_list_noops);
  1538     cx_test_register(suite, test_empty_list_at);
  1539     cx_test_register(suite, test_empty_list_find);
  1540     cx_test_register(suite, test_empty_list_compare);
  1542     return suite;

mercurial