fix name of collection base member (to avoid base.base)

Thu, 23 May 2024 20:43:04 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 May 2024 20:43:04 +0200
changeset 856
6bbbf219251d
parent 855
35bcb3216c0d
child 857
4d12e34bb130

fix name of collection base member (to avoid base.base)

src/array_list.c file | annotate | diff | comparison | revisions
src/cx/collection.h file | annotate | diff | comparison | revisions
src/cx/collection_base.h file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/cx/map.h file | annotate | diff | comparison | revisions
src/hash_map.c file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
tests/test_hash_map.c file | annotate | diff | comparison | revisions
tests/test_list.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/array_list.c	Thu May 23 20:31:37 2024 +0200
     1.2 +++ b/src/array_list.c	Thu May 23 20:43:04 2024 +0200
     1.3 @@ -191,21 +191,21 @@
     1.4  
     1.5      char *ptr = arl->data;
     1.6  
     1.7 -    if (list->base.simple_destructor) {
     1.8 -        for (size_t i = 0; i < list->base.size; i++) {
     1.9 +    if (list->collection.simple_destructor) {
    1.10 +        for (size_t i = 0; i < list->collection.size; i++) {
    1.11              cx_invoke_simple_destructor(list, ptr);
    1.12 -            ptr += list->base.elem_size;
    1.13 +            ptr += list->collection.elem_size;
    1.14          }
    1.15      }
    1.16 -    if (list->base.advanced_destructor) {
    1.17 -        for (size_t i = 0; i < list->base.size; i++) {
    1.18 +    if (list->collection.advanced_destructor) {
    1.19 +        for (size_t i = 0; i < list->collection.size; i++) {
    1.20              cx_invoke_advanced_destructor(list, ptr);
    1.21 -            ptr += list->base.elem_size;
    1.22 +            ptr += list->collection.elem_size;
    1.23          }
    1.24      }
    1.25  
    1.26 -    cxFree(list->base.allocator, arl->data);
    1.27 -    cxFree(list->base.allocator, list);
    1.28 +    cxFree(list->collection.allocator, arl->data);
    1.29 +    cxFree(list->collection.allocator, list);
    1.30  }
    1.31  
    1.32  static size_t cx_arl_insert_array(
    1.33 @@ -215,25 +215,25 @@
    1.34          size_t n
    1.35  ) {
    1.36      // out of bounds and special case check
    1.37 -    if (index > list->base.size || n == 0) return 0;
    1.38 +    if (index > list->collection.size || n == 0) return 0;
    1.39  
    1.40      // get a correctly typed pointer to the list
    1.41      cx_array_list *arl = (cx_array_list *) list;
    1.42  
    1.43      // do we need to move some elements?
    1.44 -    if (index < list->base.size) {
    1.45 +    if (index < list->collection.size) {
    1.46          char const *first_to_move = (char const *) arl->data;
    1.47 -        first_to_move += index * list->base.elem_size;
    1.48 -        size_t elems_to_move = list->base.size - index;
    1.49 +        first_to_move += index * list->collection.elem_size;
    1.50 +        size_t elems_to_move = list->collection.size - index;
    1.51          size_t start_of_moved = index + n;
    1.52  
    1.53          if (CX_ARRAY_SUCCESS != cx_array_copy(
    1.54                  &arl->data,
    1.55 -                &list->base.size,
    1.56 +                &list->collection.size,
    1.57                  &arl->capacity,
    1.58                  start_of_moved,
    1.59                  first_to_move,
    1.60 -                list->base.elem_size,
    1.61 +                list->collection.elem_size,
    1.62                  elems_to_move,
    1.63                  &arl->reallocator
    1.64          )) {
    1.65 @@ -249,11 +249,11 @@
    1.66      // place the new elements
    1.67      if (CX_ARRAY_SUCCESS == cx_array_copy(
    1.68              &arl->data,
    1.69 -            &list->base.size,
    1.70 +            &list->collection.size,
    1.71              &arl->capacity,
    1.72              index,
    1.73              array,
    1.74 -            list->base.elem_size,
    1.75 +            list->collection.elem_size,
    1.76              n,
    1.77              &arl->reallocator
    1.78      )) {
    1.79 @@ -278,7 +278,7 @@
    1.80          int prepend
    1.81  ) {
    1.82      struct cx_list_s *list = iter->src_handle.m;
    1.83 -    if (iter->index < list->base.size) {
    1.84 +    if (iter->index < list->collection.size) {
    1.85          int result = cx_arl_insert_element(
    1.86                  list,
    1.87                  iter->index + 1 - prepend,
    1.88 @@ -286,12 +286,12 @@
    1.89          );
    1.90          if (result == 0 && prepend != 0) {
    1.91              iter->index++;
    1.92 -            iter->elem_handle = ((char *) iter->elem_handle) + list->base.elem_size;
    1.93 +            iter->elem_handle = ((char *) iter->elem_handle) + list->collection.elem_size;
    1.94          }
    1.95          return result;
    1.96      } else {
    1.97 -        int result = cx_arl_insert_element(list, list->base.size, elem);
    1.98 -        iter->index = list->base.size;
    1.99 +        int result = cx_arl_insert_element(list, list->collection.size, elem);
   1.100 +        iter->index = list->collection.size;
   1.101          return result;
   1.102      }
   1.103  }
   1.104 @@ -303,28 +303,28 @@
   1.105      cx_array_list *arl = (cx_array_list *) list;
   1.106  
   1.107      // out-of-bounds check
   1.108 -    if (index >= list->base.size) {
   1.109 +    if (index >= list->collection.size) {
   1.110          return 1;
   1.111      }
   1.112  
   1.113      // content destruction
   1.114 -    cx_invoke_destructor(list, ((char *) arl->data) + index * list->base.elem_size);
   1.115 +    cx_invoke_destructor(list, ((char *) arl->data) + index * list->collection.elem_size);
   1.116  
   1.117      // short-circuit removal of last element
   1.118 -    if (index == list->base.size - 1) {
   1.119 -        list->base.size--;
   1.120 +    if (index == list->collection.size - 1) {
   1.121 +        list->collection.size--;
   1.122          return 0;
   1.123      }
   1.124  
   1.125      // just move the elements starting at index to the left
   1.126      int result = cx_array_copy(
   1.127              &arl->data,
   1.128 -            &list->base.size,
   1.129 +            &list->collection.size,
   1.130              &arl->capacity,
   1.131              index,
   1.132 -            ((char *) arl->data) + (index + 1) * list->base.elem_size,
   1.133 -            list->base.elem_size,
   1.134 -            list->base.size - index - 1,
   1.135 +            ((char *) arl->data) + (index + 1) * list->collection.elem_size,
   1.136 +            list->collection.elem_size,
   1.137 +            list->collection.size - index - 1,
   1.138              &arl->reallocator
   1.139      );
   1.140  
   1.141 @@ -332,32 +332,32 @@
   1.142      assert(result == 0);
   1.143  
   1.144      // decrease the size
   1.145 -    list->base.size--;
   1.146 +    list->collection.size--;
   1.147  
   1.148      return 0;
   1.149  }
   1.150  
   1.151  static void cx_arl_clear(struct cx_list_s *list) {
   1.152 -    if (list->base.size == 0) return;
   1.153 +    if (list->collection.size == 0) return;
   1.154  
   1.155      cx_array_list *arl = (cx_array_list *) list;
   1.156      char *ptr = arl->data;
   1.157  
   1.158 -    if (list->base.simple_destructor) {
   1.159 -        for (size_t i = 0; i < list->base.size; i++) {
   1.160 +    if (list->collection.simple_destructor) {
   1.161 +        for (size_t i = 0; i < list->collection.size; i++) {
   1.162              cx_invoke_simple_destructor(list, ptr);
   1.163 -            ptr += list->base.elem_size;
   1.164 +            ptr += list->collection.elem_size;
   1.165          }
   1.166      }
   1.167 -    if (list->base.advanced_destructor) {
   1.168 -        for (size_t i = 0; i < list->base.size; i++) {
   1.169 +    if (list->collection.advanced_destructor) {
   1.170 +        for (size_t i = 0; i < list->collection.size; i++) {
   1.171              cx_invoke_advanced_destructor(list, ptr);
   1.172 -            ptr += list->base.elem_size;
   1.173 +            ptr += list->collection.elem_size;
   1.174          }
   1.175      }
   1.176  
   1.177 -    memset(arl->data, 0, list->base.size * list->base.elem_size);
   1.178 -    list->base.size = 0;
   1.179 +    memset(arl->data, 0, list->collection.size * list->collection.elem_size);
   1.180 +    list->collection.size = 0;
   1.181  }
   1.182  
   1.183  static int cx_arl_swap(
   1.184 @@ -365,9 +365,9 @@
   1.185          size_t i,
   1.186          size_t j
   1.187  ) {
   1.188 -    if (i >= list->base.size || j >= list->base.size) return 1;
   1.189 +    if (i >= list->collection.size || j >= list->collection.size) return 1;
   1.190      cx_array_list *arl = (cx_array_list *) list;
   1.191 -    cx_array_swap(arl->data, list->base.elem_size, i, j);
   1.192 +    cx_array_swap(arl->data, list->collection.elem_size, i, j);
   1.193      return 0;
   1.194  }
   1.195  
   1.196 @@ -375,10 +375,10 @@
   1.197          struct cx_list_s const *list,
   1.198          size_t index
   1.199  ) {
   1.200 -    if (index < list->base.size) {
   1.201 +    if (index < list->collection.size) {
   1.202          cx_array_list const *arl = (cx_array_list const *) list;
   1.203          char *space = arl->data;
   1.204 -        return space + index * list->base.elem_size;
   1.205 +        return space + index * list->collection.elem_size;
   1.206      } else {
   1.207          return NULL;
   1.208      }
   1.209 @@ -389,12 +389,12 @@
   1.210          void const *elem,
   1.211          bool remove
   1.212  ) {
   1.213 -    assert(list->base.cmpfunc != NULL);
   1.214 -    assert(list->base.size < SIZE_MAX / 2);
   1.215 +    assert(list->collection.cmpfunc != NULL);
   1.216 +    assert(list->collection.size < SIZE_MAX / 2);
   1.217      char *cur = ((cx_array_list const *) list)->data;
   1.218  
   1.219 -    for (ssize_t i = 0; i < (ssize_t) list->base.size; i++) {
   1.220 -        if (0 == list->base.cmpfunc(elem, cur)) {
   1.221 +    for (ssize_t i = 0; i < (ssize_t) list->collection.size; i++) {
   1.222 +        if (0 == list->collection.cmpfunc(elem, cur)) {
   1.223              if (remove) {
   1.224                  if (0 == cx_arl_remove(list, i)) {
   1.225                      return i;
   1.226 @@ -405,18 +405,18 @@
   1.227                  return i;
   1.228              }
   1.229          }
   1.230 -        cur += list->base.elem_size;
   1.231 +        cur += list->collection.elem_size;
   1.232      }
   1.233  
   1.234      return -1;
   1.235  }
   1.236  
   1.237  static void cx_arl_sort(struct cx_list_s *list) {
   1.238 -    assert(list->base.cmpfunc != NULL);
   1.239 +    assert(list->collection.cmpfunc != NULL);
   1.240      qsort(((cx_array_list *) list)->data,
   1.241 -          list->base.size,
   1.242 -          list->base.elem_size,
   1.243 -          list->base.cmpfunc
   1.244 +          list->collection.size,
   1.245 +          list->collection.elem_size,
   1.246 +          list->collection.cmpfunc
   1.247      );
   1.248  }
   1.249  
   1.250 @@ -424,37 +424,37 @@
   1.251          struct cx_list_s const *list,
   1.252          struct cx_list_s const *other
   1.253  ) {
   1.254 -    assert(list->base.cmpfunc != NULL);
   1.255 -    if (list->base.size == other->base.size) {
   1.256 +    assert(list->collection.cmpfunc != NULL);
   1.257 +    if (list->collection.size == other->collection.size) {
   1.258          char const *left = ((cx_array_list const *) list)->data;
   1.259          char const *right = ((cx_array_list const *) other)->data;
   1.260 -        for (size_t i = 0; i < list->base.size; i++) {
   1.261 -            int d = list->base.cmpfunc(left, right);
   1.262 +        for (size_t i = 0; i < list->collection.size; i++) {
   1.263 +            int d = list->collection.cmpfunc(left, right);
   1.264              if (d != 0) {
   1.265                  return d;
   1.266              }
   1.267 -            left += list->base.elem_size;
   1.268 -            right += other->base.elem_size;
   1.269 +            left += list->collection.elem_size;
   1.270 +            right += other->collection.elem_size;
   1.271          }
   1.272          return 0;
   1.273      } else {
   1.274 -        return list->base.size < other->base.size ? -1 : 1;
   1.275 +        return list->collection.size < other->collection.size ? -1 : 1;
   1.276      }
   1.277  }
   1.278  
   1.279  static void cx_arl_reverse(struct cx_list_s *list) {
   1.280 -    if (list->base.size < 2) return;
   1.281 +    if (list->collection.size < 2) return;
   1.282      void *data = ((cx_array_list const *) list)->data;
   1.283 -    size_t half = list->base.size / 2;
   1.284 +    size_t half = list->collection.size / 2;
   1.285      for (size_t i = 0; i < half; i++) {
   1.286 -        cx_array_swap(data, list->base.elem_size, i, list->base.size - 1 - i);
   1.287 +        cx_array_swap(data, list->collection.elem_size, i, list->collection.size - 1 - i);
   1.288      }
   1.289  }
   1.290  
   1.291  static bool cx_arl_iter_valid(void const *it) {
   1.292      struct cx_iterator_s const *iter = it;
   1.293      struct cx_list_s const *list = iter->src_handle.c;
   1.294 -    return iter->index < list->base.size;
   1.295 +    return iter->index < list->collection.size;
   1.296  }
   1.297  
   1.298  static void *cx_arl_iter_current(void const *it) {
   1.299 @@ -471,7 +471,7 @@
   1.300          iter->index++;
   1.301          iter->elem_handle =
   1.302                  ((char *) iter->elem_handle)
   1.303 -                + ((struct cx_list_s const *) iter->src_handle.c)->base.elem_size;
   1.304 +                + ((struct cx_list_s const *) iter->src_handle.c)->collection.elem_size;
   1.305      }
   1.306  }
   1.307  
   1.308 @@ -483,9 +483,9 @@
   1.309          cx_arl_remove(iter->src_handle.m, iter->index);
   1.310      }
   1.311      iter->index--;
   1.312 -    if (iter->index < list->base.base.size) {
   1.313 +    if (iter->index < list->base.collection.size) {
   1.314          iter->elem_handle = ((char *) list->data)
   1.315 -                            + iter->index * list->base.base.elem_size;
   1.316 +                            + iter->index * list->base.collection.elem_size;
   1.317      }
   1.318  }
   1.319  
   1.320 @@ -500,8 +500,8 @@
   1.321      iter.index = index;
   1.322      iter.src_handle.c = list;
   1.323      iter.elem_handle = cx_arl_at(list, index);
   1.324 -    iter.elem_size = list->base.elem_size;
   1.325 -    iter.elem_count = list->base.size;
   1.326 +    iter.elem_size = list->collection.elem_size;
   1.327 +    iter.elem_count = list->collection.size;
   1.328      iter.base.valid = cx_arl_iter_valid;
   1.329      iter.base.current = cx_arl_iter_current;
   1.330      iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next;
   1.331 @@ -541,15 +541,15 @@
   1.332      if (list == NULL) return NULL;
   1.333  
   1.334      list->base.cl = &cx_array_list_class;
   1.335 -    list->base.base.allocator = allocator;
   1.336 +    list->base.collection.allocator = allocator;
   1.337      list->capacity = initial_capacity;
   1.338  
   1.339      if (elem_size > 0) {
   1.340 -        list->base.base.elem_size = elem_size;
   1.341 -        list->base.base.cmpfunc = comparator;
   1.342 +        list->base.collection.elem_size = elem_size;
   1.343 +        list->base.collection.cmpfunc = comparator;
   1.344      } else {
   1.345          elem_size = sizeof(void *);
   1.346 -        list->base.base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
   1.347 +        list->base.collection.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
   1.348          cxListStorePointers((CxList *) list);
   1.349      }
   1.350  
     2.1 --- a/src/cx/collection.h	Thu May 23 20:31:37 2024 +0200
     2.2 +++ b/src/cx/collection.h	Thu May 23 20:43:04 2024 +0200
     2.3 @@ -97,7 +97,7 @@
     2.4  /**
     2.5   * Use this macro to declare common members for a collection structure.
     2.6   */
     2.7 -#define CX_COLLECTION_BASE struct cx_collection_s base
     2.8 +#define CX_COLLECTION_BASE struct cx_collection_s collection
     2.9  
    2.10  /**
    2.11   * Invokes the simple destructor function for a specific element.
    2.12 @@ -109,7 +109,7 @@
    2.13   * @param e the element
    2.14   */
    2.15  #define cx_invoke_simple_destructor(c, e) \
    2.16 -    (c)->base.simple_destructor((c)->base.store_pointer ? (*((void **) (e))) : (e))
    2.17 +    (c)->collection.simple_destructor((c)->collection.store_pointer ? (*((void **) (e))) : (e))
    2.18  
    2.19  /**
    2.20   * Invokes the advanced destructor function for a specific element.
    2.21 @@ -121,8 +121,8 @@
    2.22   * @param e the element
    2.23   */
    2.24  #define cx_invoke_advanced_destructor(c, e) \
    2.25 -    (c)->base.advanced_destructor((c)->base.destructor_data, \
    2.26 -    (c)->base.store_pointer ? (*((void **) (e))) : (e))
    2.27 +    (c)->collection.advanced_destructor((c)->collection.destructor_data, \
    2.28 +    (c)->collection.store_pointer ? (*((void **) (e))) : (e))
    2.29  
    2.30  
    2.31  /**
    2.32 @@ -135,8 +135,8 @@
    2.33   * @param e the element
    2.34   */
    2.35  #define cx_invoke_destructor(c, e) \
    2.36 -    if ((c)->base.simple_destructor) cx_invoke_simple_destructor(c,e); \
    2.37 -    if ((c)->base.advanced_destructor) cx_invoke_advanced_destructor(c,e)
    2.38 +    if ((c)->collection.simple_destructor) cx_invoke_simple_destructor(c,e); \
    2.39 +    if ((c)->collection.advanced_destructor) cx_invoke_advanced_destructor(c,e)
    2.40  
    2.41  #ifdef __cplusplus
    2.42  } // extern "C"
     3.1 --- a/src/cx/collection_base.h	Thu May 23 20:31:37 2024 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,35 +0,0 @@
     3.4 -/*
     3.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 - *
     3.7 - * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
     3.8 - *
     3.9 - * Redistribution and use in source and binary forms, with or without
    3.10 - * modification, are permitted provided that the following conditions are met:
    3.11 - *
    3.12 - *   1. Redistributions of source code must retain the above copyright
    3.13 - *      notice, this list of conditions and the following disclaimer.
    3.14 - *
    3.15 - *   2. Redistributions in binary form must reproduce the above copyright
    3.16 - *      notice, this list of conditions and the following disclaimer in the
    3.17 - *      documentation and/or other materials provided with the distribution.
    3.18 - *
    3.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    3.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    3.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    3.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    3.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    3.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    3.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    3.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    3.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.29 - * POSSIBILITY OF SUCH DAMAGE.
    3.30 - */
    3.31 -/**
    3.32 - * \file collection_base.h
    3.33 - * \brief Include this file in your collection struct to declare common members.
    3.34 - * \author Mike Becker
    3.35 - * \author Olaf Wintermann
    3.36 - * \copyright 2-Clause BSD License
    3.37 - */
    3.38 -
     4.1 --- a/src/cx/list.h	Thu May 23 20:31:37 2024 +0200
     4.2 +++ b/src/cx/list.h	Thu May 23 20:43:04 2024 +0200
     4.3 @@ -213,7 +213,7 @@
     4.4   */
     4.5  __attribute__((__nonnull__))
     4.6  static inline bool cxListIsStoringPointers(CxList const *list) {
     4.7 -    return list->base.store_pointer;
     4.8 +    return list->collection.store_pointer;
     4.9  }
    4.10  
    4.11  /**
    4.12 @@ -224,7 +224,7 @@
    4.13   */
    4.14  __attribute__((__nonnull__))
    4.15  static inline size_t cxListSize(CxList const *list) {
    4.16 -    return list->base.size;
    4.17 +    return list->collection.size;
    4.18  }
    4.19  
    4.20  /**
    4.21 @@ -240,7 +240,7 @@
    4.22          CxList *list,
    4.23          void const *elem
    4.24  ) {
    4.25 -    return list->cl->insert_element(list, list->base.size, elem);
    4.26 +    return list->cl->insert_element(list, list->collection.size, elem);
    4.27  }
    4.28  
    4.29  /**
    4.30 @@ -265,7 +265,7 @@
    4.31          void const *array,
    4.32          size_t n
    4.33  ) {
    4.34 -    return list->cl->insert_array(list, list->base.size, array, n);
    4.35 +    return list->cl->insert_array(list, list->collection.size, array, n);
    4.36  }
    4.37  
    4.38  /**
    4.39 @@ -547,7 +547,7 @@
    4.40   */
    4.41  __attribute__((__nonnull__, __warn_unused_result__))
    4.42  static inline CxIterator cxListBackwardsIterator(CxList const *list) {
    4.43 -    return list->cl->iterator(list, list->base.size - 1, true);
    4.44 +    return list->cl->iterator(list, list->collection.size - 1, true);
    4.45  }
    4.46  
    4.47  /**
    4.48 @@ -562,7 +562,7 @@
    4.49   */
    4.50  __attribute__((__nonnull__, __warn_unused_result__))
    4.51  static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
    4.52 -    return cxListMutBackwardsIteratorAt(list, list->base.size - 1);
    4.53 +    return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
    4.54  }
    4.55  
    4.56  /**
     5.1 --- a/src/cx/map.h	Thu May 23 20:31:37 2024 +0200
     5.2 +++ b/src/cx/map.h	Thu May 23 20:43:04 2024 +0200
     5.3 @@ -166,7 +166,7 @@
     5.4   */
     5.5  __attribute__((__nonnull__))
     5.6  static inline void cxMapStoreObjects(CxMap *map) {
     5.7 -    map->base.store_pointer = false;
     5.8 +    map->collection.store_pointer = false;
     5.9  }
    5.10  
    5.11  /**
    5.12 @@ -183,8 +183,8 @@
    5.13   */
    5.14  __attribute__((__nonnull__))
    5.15  static inline void cxMapStorePointers(CxMap *map) {
    5.16 -    map->base.store_pointer = true;
    5.17 -    map->base.elem_size = sizeof(void *);
    5.18 +    map->collection.store_pointer = true;
    5.19 +    map->collection.elem_size = sizeof(void *);
    5.20  }
    5.21  
    5.22  
    5.23 @@ -209,6 +209,17 @@
    5.24      map->cl->clear(map);
    5.25  }
    5.26  
    5.27 +/**
    5.28 + * Returns the number of elements in this map.
    5.29 + *
    5.30 + * @param map the map
    5.31 + * @return the number of stored elements
    5.32 + */
    5.33 +__attribute__((__nonnull__))
    5.34 +static inline size_t cxMapSize(CxMap const *map) {
    5.35 +    return map->collection.size;
    5.36 +}
    5.37 +
    5.38  
    5.39  // TODO: set-like map operations (union, intersect, difference)
    5.40  
    5.41 @@ -1053,7 +1064,7 @@
    5.42          CxMap *map,
    5.43          CxHashKey key
    5.44  ) {
    5.45 -    return map->cl->remove(map, key, !map->base.store_pointer);
    5.46 +    return map->cl->remove(map, key, !map->collection.store_pointer);
    5.47  }
    5.48  
    5.49  /**
    5.50 @@ -1069,7 +1080,7 @@
    5.51          CxMap *map,
    5.52          cxstring key
    5.53  ) {
    5.54 -    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
    5.55 +    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
    5.56  }
    5.57  
    5.58  /**
    5.59 @@ -1085,7 +1096,7 @@
    5.60          CxMap *map,
    5.61          cxmutstr key
    5.62  ) {
    5.63 -    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
    5.64 +    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
    5.65  }
    5.66  
    5.67  /**
    5.68 @@ -1101,7 +1112,7 @@
    5.69          CxMap *map,
    5.70          char const *key
    5.71  ) {
    5.72 -    return map->cl->remove(map, cx_hash_key_str(key), !map->base.store_pointer);
    5.73 +    return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
    5.74  }
    5.75  
    5.76  /**
     6.1 --- a/src/hash_map.c	Thu May 23 20:31:37 2024 +0200
     6.2 +++ b/src/hash_map.c	Thu May 23 20:43:04 2024 +0200
     6.3 @@ -53,9 +53,9 @@
     6.4                  // invoke the destructor
     6.5                  cx_invoke_destructor(map, elem->data);
     6.6                  // free the key data
     6.7 -                cxFree(map->base.allocator, (void *) elem->key.data);
     6.8 +                cxFree(map->collection.allocator, (void *) elem->key.data);
     6.9                  // free the node
    6.10 -                cxFree(map->base.allocator, elem);
    6.11 +                cxFree(map->collection.allocator, elem);
    6.12                  // proceed
    6.13                  elem = next;
    6.14              } while (elem != NULL);
    6.15 @@ -64,7 +64,7 @@
    6.16              hash_map->buckets[i] = NULL;
    6.17          }
    6.18      }
    6.19 -    map->base.size = 0;
    6.20 +    map->collection.size = 0;
    6.21  }
    6.22  
    6.23  static void cx_hash_map_destructor(struct cx_map_s *map) {
    6.24 @@ -72,10 +72,10 @@
    6.25  
    6.26      // free the buckets
    6.27      cx_hash_map_clear(map);
    6.28 -    cxFree(map->base.allocator, hash_map->buckets);
    6.29 +    cxFree(map->collection.allocator, hash_map->buckets);
    6.30  
    6.31      // free the map structure
    6.32 -    cxFree(map->base.allocator, map);
    6.33 +    cxFree(map->collection.allocator, map);
    6.34  }
    6.35  
    6.36  static int cx_hash_map_put(
    6.37 @@ -84,7 +84,7 @@
    6.38          void *value
    6.39  ) {
    6.40      struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
    6.41 -    CxAllocator const *allocator = map->base.allocator;
    6.42 +    CxAllocator const *allocator = map->collection.allocator;
    6.43  
    6.44      unsigned hash = key.hash;
    6.45      if (hash == 0) {
    6.46 @@ -104,26 +104,26 @@
    6.47      if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len &&
    6.48          memcmp(elm->key.data, key.data, key.len) == 0) {
    6.49          // overwrite existing element
    6.50 -        if (map->base.store_pointer) {
    6.51 +        if (map->collection.store_pointer) {
    6.52              memcpy(elm->data, &value, sizeof(void *));
    6.53          } else {
    6.54 -            memcpy(elm->data, value, map->base.elem_size);
    6.55 +            memcpy(elm->data, value, map->collection.elem_size);
    6.56          }
    6.57      } else {
    6.58          // allocate new element
    6.59          struct cx_hash_map_element_s *e = cxMalloc(
    6.60                  allocator,
    6.61 -                sizeof(struct cx_hash_map_element_s) + map->base.elem_size
    6.62 +                sizeof(struct cx_hash_map_element_s) + map->collection.elem_size
    6.63          );
    6.64          if (e == NULL) {
    6.65              return -1;
    6.66          }
    6.67  
    6.68          // write the value
    6.69 -        if (map->base.store_pointer) {
    6.70 +        if (map->collection.store_pointer) {
    6.71              memcpy(e->data, &value, sizeof(void *));
    6.72          } else {
    6.73 -            memcpy(e->data, value, map->base.elem_size);
    6.74 +            memcpy(e->data, value, map->collection.elem_size);
    6.75          }
    6.76  
    6.77          // copy the key
    6.78 @@ -145,7 +145,7 @@
    6.79          e->next = elm;
    6.80  
    6.81          // increase the size
    6.82 -        map->base.size++;
    6.83 +        map->collection.size++;
    6.84      }
    6.85  
    6.86      return 0;
    6.87 @@ -164,10 +164,10 @@
    6.88          prev->next = elm->next;
    6.89      }
    6.90      // free element
    6.91 -    cxFree(hash_map->base.base.allocator, (void *) elm->key.data);
    6.92 -    cxFree(hash_map->base.base.allocator, elm);
    6.93 +    cxFree(hash_map->base.collection.allocator, (void *) elm->key.data);
    6.94 +    cxFree(hash_map->base.collection.allocator, elm);
    6.95      // decrease size
    6.96 -    hash_map->base.base.size--;
    6.97 +    hash_map->base.collection.size--;
    6.98  }
    6.99  
   6.100  /**
   6.101 @@ -203,7 +203,7 @@
   6.102                  if (destroy) {
   6.103                      cx_invoke_destructor(map, elm->data);
   6.104                  } else {
   6.105 -                    if (map->base.store_pointer) {
   6.106 +                    if (map->collection.store_pointer) {
   6.107                          data = *(void **) elm->data;
   6.108                      } else {
   6.109                          data = elm->data;
   6.110 @@ -254,7 +254,7 @@
   6.111      struct cx_iterator_s const *iter = it;
   6.112      struct cx_hash_map_s const *map = iter->src_handle.c;
   6.113      struct cx_hash_map_element_s *elm = iter->elem_handle;
   6.114 -    if (map->base.base.store_pointer) {
   6.115 +    if (map->base.collection.store_pointer) {
   6.116          return *(void **) elm->data;
   6.117      } else {
   6.118          return elm->data;
   6.119 @@ -315,7 +315,7 @@
   6.120          iter->kv_data.value = NULL;
   6.121      } else {
   6.122          iter->kv_data.key = &elm->key;
   6.123 -        if (map->base.base.store_pointer) {
   6.124 +        if (map->base.collection.store_pointer) {
   6.125              iter->kv_data.value = *(void **) elm->data;
   6.126          } else {
   6.127              iter->kv_data.value = elm->data;
   6.128 @@ -330,7 +330,7 @@
   6.129      CxIterator iter;
   6.130  
   6.131      iter.src_handle.c = map;
   6.132 -    iter.elem_count = map->base.size;
   6.133 +    iter.elem_count = map->collection.size;
   6.134  
   6.135      switch (type) {
   6.136          case CX_MAP_ITERATOR_PAIRS:
   6.137 @@ -342,7 +342,7 @@
   6.138              iter.base.current = cx_hash_map_iter_current_key;
   6.139              break;
   6.140          case CX_MAP_ITERATOR_VALUES:
   6.141 -            iter.elem_size = map->base.elem_size;
   6.142 +            iter.elem_size = map->collection.elem_size;
   6.143              iter.base.current = cx_hash_map_iter_current_value;
   6.144              break;
   6.145          default:
   6.146 @@ -357,7 +357,7 @@
   6.147      iter.slot = 0;
   6.148      iter.index = 0;
   6.149  
   6.150 -    if (map->base.size > 0) {
   6.151 +    if (map->collection.size > 0) {
   6.152          struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
   6.153          struct cx_hash_map_element_s *elm = hash_map->buckets[0];
   6.154          while (elm == NULL) {
   6.155 @@ -365,7 +365,7 @@
   6.156          }
   6.157          iter.elem_handle = elm;
   6.158          iter.kv_data.key = &elm->key;
   6.159 -        if (map->base.store_pointer) {
   6.160 +        if (map->collection.store_pointer) {
   6.161              iter.kv_data.value = *(void **) elm->data;
   6.162          } else {
   6.163              iter.kv_data.value = elm->data;
   6.164 @@ -413,14 +413,14 @@
   6.165  
   6.166      // initialize base members
   6.167      map->base.cl = &cx_hash_map_class;
   6.168 -    map->base.base.allocator = allocator;
   6.169 +    map->base.collection.allocator = allocator;
   6.170  
   6.171      if (itemsize > 0) {
   6.172 -        map->base.base.store_pointer = false;
   6.173 -        map->base.base.elem_size = itemsize;
   6.174 +        map->base.collection.store_pointer = false;
   6.175 +        map->base.collection.elem_size = itemsize;
   6.176      } else {
   6.177 -        map->base.base.store_pointer = true;
   6.178 -        map->base.base.elem_size = sizeof(void *);
   6.179 +        map->base.collection.store_pointer = true;
   6.180 +        map->base.collection.elem_size = sizeof(void *);
   6.181      }
   6.182  
   6.183      return (CxMap *) map;
   6.184 @@ -428,11 +428,11 @@
   6.185  
   6.186  int cxMapRehash(CxMap *map) {
   6.187      struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
   6.188 -    if (map->base.size > ((hash_map->bucket_count * 3) >> 2)) {
   6.189 +    if (map->collection.size > ((hash_map->bucket_count * 3) >> 2)) {
   6.190  
   6.191 -        size_t new_bucket_count = (map->base.size * 5) >> 1;
   6.192 +        size_t new_bucket_count = (map->collection.size * 5) >> 1;
   6.193          struct cx_hash_map_element_s **new_buckets = cxCalloc(
   6.194 -                map->base.allocator,
   6.195 +                map->collection.allocator,
   6.196                  new_bucket_count, sizeof(struct cx_hash_map_element_s *)
   6.197          );
   6.198  
   6.199 @@ -472,7 +472,7 @@
   6.200  
   6.201          // assign result to the map
   6.202          hash_map->bucket_count = new_bucket_count;
   6.203 -        cxFree(map->base.allocator, hash_map->buckets);
   6.204 +        cxFree(map->collection.allocator, hash_map->buckets);
   6.205          hash_map->buckets = new_buckets;
   6.206      }
   6.207      return 0;
     7.1 --- a/src/linked_list.c	Thu May 23 20:31:37 2024 +0200
     7.2 +++ b/src/linked_list.c	Thu May 23 20:43:04 2024 +0200
     7.3 @@ -501,10 +501,10 @@
     7.4          cx_linked_list const *list,
     7.5          size_t index
     7.6  ) {
     7.7 -    if (index >= list->base.base.size) {
     7.8 +    if (index >= list->base.collection.size) {
     7.9          return NULL;
    7.10 -    } else if (index > list->base.base.size / 2) {
    7.11 -        return cx_linked_list_at(list->end, list->base.base.size - 1, CX_LL_LOC_PREV, index);
    7.12 +    } else if (index > list->base.collection.size / 2) {
    7.13 +        return cx_linked_list_at(list->end, list->base.collection.size - 1, CX_LL_LOC_PREV, index);
    7.14      } else {
    7.15          return cx_linked_list_at(list->begin, 0, CX_LL_LOC_NEXT, index);
    7.16      }
    7.17 @@ -517,15 +517,15 @@
    7.18  ) {
    7.19  
    7.20      // create the new new_node
    7.21 -    cx_linked_list_node *new_node = cxMalloc(list->base.allocator,
    7.22 -                                             sizeof(cx_linked_list_node) + list->base.elem_size);
    7.23 +    cx_linked_list_node *new_node = cxMalloc(list->collection.allocator,
    7.24 +                                             sizeof(cx_linked_list_node) + list->collection.elem_size);
    7.25  
    7.26      // sortir if failed
    7.27      if (new_node == NULL) return 1;
    7.28  
    7.29      // initialize new new_node
    7.30      new_node->prev = new_node->next = NULL;
    7.31 -    memcpy(new_node->payload, elem, list->base.elem_size);
    7.32 +    memcpy(new_node->payload, elem, list->collection.elem_size);
    7.33  
    7.34      // insert
    7.35      cx_linked_list *ll = (cx_linked_list *) list;
    7.36 @@ -536,7 +536,7 @@
    7.37      );
    7.38  
    7.39      // increase the size and return
    7.40 -    list->base.size++;
    7.41 +    list->collection.size++;
    7.42      return 0;
    7.43  }
    7.44  
    7.45 @@ -547,7 +547,7 @@
    7.46          size_t n
    7.47  ) {
    7.48      // out-of bounds and corner case check
    7.49 -    if (index > list->base.size || n == 0) return 0;
    7.50 +    if (index > list->collection.size || n == 0) return 0;
    7.51  
    7.52      // find position efficiently
    7.53      cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
    7.54 @@ -566,7 +566,7 @@
    7.55      // we can add the remaining nodes and immedately advance to the inserted node
    7.56      char const *source = array;
    7.57      for (size_t i = 1; i < n; i++) {
    7.58 -        source += list->base.elem_size;
    7.59 +        source += list->collection.elem_size;
    7.60          if (0 != cx_ll_insert_at(list, node, source)) {
    7.61              return i;
    7.62          }
    7.63 @@ -601,27 +601,27 @@
    7.64                            CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
    7.65  
    7.66      // adjust size
    7.67 -    list->base.size--;
    7.68 +    list->collection.size--;
    7.69  
    7.70      // free and return
    7.71 -    cxFree(list->base.allocator, node);
    7.72 +    cxFree(list->collection.allocator, node);
    7.73  
    7.74      return 0;
    7.75  }
    7.76  
    7.77  static void cx_ll_clear(struct cx_list_s *list) {
    7.78 -    if (list->base.size == 0) return;
    7.79 +    if (list->collection.size == 0) return;
    7.80  
    7.81      cx_linked_list *ll = (cx_linked_list *) list;
    7.82      cx_linked_list_node *node = ll->begin;
    7.83      while (node != NULL) {
    7.84          cx_invoke_destructor(list, node->payload);
    7.85          cx_linked_list_node *next = node->next;
    7.86 -        cxFree(list->base.allocator, node);
    7.87 +        cxFree(list->collection.allocator, node);
    7.88          node = next;
    7.89      }
    7.90      ll->begin = ll->end = NULL;
    7.91 -    list->base.size = 0;
    7.92 +    list->collection.size = 0;
    7.93  }
    7.94  
    7.95  #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE
    7.96 @@ -634,12 +634,12 @@
    7.97          size_t i,
    7.98          size_t j
    7.99  ) {
   7.100 -    if (i >= list->base.size || j >= list->base.size) return 1;
   7.101 +    if (i >= list->collection.size || j >= list->collection.size) return 1;
   7.102      if (i == j) return 0;
   7.103  
   7.104      // perform an optimized search that finds both elements in one run
   7.105      cx_linked_list *ll = (cx_linked_list *) list;
   7.106 -    size_t mid = list->base.size / 2;
   7.107 +    size_t mid = list->collection.size / 2;
   7.108      size_t left, right;
   7.109      if (i < j) {
   7.110          left = i;
   7.111 @@ -671,7 +671,7 @@
   7.112          // chose the closest to begin / end
   7.113          size_t closest;
   7.114          size_t other;
   7.115 -        size_t diff2boundary = list->base.size - right - 1;
   7.116 +        size_t diff2boundary = list->collection.size - right - 1;
   7.117          if (left <= diff2boundary) {
   7.118              closest = left;
   7.119              other = right;
   7.120 @@ -707,7 +707,7 @@
   7.121          }
   7.122      }
   7.123  
   7.124 -    if (list->base.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) {
   7.125 +    if (list->collection.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) {
   7.126          cx_linked_list_node *prev = nleft->prev;
   7.127          cx_linked_list_node *next = nright->next;
   7.128          cx_linked_list_node *midstart = nleft->next;
   7.129 @@ -739,9 +739,9 @@
   7.130      } else {
   7.131          // swap payloads to avoid relinking
   7.132          char buf[CX_LINKED_LIST_SWAP_SBO_SIZE];
   7.133 -        memcpy(buf, nleft->payload, list->base.elem_size);
   7.134 -        memcpy(nleft->payload, nright->payload, list->base.elem_size);
   7.135 -        memcpy(nright->payload, buf, list->base.elem_size);
   7.136 +        memcpy(buf, nleft->payload, list->collection.elem_size);
   7.137 +        memcpy(nleft->payload, nright->payload, list->collection.elem_size);
   7.138 +        memcpy(nright->payload, buf, list->collection.elem_size);
   7.139      }
   7.140  
   7.141      return 0;
   7.142 @@ -768,21 +768,21 @@
   7.143                  (void **) &node,
   7.144                  ll->begin,
   7.145                  CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
   7.146 -                list->base.cmpfunc, elem
   7.147 +                list->collection.cmpfunc, elem
   7.148          );
   7.149          if (node != NULL) {
   7.150              cx_invoke_destructor(list, node->payload);
   7.151              cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
   7.152                                    CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
   7.153 -            list->base.size--;
   7.154 -            cxFree(list->base.allocator, node);
   7.155 +            list->collection.size--;
   7.156 +            cxFree(list->collection.allocator, node);
   7.157          }
   7.158          return index;
   7.159      } else {
   7.160          return cx_linked_list_find(
   7.161                  ((cx_linked_list *) list)->begin,
   7.162                  CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
   7.163 -                list->base.cmpfunc, elem
   7.164 +                list->collection.cmpfunc, elem
   7.165          );
   7.166      }
   7.167  }
   7.168 @@ -791,7 +791,7 @@
   7.169      cx_linked_list *ll = (cx_linked_list *) list;
   7.170      cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end,
   7.171                          CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
   7.172 -                        list->base.cmpfunc);
   7.173 +                        list->collection.cmpfunc);
   7.174  }
   7.175  
   7.176  static void cx_ll_reverse(struct cx_list_s *list) {
   7.177 @@ -807,7 +807,7 @@
   7.178      cx_linked_list *right = (cx_linked_list *) other;
   7.179      return cx_linked_list_compare(left->begin, right->begin,
   7.180                                    CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
   7.181 -                                  list->base.cmpfunc);
   7.182 +                                  list->collection.cmpfunc);
   7.183  }
   7.184  
   7.185  static bool cx_ll_iter_valid(void const *it) {
   7.186 @@ -826,8 +826,8 @@
   7.187          cx_invoke_destructor(list, node->payload);
   7.188          cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
   7.189                                CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
   7.190 -        list->base.size--;
   7.191 -        cxFree(list->base.allocator, node);
   7.192 +        list->collection.size--;
   7.193 +        cxFree(list->collection.allocator, node);
   7.194      } else {
   7.195          iter->index++;
   7.196          cx_linked_list_node *node = iter->elem_handle;
   7.197 @@ -847,8 +847,8 @@
   7.198          cx_invoke_destructor(list, node->payload);
   7.199          cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
   7.200                                CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
   7.201 -        list->base.size--;
   7.202 -        cxFree(list->base.allocator, node);
   7.203 +        list->collection.size--;
   7.204 +        cxFree(list->collection.allocator, node);
   7.205      } else {
   7.206          iter->index--;
   7.207          cx_linked_list_node *node = iter->elem_handle;
   7.208 @@ -871,8 +871,8 @@
   7.209      iter.index = index;
   7.210      iter.src_handle.c = list;
   7.211      iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index);
   7.212 -    iter.elem_size = list->base.elem_size;
   7.213 -    iter.elem_count = list->base.size;
   7.214 +    iter.elem_size = list->collection.elem_size;
   7.215 +    iter.elem_count = list->collection.size;
   7.216      iter.base.valid = cx_ll_iter_valid;
   7.217      iter.base.current = cx_ll_iter_current;
   7.218      iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next;
   7.219 @@ -895,8 +895,8 @@
   7.220          iter->index += prepend * (0 == result);
   7.221          return result;
   7.222      } else {
   7.223 -        int result = cx_ll_insert_element(list, list->base.size, elem);
   7.224 -        iter->index = list->base.size;
   7.225 +        int result = cx_ll_insert_element(list, list->collection.size, elem);
   7.226 +        iter->index = list->collection.size;
   7.227          return result;
   7.228      }
   7.229  }
   7.230 @@ -908,11 +908,11 @@
   7.231      while (node) {
   7.232          cx_invoke_destructor(list, node->payload);
   7.233          void *next = node->next;
   7.234 -        cxFree(list->base.allocator, node);
   7.235 +        cxFree(list->collection.allocator, node);
   7.236          node = next;
   7.237      }
   7.238  
   7.239 -    cxFree(list->base.allocator, list);
   7.240 +    cxFree(list->collection.allocator, list);
   7.241  }
   7.242  
   7.243  static cx_list_class cx_linked_list_class = {
   7.244 @@ -944,13 +944,13 @@
   7.245      if (list == NULL) return NULL;
   7.246  
   7.247      list->base.cl = &cx_linked_list_class;
   7.248 -    list->base.base.allocator = allocator;
   7.249 +    list->base.collection.allocator = allocator;
   7.250  
   7.251      if (elem_size > 0) {
   7.252 -        list->base.base.elem_size = elem_size;
   7.253 -        list->base.base.cmpfunc = comparator;
   7.254 +        list->base.collection.elem_size = elem_size;
   7.255 +        list->base.collection.cmpfunc = comparator;
   7.256      } else {
   7.257 -        list->base.base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
   7.258 +        list->base.collection.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
   7.259          cxListStorePointers((CxList *) list);
   7.260      }
   7.261  
     8.1 --- a/src/list.c	Thu May 23 20:31:37 2024 +0200
     8.2 +++ b/src/list.c	Thu May 23 20:43:04 2024 +0200
     8.3 @@ -47,14 +47,14 @@
     8.4  
     8.5  static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) {
     8.6      // cast away const - this is the hacky thing
     8.7 -    struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
     8.8 +    struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
     8.9      cx_pl_cmpfunc_impl = l->cmpfunc;
    8.10      l->cmpfunc = cx_pl_cmpfunc;
    8.11  }
    8.12  
    8.13  static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) {
    8.14      // cast away const - this is the hacky thing
    8.15 -    struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
    8.16 +    struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
    8.17      l->cmpfunc = cx_pl_cmpfunc_impl;
    8.18  }
    8.19  
    8.20 @@ -180,7 +180,7 @@
    8.21  };
    8.22  
    8.23  void cxListStoreObjects(CxList *list) {
    8.24 -    list->base.store_pointer = false;
    8.25 +    list->collection.store_pointer = false;
    8.26      if (list->climpl != NULL) {
    8.27          list->cl = list->climpl;
    8.28          list->climpl = NULL;
    8.29 @@ -188,8 +188,8 @@
    8.30  }
    8.31  
    8.32  void cxListStorePointers(CxList *list) {
    8.33 -    list->base.elem_size = sizeof(void *);
    8.34 -    list->base.store_pointer = true;
    8.35 +    list->collection.elem_size = sizeof(void *);
    8.36 +    list->collection.store_pointer = true;
    8.37      list->climpl = list->cl;
    8.38      list->cl = &cx_pointer_list_class;
    8.39  }
    8.40 @@ -221,7 +221,7 @@
    8.41          __attribute__((__unused__)) struct cx_list_s const *list,
    8.42          struct cx_list_s const *other
    8.43  ) {
    8.44 -    if (other->base.size == 0) return 0;
    8.45 +    if (other->collection.size == 0) return 0;
    8.46      return -1;
    8.47  }
    8.48  
    8.49 @@ -286,7 +286,7 @@
    8.50  ) {
    8.51      if (
    8.52          // if one is storing pointers but the other is not
    8.53 -        (list->base.store_pointer ^ other->base.store_pointer) ||
    8.54 +        (list->collection.store_pointer ^ other->collection.store_pointer) ||
    8.55  
    8.56          // if one class is wrapped but the other is not
    8.57          ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
    8.58 @@ -296,13 +296,13 @@
    8.59           (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
    8.60      ) {
    8.61          // lists are definitely different - cannot use internal compare function
    8.62 -        if (list->base.size == other->base.size) {
    8.63 +        if (list->collection.size == other->collection.size) {
    8.64              CxIterator left = list->cl->iterator(list, 0, false);
    8.65              CxIterator right = other->cl->iterator(other, 0, false);
    8.66 -            for (size_t i = 0; i < list->base.size; i++) {
    8.67 +            for (size_t i = 0; i < list->collection.size; i++) {
    8.68                  void *leftValue = cxIteratorCurrent(left);
    8.69                  void *rightValue = cxIteratorCurrent(right);
    8.70 -                int d = list->base.cmpfunc(leftValue, rightValue);
    8.71 +                int d = list->collection.cmpfunc(leftValue, rightValue);
    8.72                  if (d != 0) {
    8.73                      return d;
    8.74                  }
    8.75 @@ -311,7 +311,7 @@
    8.76              }
    8.77              return 0;
    8.78          } else {
    8.79 -            return list->base.size < other->base.size ? -1 : 1;
    8.80 +            return list->collection.size < other->collection.size ? -1 : 1;
    8.81          }
    8.82      } else {
    8.83          // lists are compatible
     9.1 --- a/tests/test_hash_map.c	Thu May 23 20:31:37 2024 +0200
     9.2 +++ b/tests/test_hash_map.c	Thu May 23 20:43:04 2024 +0200
     9.3 @@ -42,19 +42,19 @@
     9.4          for(size_t i = 0 ; i < hmap->bucket_count ; i++) {
     9.5              CX_TEST_ASSERT(hmap->buckets[i] == NULL);
     9.6          }
     9.7 -        CX_TEST_ASSERT(map->base.elem_size == 1);
     9.8 -        CX_TEST_ASSERT(map->base.size == 0);
     9.9 -        CX_TEST_ASSERT(map->base.allocator == allocator);
    9.10 -        CX_TEST_ASSERT(!map->base.store_pointer);
    9.11 -        CX_TEST_ASSERT(map->base.cmpfunc == NULL);
    9.12 -        CX_TEST_ASSERT(map->base.simple_destructor == NULL);
    9.13 -        CX_TEST_ASSERT(map->base.advanced_destructor == NULL);
    9.14 -        CX_TEST_ASSERT(map->base.destructor_data == NULL);
    9.15 +        CX_TEST_ASSERT(map->collection.elem_size == 1);
    9.16 +        CX_TEST_ASSERT(map->collection.size == 0);
    9.17 +        CX_TEST_ASSERT(map->collection.allocator == allocator);
    9.18 +        CX_TEST_ASSERT(!map->collection.store_pointer);
    9.19 +        CX_TEST_ASSERT(map->collection.cmpfunc == NULL);
    9.20 +        CX_TEST_ASSERT(map->collection.simple_destructor == NULL);
    9.21 +        CX_TEST_ASSERT(map->collection.advanced_destructor == NULL);
    9.22 +        CX_TEST_ASSERT(map->collection.destructor_data == NULL);
    9.23          cxMapStorePointers(map);
    9.24 -        CX_TEST_ASSERT(map->base.store_pointer);
    9.25 -        CX_TEST_ASSERT(map->base.elem_size == sizeof(void *));
    9.26 +        CX_TEST_ASSERT(map->collection.store_pointer);
    9.27 +        CX_TEST_ASSERT(map->collection.elem_size == sizeof(void *));
    9.28          cxMapStoreObjects(map);
    9.29 -        CX_TEST_ASSERT(!map->base.store_pointer);
    9.30 +        CX_TEST_ASSERT(!map->collection.store_pointer);
    9.31  
    9.32          cxMapDestroy(map);
    9.33          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
    9.34 @@ -73,10 +73,10 @@
    9.35          for (size_t i = 0; i < hmap->bucket_count; i++) {
    9.36              CX_TEST_ASSERT(hmap->buckets[i] == NULL);
    9.37          }
    9.38 -        CX_TEST_ASSERT(map->base.size == 0);
    9.39 -        CX_TEST_ASSERT(map->base.allocator == allocator);
    9.40 -        CX_TEST_ASSERT(map->base.store_pointer);
    9.41 -        CX_TEST_ASSERT(map->base.elem_size == sizeof(void *));
    9.42 +        CX_TEST_ASSERT(map->collection.size == 0);
    9.43 +        CX_TEST_ASSERT(map->collection.allocator == allocator);
    9.44 +        CX_TEST_ASSERT(map->collection.store_pointer);
    9.45 +        CX_TEST_ASSERT(map->collection.elem_size == sizeof(void *));
    9.46  
    9.47          cxMapDestroy(map);
    9.48          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
    9.49 @@ -106,7 +106,7 @@
    9.50          int result = cxMapRehash(map);
    9.51          CX_TEST_ASSERT(result == 0);
    9.52          CX_TEST_ASSERT(((struct cx_hash_map_s *)map)->bucket_count == 25);
    9.53 -        CX_TEST_ASSERT(map->base.size == 10);
    9.54 +        CX_TEST_ASSERT(map->collection.size == 10);
    9.55  
    9.56          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key 1"), "val 1"));
    9.57          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key 2"), "val 2"));
    9.58 @@ -161,11 +161,11 @@
    9.59          cxMapPut(map, "key 2", (void *) "val 2");
    9.60          cxMapPut(map, "key 3", (void *) "val 3");
    9.61  
    9.62 -        CX_TEST_ASSERT(map->base.size == 3);
    9.63 +        CX_TEST_ASSERT(map->collection.size == 3);
    9.64  
    9.65          cxMapClear(map);
    9.66  
    9.67 -        CX_TEST_ASSERT(map->base.size == 0);
    9.68 +        CX_TEST_ASSERT(map->collection.size == 0);
    9.69          CX_TEST_ASSERT(cxMapGet(map, "key 1") == NULL);
    9.70          CX_TEST_ASSERT(cxMapGet(map, "key 2") == NULL);
    9.71          CX_TEST_ASSERT(cxMapGet(map, "key 3") == NULL);
    9.72 @@ -208,7 +208,7 @@
    9.73  
    9.74          // remove a string
    9.75          cxMapRemove(map, "s2");
    9.76 -        CX_TEST_ASSERT(map->base.size == 3);
    9.77 +        CX_TEST_ASSERT(map->collection.size == 3);
    9.78  
    9.79          // iterate
    9.80          bool s3found = false, s4found = false, s5found = false;
    9.81 @@ -244,8 +244,8 @@
    9.82          cx_foreach(CxMapEntry*, entry, iter) {
    9.83              if (((char const *)entry->key->data)[4] % 2 == 1) cxIteratorFlagRemoval(iter);
    9.84          }
    9.85 -        CX_TEST_ASSERT(map->base.size == 3);
    9.86 -        CX_TEST_ASSERT(iter.index == map->base.size);
    9.87 +        CX_TEST_ASSERT(map->collection.size == 3);
    9.88 +        CX_TEST_ASSERT(iter.index == map->collection.size);
    9.89  
    9.90          CX_TEST_ASSERT(cxMapGet(map, "key 1") == NULL);
    9.91          CX_TEST_ASSERT(cxMapGet(map, "key 2") != NULL);
    9.92 @@ -348,7 +348,7 @@
    9.93      CxAllocator *allocator = &talloc.base;
    9.94      CX_TEST_DO {
    9.95          CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
    9.96 -        map->base.simple_destructor = test_simple_destructor;
    9.97 +        map->collection.simple_destructor = test_simple_destructor;
    9.98          CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
    9.99          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   9.100      }
   9.101 @@ -361,7 +361,7 @@
   9.102      CxAllocator *allocator = &talloc.base;
   9.103      CX_TEST_DO {
   9.104          CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
   9.105 -        map->base.advanced_destructor = test_advanced_destructor;
   9.106 +        map->collection.advanced_destructor = test_advanced_destructor;
   9.107          CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
   9.108          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   9.109      }
   9.110 @@ -370,7 +370,8 @@
   9.111  
   9.112  CX_TEST(test_empty_map_size) {
   9.113      CX_TEST_DO {
   9.114 -        CX_TEST_ASSERT(cxEmptyMap->base.size == 0);
   9.115 +        CX_TEST_ASSERT(cxEmptyMap->collection.size == 0);
   9.116 +        CX_TEST_ASSERT(cxMapSize(cxEmptyMap) == 0);
   9.117      }
   9.118  }
   9.119  
   9.120 @@ -430,7 +431,7 @@
   9.121          cxMapPut(map, cx_mutstr("foo"), "bar");
   9.122          cxMapPut(map, cx_str("hallo"), "welt");
   9.123  
   9.124 -        CX_TEST_ASSERT(map->base.size == 3);
   9.125 +        CX_TEST_ASSERT(map->collection.size == 3);
   9.126          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "test"), "test"));
   9.127          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "foo"), "bar"));
   9.128          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "hallo"), "welt"));
   9.129 @@ -441,16 +442,16 @@
   9.130          cxMapDetach(map, hallo);
   9.131          cxMapPut(map, cx_hash_key_str("key"), "value");
   9.132  
   9.133 -        CX_TEST_ASSERT(map->base.size == 2);
   9.134 +        CX_TEST_ASSERT(map->collection.size == 2);
   9.135          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key"), "value"));
   9.136          CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "foo"), "bar"));
   9.137  
   9.138          void *r;
   9.139          r = cxMapRemoveAndGet(map, "key");
   9.140          r = cxMapRemoveAndGet(map, cx_str("foo"));
   9.141 -        if (r != NULL) map->base.size = 47;
   9.142 +        if (r != NULL) map->collection.size = 47;
   9.143  
   9.144 -        CX_TEST_ASSERT(map->base.size == 0);
   9.145 +        CX_TEST_ASSERT(map->collection.size == 0);
   9.146  
   9.147          cxMapDestroy(map);
   9.148          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   9.149 @@ -539,21 +540,21 @@
   9.150  
   9.151  static CX_TEST_SUBROUTINE(verify_map_contents, CxMap *map) {
   9.152      // verify that the reference map has same size (i.e. no other keys are mapped)
   9.153 -    CX_TEST_ASSERT(map->base.size == test_map_reference_size());
   9.154 +    CX_TEST_ASSERT(map->collection.size == test_map_reference_size());
   9.155  
   9.156      // verify key iterator
   9.157      {
   9.158          // collect the keys from the map iterator
   9.159          CxIterator keyiter = cxMapIteratorKeys(map);
   9.160          CX_TEST_ASSERT(keyiter.elem_size == sizeof(CxHashKey));
   9.161 -        CX_TEST_ASSERT(keyiter.elem_count == map->base.size);
   9.162 -        CxHashKey *keys = calloc(map->base.size, sizeof(CxHashKey));
   9.163 +        CX_TEST_ASSERT(keyiter.elem_count == map->collection.size);
   9.164 +        CxHashKey *keys = calloc(map->collection.size, sizeof(CxHashKey));
   9.165          cx_foreach(CxHashKey*, elem, keyiter) {
   9.166              keys[keyiter.index] = *elem;
   9.167          }
   9.168 -        CX_TEST_ASSERT(keyiter.index == map->base.size);
   9.169 +        CX_TEST_ASSERT(keyiter.index == map->collection.size);
   9.170          // verify that all keys are mapped to values in reference map
   9.171 -        for (size_t i = 0 ; i < map->base.size ; i++) {
   9.172 +        for (size_t i = 0 ; i < map->collection.size ; i++) {
   9.173              cxmutstr ksz = cx_strdup(cx_strn(keys[i].data, keys[i].len));
   9.174              CX_TEST_ASSERT(test_map_reference_get(ksz.ptr) != NULL);
   9.175              cx_strfree(&ksz);
   9.176 @@ -566,15 +567,15 @@
   9.177          // by using that the values in our test data are unique strings
   9.178          // we can re-use a similar approach as above
   9.179          CxIterator valiter = cxMapIteratorValues(map);
   9.180 -        CX_TEST_ASSERT(valiter.elem_size == map->base.elem_size);
   9.181 -        CX_TEST_ASSERT(valiter.elem_count == map->base.size);
   9.182 -        char const** values = calloc(map->base.size, sizeof(char const*));
   9.183 +        CX_TEST_ASSERT(valiter.elem_size == map->collection.elem_size);
   9.184 +        CX_TEST_ASSERT(valiter.elem_count == map->collection.size);
   9.185 +        char const** values = calloc(map->collection.size, sizeof(char const*));
   9.186          cx_foreach(char const*, elem, valiter) {
   9.187              values[valiter.index] = elem;
   9.188          }
   9.189 -        CX_TEST_ASSERT(valiter.index == map->base.size);
   9.190 +        CX_TEST_ASSERT(valiter.index == map->collection.size);
   9.191          // verify that all values are present in the reference map
   9.192 -        for (size_t i = 0 ; i < map->base.size ; i++) {
   9.193 +        for (size_t i = 0 ; i < map->collection.size ; i++) {
   9.194              bool found = false;
   9.195              for (size_t j = 0; j < test_map_reference_len ; j++) {
   9.196                  if (test_map_reference[j].value == values[i]) {
   9.197 @@ -591,16 +592,16 @@
   9.198      {
   9.199          CxIterator pairiter = cxMapIterator(map);
   9.200          CX_TEST_ASSERT(pairiter.elem_size == sizeof(CxMapEntry));
   9.201 -        CX_TEST_ASSERT(pairiter.elem_count == map->base.size);
   9.202 -        struct test_map_kv *pairs = calloc(map->base.size, sizeof(struct test_map_kv));
   9.203 +        CX_TEST_ASSERT(pairiter.elem_count == map->collection.size);
   9.204 +        struct test_map_kv *pairs = calloc(map->collection.size, sizeof(struct test_map_kv));
   9.205          cx_foreach(CxMapEntry*, entry, pairiter) {
   9.206              CxHashKey const *key = entry->key;
   9.207              pairs[pairiter.index].key = cx_strdup(cx_strn(key->data, key->len)).ptr;
   9.208              pairs[pairiter.index].value = entry->value;
   9.209          }
   9.210 -        CX_TEST_ASSERT(pairiter.index == map->base.size);
   9.211 +        CX_TEST_ASSERT(pairiter.index == map->collection.size);
   9.212          // verify that all pairs are present in the reference map
   9.213 -        for (size_t i = 0 ; i < map->base.size ; i++) {
   9.214 +        for (size_t i = 0 ; i < map->collection.size ; i++) {
   9.215              CX_TEST_ASSERT(test_map_reference_get(pairs[i].key) == pairs[i].value);
   9.216              // this was strdup'ed
   9.217              free((void*)pairs[i].key);
    10.1 --- a/tests/test_list.c	Thu May 23 20:31:37 2024 +0200
    10.2 +++ b/tests/test_list.c	Thu May 23 20:43:04 2024 +0200
    10.3 @@ -622,7 +622,7 @@
    10.4  
    10.5  CX_TEST(test_empty_list_size) {
    10.6      CX_TEST_DO {
    10.7 -        CX_TEST_ASSERT(cxEmptyList->base.size == 0);
    10.8 +        CX_TEST_ASSERT(cxEmptyList->collection.size == 0);
    10.9          CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0);
   10.10      }
   10.11  }
   10.12 @@ -706,13 +706,13 @@
   10.13      CX_TEST_DO {
   10.14          CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int));
   10.15          CX_TEST_ASSERT(list != NULL);
   10.16 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
   10.17 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
   10.18 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
   10.19 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
   10.20 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
   10.21 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
   10.22 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
   10.23 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
   10.24          CX_TEST_ASSERT(cxListSize(list) == 0);
   10.25 -        CX_TEST_ASSERT(list->base.allocator == alloc);
   10.26 -        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_int);
   10.27 +        CX_TEST_ASSERT(list->collection.allocator == alloc);
   10.28 +        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int);
   10.29          CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   10.30          cxListDestroy(list);
   10.31          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
   10.32 @@ -724,13 +724,13 @@
   10.33      CxList *list = cxLinkedListCreateSimple(sizeof(int));
   10.34      CX_TEST_DO {
   10.35          CX_TEST_ASSERT(list != NULL);
   10.36 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
   10.37 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
   10.38 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
   10.39 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
   10.40 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
   10.41 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
   10.42 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
   10.43 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
   10.44          CX_TEST_ASSERT(cxListSize(list) == 0);
   10.45 -        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
   10.46 -        CX_TEST_ASSERT(list->base.cmpfunc == NULL);
   10.47 +        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
   10.48 +        CX_TEST_ASSERT(list->collection.cmpfunc == NULL);
   10.49          CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   10.50      }
   10.51      cxListDestroy(list);
   10.52 @@ -741,7 +741,7 @@
   10.53      CX_TEST_DO {
   10.54          CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   10.55          cxListStorePointers(list);
   10.56 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(void *));
   10.57 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void *));
   10.58          CX_TEST_ASSERT(list->cl != NULL);
   10.59          CX_TEST_ASSERT(list->climpl != NULL);
   10.60          CX_TEST_ASSERT(cxListIsStoringPointers(list));
   10.61 @@ -757,13 +757,13 @@
   10.62      CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
   10.63      CX_TEST_DO {
   10.64          CX_TEST_ASSERT(list != NULL);
   10.65 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(void*));
   10.66 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
   10.67 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
   10.68 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
   10.69 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*));
   10.70 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
   10.71 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
   10.72 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
   10.73          CX_TEST_ASSERT(cxListSize(list) == 0);
   10.74 -        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
   10.75 -        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_ptr);
   10.76 +        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
   10.77 +        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr);
   10.78          CX_TEST_ASSERT(cxListIsStoringPointers(list));
   10.79      }
   10.80      cxListDestroy(list);
   10.81 @@ -776,13 +776,13 @@
   10.82      CX_TEST_DO {
   10.83          CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8);
   10.84          CX_TEST_ASSERT(list != NULL);
   10.85 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
   10.86 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
   10.87 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
   10.88 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
   10.89 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
   10.90 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
   10.91 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
   10.92 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
   10.93          CX_TEST_ASSERT(cxListSize(list) == 0);
   10.94 -        CX_TEST_ASSERT(list->base.allocator == alloc);
   10.95 -        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_int);
   10.96 +        CX_TEST_ASSERT(list->collection.allocator == alloc);
   10.97 +        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int);
   10.98          CX_TEST_ASSERT(!cxListIsStoringPointers(list));
   10.99          cxListDestroy(list);
  10.100          CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
  10.101 @@ -794,13 +794,13 @@
  10.102      CxList *list = cxArrayListCreateSimple(sizeof(int), 8);
  10.103      CX_TEST_DO {
  10.104          CX_TEST_ASSERT(list != NULL);
  10.105 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
  10.106 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
  10.107 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
  10.108 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
  10.109 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
  10.110 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
  10.111 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
  10.112 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
  10.113          CX_TEST_ASSERT(cxListSize(list) == 0);
  10.114 -        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
  10.115 -        CX_TEST_ASSERT(list->base.cmpfunc == NULL);
  10.116 +        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
  10.117 +        CX_TEST_ASSERT(list->collection.cmpfunc == NULL);
  10.118          CX_TEST_ASSERT(!cxListIsStoringPointers(list));
  10.119      }
  10.120      cxListDestroy(list);
  10.121 @@ -810,13 +810,13 @@
  10.122      CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8);
  10.123      CX_TEST_DO {
  10.124          CX_TEST_ASSERT(list != NULL);
  10.125 -        CX_TEST_ASSERT(list->base.elem_size == sizeof(void*));
  10.126 -        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
  10.127 -        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
  10.128 -        CX_TEST_ASSERT(list->base.destructor_data == NULL);
  10.129 +        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*));
  10.130 +        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
  10.131 +        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
  10.132 +        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
  10.133          CX_TEST_ASSERT(cxListSize(list) == 0);
  10.134 -        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
  10.135 -        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_ptr);
  10.136 +        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
  10.137 +        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr);
  10.138          CX_TEST_ASSERT(cxListIsStoringPointers(list));
  10.139      }
  10.140      cxListDestroy(list);
  10.141 @@ -848,7 +848,7 @@
  10.142      CX_TEST_DO {
  10.143          int item = 0;
  10.144          CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
  10.145 -        list->base.simple_destructor = test_fake_simple_int_destr;
  10.146 +        list->collection.simple_destructor = test_fake_simple_int_destr;
  10.147          cxListAdd(list, &item);
  10.148          cxListDestroy(list);
  10.149          CX_TEST_ASSERT(item == 42);
  10.150 @@ -862,8 +862,8 @@
  10.151      CX_TEST_DO {
  10.152          void *item = cxMalloc(alloc, sizeof(int));
  10.153          CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
  10.154 -        list->base.destructor_data = alloc;
  10.155 -        list->base.advanced_destructor = (cx_destructor_func2) cxFree;
  10.156 +        list->collection.destructor_data = alloc;
  10.157 +        list->collection.advanced_destructor = (cx_destructor_func2) cxFree;
  10.158          cxListAdd(list, item);
  10.159          CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
  10.160          cxListDestroy(list);
  10.161 @@ -894,7 +894,7 @@
  10.162      CX_TEST_DO {
  10.163          int item = 0;
  10.164          CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
  10.165 -        list->base.simple_destructor = test_fake_simple_int_destr;
  10.166 +        list->collection.simple_destructor = test_fake_simple_int_destr;
  10.167          cxListAdd(list, &item);
  10.168          cxListDestroy(list);
  10.169          CX_TEST_ASSERT(item == 42);
  10.170 @@ -908,8 +908,8 @@
  10.171      CX_TEST_DO {
  10.172          void *item = cxMalloc(alloc, sizeof(int));
  10.173          CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
  10.174 -        list->base.destructor_data = alloc;
  10.175 -        list->base.advanced_destructor = (cx_destructor_func2) cxFree;
  10.176 +        list->collection.destructor_data = alloc;
  10.177 +        list->collection.advanced_destructor = (cx_destructor_func2) cxFree;
  10.178          cxListAdd(list, item);
  10.179          CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
  10.180          cxListDestroy(list);
  10.181 @@ -1207,8 +1207,8 @@
  10.182      int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  10.183  
  10.184      CxIterator iter = cxListIterator(list);
  10.185 -    CX_TEST_ASSERT(iter.elem_size == list->base.elem_size);
  10.186 -    CX_TEST_ASSERT(iter.elem_count == list->base.size);
  10.187 +    CX_TEST_ASSERT(iter.elem_size == list->collection.elem_size);
  10.188 +    CX_TEST_ASSERT(iter.elem_count == list->collection.size);
  10.189      size_t i = 0;
  10.190      cx_foreach(int*, x, iter) {
  10.191          CX_TEST_ASSERT(i == iter.index);
  10.192 @@ -1225,8 +1225,8 @@
  10.193      CX_TEST_ASSERT(i == 0);
  10.194      i = len / 2;
  10.195      CxIterator mut_iter = cxListMutIteratorAt(list, i);
  10.196 -    CX_TEST_ASSERT(mut_iter.elem_size == list->base.elem_size);
  10.197 -    CX_TEST_ASSERT(mut_iter.elem_count == list->base.size);
  10.198 +    CX_TEST_ASSERT(mut_iter.elem_size == list->collection.elem_size);
  10.199 +    CX_TEST_ASSERT(mut_iter.elem_count == list->collection.size);
  10.200      size_t j = 0;
  10.201      cx_foreach(int*, x, mut_iter) {
  10.202          CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2);
  10.203 @@ -1395,7 +1395,7 @@
  10.204  roll_out_test_combos(simple_destr, {
  10.205      const size_t len = 60;
  10.206      int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  10.207 -    list->base.simple_destructor = simple_destr_test_fun;
  10.208 +    list->collection.simple_destructor = simple_destr_test_fun;
  10.209      CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  10.210      free(testdata);
  10.211  })
  10.212 @@ -1403,7 +1403,7 @@
  10.213  roll_out_test_combos(advanced_destr, {
  10.214      const size_t len = 75;
  10.215      int *testdata = int_test_data_added_to_list(list, isptrlist, len);
  10.216 -    list->base.advanced_destructor = advanced_destr_test_fun;
  10.217 +    list->collection.advanced_destructor = advanced_destr_test_fun;
  10.218      CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
  10.219      free(testdata);
  10.220  })

mercurial