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
--- a/src/array_list.c	Thu May 23 20:31:37 2024 +0200
+++ b/src/array_list.c	Thu May 23 20:43:04 2024 +0200
@@ -191,21 +191,21 @@
 
     char *ptr = arl->data;
 
-    if (list->base.simple_destructor) {
-        for (size_t i = 0; i < list->base.size; i++) {
+    if (list->collection.simple_destructor) {
+        for (size_t i = 0; i < list->collection.size; i++) {
             cx_invoke_simple_destructor(list, ptr);
-            ptr += list->base.elem_size;
+            ptr += list->collection.elem_size;
         }
     }
-    if (list->base.advanced_destructor) {
-        for (size_t i = 0; i < list->base.size; i++) {
+    if (list->collection.advanced_destructor) {
+        for (size_t i = 0; i < list->collection.size; i++) {
             cx_invoke_advanced_destructor(list, ptr);
-            ptr += list->base.elem_size;
+            ptr += list->collection.elem_size;
         }
     }
 
-    cxFree(list->base.allocator, arl->data);
-    cxFree(list->base.allocator, list);
+    cxFree(list->collection.allocator, arl->data);
+    cxFree(list->collection.allocator, list);
 }
 
 static size_t cx_arl_insert_array(
@@ -215,25 +215,25 @@
         size_t n
 ) {
     // out of bounds and special case check
-    if (index > list->base.size || n == 0) return 0;
+    if (index > list->collection.size || n == 0) return 0;
 
     // get a correctly typed pointer to the list
     cx_array_list *arl = (cx_array_list *) list;
 
     // do we need to move some elements?
-    if (index < list->base.size) {
+    if (index < list->collection.size) {
         char const *first_to_move = (char const *) arl->data;
-        first_to_move += index * list->base.elem_size;
-        size_t elems_to_move = list->base.size - index;
+        first_to_move += index * list->collection.elem_size;
+        size_t elems_to_move = list->collection.size - index;
         size_t start_of_moved = index + n;
 
         if (CX_ARRAY_SUCCESS != cx_array_copy(
                 &arl->data,
-                &list->base.size,
+                &list->collection.size,
                 &arl->capacity,
                 start_of_moved,
                 first_to_move,
-                list->base.elem_size,
+                list->collection.elem_size,
                 elems_to_move,
                 &arl->reallocator
         )) {
@@ -249,11 +249,11 @@
     // place the new elements
     if (CX_ARRAY_SUCCESS == cx_array_copy(
             &arl->data,
-            &list->base.size,
+            &list->collection.size,
             &arl->capacity,
             index,
             array,
-            list->base.elem_size,
+            list->collection.elem_size,
             n,
             &arl->reallocator
     )) {
@@ -278,7 +278,7 @@
         int prepend
 ) {
     struct cx_list_s *list = iter->src_handle.m;
-    if (iter->index < list->base.size) {
+    if (iter->index < list->collection.size) {
         int result = cx_arl_insert_element(
                 list,
                 iter->index + 1 - prepend,
@@ -286,12 +286,12 @@
         );
         if (result == 0 && prepend != 0) {
             iter->index++;
-            iter->elem_handle = ((char *) iter->elem_handle) + list->base.elem_size;
+            iter->elem_handle = ((char *) iter->elem_handle) + list->collection.elem_size;
         }
         return result;
     } else {
-        int result = cx_arl_insert_element(list, list->base.size, elem);
-        iter->index = list->base.size;
+        int result = cx_arl_insert_element(list, list->collection.size, elem);
+        iter->index = list->collection.size;
         return result;
     }
 }
@@ -303,28 +303,28 @@
     cx_array_list *arl = (cx_array_list *) list;
 
     // out-of-bounds check
-    if (index >= list->base.size) {
+    if (index >= list->collection.size) {
         return 1;
     }
 
     // content destruction
-    cx_invoke_destructor(list, ((char *) arl->data) + index * list->base.elem_size);
+    cx_invoke_destructor(list, ((char *) arl->data) + index * list->collection.elem_size);
 
     // short-circuit removal of last element
-    if (index == list->base.size - 1) {
-        list->base.size--;
+    if (index == list->collection.size - 1) {
+        list->collection.size--;
         return 0;
     }
 
     // just move the elements starting at index to the left
     int result = cx_array_copy(
             &arl->data,
-            &list->base.size,
+            &list->collection.size,
             &arl->capacity,
             index,
-            ((char *) arl->data) + (index + 1) * list->base.elem_size,
-            list->base.elem_size,
-            list->base.size - index - 1,
+            ((char *) arl->data) + (index + 1) * list->collection.elem_size,
+            list->collection.elem_size,
+            list->collection.size - index - 1,
             &arl->reallocator
     );
 
@@ -332,32 +332,32 @@
     assert(result == 0);
 
     // decrease the size
-    list->base.size--;
+    list->collection.size--;
 
     return 0;
 }
 
 static void cx_arl_clear(struct cx_list_s *list) {
-    if (list->base.size == 0) return;
+    if (list->collection.size == 0) return;
 
     cx_array_list *arl = (cx_array_list *) list;
     char *ptr = arl->data;
 
-    if (list->base.simple_destructor) {
-        for (size_t i = 0; i < list->base.size; i++) {
+    if (list->collection.simple_destructor) {
+        for (size_t i = 0; i < list->collection.size; i++) {
             cx_invoke_simple_destructor(list, ptr);
-            ptr += list->base.elem_size;
+            ptr += list->collection.elem_size;
         }
     }
-    if (list->base.advanced_destructor) {
-        for (size_t i = 0; i < list->base.size; i++) {
+    if (list->collection.advanced_destructor) {
+        for (size_t i = 0; i < list->collection.size; i++) {
             cx_invoke_advanced_destructor(list, ptr);
-            ptr += list->base.elem_size;
+            ptr += list->collection.elem_size;
         }
     }
 
-    memset(arl->data, 0, list->base.size * list->base.elem_size);
-    list->base.size = 0;
+    memset(arl->data, 0, list->collection.size * list->collection.elem_size);
+    list->collection.size = 0;
 }
 
 static int cx_arl_swap(
@@ -365,9 +365,9 @@
         size_t i,
         size_t j
 ) {
-    if (i >= list->base.size || j >= list->base.size) return 1;
+    if (i >= list->collection.size || j >= list->collection.size) return 1;
     cx_array_list *arl = (cx_array_list *) list;
-    cx_array_swap(arl->data, list->base.elem_size, i, j);
+    cx_array_swap(arl->data, list->collection.elem_size, i, j);
     return 0;
 }
 
@@ -375,10 +375,10 @@
         struct cx_list_s const *list,
         size_t index
 ) {
-    if (index < list->base.size) {
+    if (index < list->collection.size) {
         cx_array_list const *arl = (cx_array_list const *) list;
         char *space = arl->data;
-        return space + index * list->base.elem_size;
+        return space + index * list->collection.elem_size;
     } else {
         return NULL;
     }
@@ -389,12 +389,12 @@
         void const *elem,
         bool remove
 ) {
-    assert(list->base.cmpfunc != NULL);
-    assert(list->base.size < SIZE_MAX / 2);
+    assert(list->collection.cmpfunc != NULL);
+    assert(list->collection.size < SIZE_MAX / 2);
     char *cur = ((cx_array_list const *) list)->data;
 
-    for (ssize_t i = 0; i < (ssize_t) list->base.size; i++) {
-        if (0 == list->base.cmpfunc(elem, cur)) {
+    for (ssize_t i = 0; i < (ssize_t) list->collection.size; i++) {
+        if (0 == list->collection.cmpfunc(elem, cur)) {
             if (remove) {
                 if (0 == cx_arl_remove(list, i)) {
                     return i;
@@ -405,18 +405,18 @@
                 return i;
             }
         }
-        cur += list->base.elem_size;
+        cur += list->collection.elem_size;
     }
 
     return -1;
 }
 
 static void cx_arl_sort(struct cx_list_s *list) {
-    assert(list->base.cmpfunc != NULL);
+    assert(list->collection.cmpfunc != NULL);
     qsort(((cx_array_list *) list)->data,
-          list->base.size,
-          list->base.elem_size,
-          list->base.cmpfunc
+          list->collection.size,
+          list->collection.elem_size,
+          list->collection.cmpfunc
     );
 }
 
@@ -424,37 +424,37 @@
         struct cx_list_s const *list,
         struct cx_list_s const *other
 ) {
-    assert(list->base.cmpfunc != NULL);
-    if (list->base.size == other->base.size) {
+    assert(list->collection.cmpfunc != NULL);
+    if (list->collection.size == other->collection.size) {
         char const *left = ((cx_array_list const *) list)->data;
         char const *right = ((cx_array_list const *) other)->data;
-        for (size_t i = 0; i < list->base.size; i++) {
-            int d = list->base.cmpfunc(left, right);
+        for (size_t i = 0; i < list->collection.size; i++) {
+            int d = list->collection.cmpfunc(left, right);
             if (d != 0) {
                 return d;
             }
-            left += list->base.elem_size;
-            right += other->base.elem_size;
+            left += list->collection.elem_size;
+            right += other->collection.elem_size;
         }
         return 0;
     } else {
-        return list->base.size < other->base.size ? -1 : 1;
+        return list->collection.size < other->collection.size ? -1 : 1;
     }
 }
 
 static void cx_arl_reverse(struct cx_list_s *list) {
-    if (list->base.size < 2) return;
+    if (list->collection.size < 2) return;
     void *data = ((cx_array_list const *) list)->data;
-    size_t half = list->base.size / 2;
+    size_t half = list->collection.size / 2;
     for (size_t i = 0; i < half; i++) {
-        cx_array_swap(data, list->base.elem_size, i, list->base.size - 1 - i);
+        cx_array_swap(data, list->collection.elem_size, i, list->collection.size - 1 - i);
     }
 }
 
 static bool cx_arl_iter_valid(void const *it) {
     struct cx_iterator_s const *iter = it;
     struct cx_list_s const *list = iter->src_handle.c;
-    return iter->index < list->base.size;
+    return iter->index < list->collection.size;
 }
 
 static void *cx_arl_iter_current(void const *it) {
@@ -471,7 +471,7 @@
         iter->index++;
         iter->elem_handle =
                 ((char *) iter->elem_handle)
-                + ((struct cx_list_s const *) iter->src_handle.c)->base.elem_size;
+                + ((struct cx_list_s const *) iter->src_handle.c)->collection.elem_size;
     }
 }
 
@@ -483,9 +483,9 @@
         cx_arl_remove(iter->src_handle.m, iter->index);
     }
     iter->index--;
-    if (iter->index < list->base.base.size) {
+    if (iter->index < list->base.collection.size) {
         iter->elem_handle = ((char *) list->data)
-                            + iter->index * list->base.base.elem_size;
+                            + iter->index * list->base.collection.elem_size;
     }
 }
 
@@ -500,8 +500,8 @@
     iter.index = index;
     iter.src_handle.c = list;
     iter.elem_handle = cx_arl_at(list, index);
-    iter.elem_size = list->base.elem_size;
-    iter.elem_count = list->base.size;
+    iter.elem_size = list->collection.elem_size;
+    iter.elem_count = list->collection.size;
     iter.base.valid = cx_arl_iter_valid;
     iter.base.current = cx_arl_iter_current;
     iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next;
@@ -541,15 +541,15 @@
     if (list == NULL) return NULL;
 
     list->base.cl = &cx_array_list_class;
-    list->base.base.allocator = allocator;
+    list->base.collection.allocator = allocator;
     list->capacity = initial_capacity;
 
     if (elem_size > 0) {
-        list->base.base.elem_size = elem_size;
-        list->base.base.cmpfunc = comparator;
+        list->base.collection.elem_size = elem_size;
+        list->base.collection.cmpfunc = comparator;
     } else {
         elem_size = sizeof(void *);
-        list->base.base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
+        list->base.collection.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
         cxListStorePointers((CxList *) list);
     }
 
--- a/src/cx/collection.h	Thu May 23 20:31:37 2024 +0200
+++ b/src/cx/collection.h	Thu May 23 20:43:04 2024 +0200
@@ -97,7 +97,7 @@
 /**
  * Use this macro to declare common members for a collection structure.
  */
-#define CX_COLLECTION_BASE struct cx_collection_s base
+#define CX_COLLECTION_BASE struct cx_collection_s collection
 
 /**
  * Invokes the simple destructor function for a specific element.
@@ -109,7 +109,7 @@
  * @param e the element
  */
 #define cx_invoke_simple_destructor(c, e) \
-    (c)->base.simple_destructor((c)->base.store_pointer ? (*((void **) (e))) : (e))
+    (c)->collection.simple_destructor((c)->collection.store_pointer ? (*((void **) (e))) : (e))
 
 /**
  * Invokes the advanced destructor function for a specific element.
@@ -121,8 +121,8 @@
  * @param e the element
  */
 #define cx_invoke_advanced_destructor(c, e) \
-    (c)->base.advanced_destructor((c)->base.destructor_data, \
-    (c)->base.store_pointer ? (*((void **) (e))) : (e))
+    (c)->collection.advanced_destructor((c)->collection.destructor_data, \
+    (c)->collection.store_pointer ? (*((void **) (e))) : (e))
 
 
 /**
@@ -135,8 +135,8 @@
  * @param e the element
  */
 #define cx_invoke_destructor(c, e) \
-    if ((c)->base.simple_destructor) cx_invoke_simple_destructor(c,e); \
-    if ((c)->base.advanced_destructor) cx_invoke_advanced_destructor(c,e)
+    if ((c)->collection.simple_destructor) cx_invoke_simple_destructor(c,e); \
+    if ((c)->collection.advanced_destructor) cx_invoke_advanced_destructor(c,e)
 
 #ifdef __cplusplus
 } // extern "C"
--- a/src/cx/collection_base.h	Thu May 23 20:31:37 2024 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * \file collection_base.h
- * \brief Include this file in your collection struct to declare common members.
- * \author Mike Becker
- * \author Olaf Wintermann
- * \copyright 2-Clause BSD License
- */
-
--- a/src/cx/list.h	Thu May 23 20:31:37 2024 +0200
+++ b/src/cx/list.h	Thu May 23 20:43:04 2024 +0200
@@ -213,7 +213,7 @@
  */
 __attribute__((__nonnull__))
 static inline bool cxListIsStoringPointers(CxList const *list) {
-    return list->base.store_pointer;
+    return list->collection.store_pointer;
 }
 
 /**
@@ -224,7 +224,7 @@
  */
 __attribute__((__nonnull__))
 static inline size_t cxListSize(CxList const *list) {
-    return list->base.size;
+    return list->collection.size;
 }
 
 /**
@@ -240,7 +240,7 @@
         CxList *list,
         void const *elem
 ) {
-    return list->cl->insert_element(list, list->base.size, elem);
+    return list->cl->insert_element(list, list->collection.size, elem);
 }
 
 /**
@@ -265,7 +265,7 @@
         void const *array,
         size_t n
 ) {
-    return list->cl->insert_array(list, list->base.size, array, n);
+    return list->cl->insert_array(list, list->collection.size, array, n);
 }
 
 /**
@@ -547,7 +547,7 @@
  */
 __attribute__((__nonnull__, __warn_unused_result__))
 static inline CxIterator cxListBackwardsIterator(CxList const *list) {
-    return list->cl->iterator(list, list->base.size - 1, true);
+    return list->cl->iterator(list, list->collection.size - 1, true);
 }
 
 /**
@@ -562,7 +562,7 @@
  */
 __attribute__((__nonnull__, __warn_unused_result__))
 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
-    return cxListMutBackwardsIteratorAt(list, list->base.size - 1);
+    return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
 }
 
 /**
--- a/src/cx/map.h	Thu May 23 20:31:37 2024 +0200
+++ b/src/cx/map.h	Thu May 23 20:43:04 2024 +0200
@@ -166,7 +166,7 @@
  */
 __attribute__((__nonnull__))
 static inline void cxMapStoreObjects(CxMap *map) {
-    map->base.store_pointer = false;
+    map->collection.store_pointer = false;
 }
 
 /**
@@ -183,8 +183,8 @@
  */
 __attribute__((__nonnull__))
 static inline void cxMapStorePointers(CxMap *map) {
-    map->base.store_pointer = true;
-    map->base.elem_size = sizeof(void *);
+    map->collection.store_pointer = true;
+    map->collection.elem_size = sizeof(void *);
 }
 
 
@@ -209,6 +209,17 @@
     map->cl->clear(map);
 }
 
+/**
+ * Returns the number of elements in this map.
+ *
+ * @param map the map
+ * @return the number of stored elements
+ */
+__attribute__((__nonnull__))
+static inline size_t cxMapSize(CxMap const *map) {
+    return map->collection.size;
+}
+
 
 // TODO: set-like map operations (union, intersect, difference)
 
@@ -1053,7 +1064,7 @@
         CxMap *map,
         CxHashKey key
 ) {
-    return map->cl->remove(map, key, !map->base.store_pointer);
+    return map->cl->remove(map, key, !map->collection.store_pointer);
 }
 
 /**
@@ -1069,7 +1080,7 @@
         CxMap *map,
         cxstring key
 ) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
+    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
 }
 
 /**
@@ -1085,7 +1096,7 @@
         CxMap *map,
         cxmutstr key
 ) {
-    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
+    return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
 }
 
 /**
@@ -1101,7 +1112,7 @@
         CxMap *map,
         char const *key
 ) {
-    return map->cl->remove(map, cx_hash_key_str(key), !map->base.store_pointer);
+    return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
 }
 
 /**
--- a/src/hash_map.c	Thu May 23 20:31:37 2024 +0200
+++ b/src/hash_map.c	Thu May 23 20:43:04 2024 +0200
@@ -53,9 +53,9 @@
                 // invoke the destructor
                 cx_invoke_destructor(map, elem->data);
                 // free the key data
-                cxFree(map->base.allocator, (void *) elem->key.data);
+                cxFree(map->collection.allocator, (void *) elem->key.data);
                 // free the node
-                cxFree(map->base.allocator, elem);
+                cxFree(map->collection.allocator, elem);
                 // proceed
                 elem = next;
             } while (elem != NULL);
@@ -64,7 +64,7 @@
             hash_map->buckets[i] = NULL;
         }
     }
-    map->base.size = 0;
+    map->collection.size = 0;
 }
 
 static void cx_hash_map_destructor(struct cx_map_s *map) {
@@ -72,10 +72,10 @@
 
     // free the buckets
     cx_hash_map_clear(map);
-    cxFree(map->base.allocator, hash_map->buckets);
+    cxFree(map->collection.allocator, hash_map->buckets);
 
     // free the map structure
-    cxFree(map->base.allocator, map);
+    cxFree(map->collection.allocator, map);
 }
 
 static int cx_hash_map_put(
@@ -84,7 +84,7 @@
         void *value
 ) {
     struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
-    CxAllocator const *allocator = map->base.allocator;
+    CxAllocator const *allocator = map->collection.allocator;
 
     unsigned hash = key.hash;
     if (hash == 0) {
@@ -104,26 +104,26 @@
     if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len &&
         memcmp(elm->key.data, key.data, key.len) == 0) {
         // overwrite existing element
-        if (map->base.store_pointer) {
+        if (map->collection.store_pointer) {
             memcpy(elm->data, &value, sizeof(void *));
         } else {
-            memcpy(elm->data, value, map->base.elem_size);
+            memcpy(elm->data, value, map->collection.elem_size);
         }
     } else {
         // allocate new element
         struct cx_hash_map_element_s *e = cxMalloc(
                 allocator,
-                sizeof(struct cx_hash_map_element_s) + map->base.elem_size
+                sizeof(struct cx_hash_map_element_s) + map->collection.elem_size
         );
         if (e == NULL) {
             return -1;
         }
 
         // write the value
-        if (map->base.store_pointer) {
+        if (map->collection.store_pointer) {
             memcpy(e->data, &value, sizeof(void *));
         } else {
-            memcpy(e->data, value, map->base.elem_size);
+            memcpy(e->data, value, map->collection.elem_size);
         }
 
         // copy the key
@@ -145,7 +145,7 @@
         e->next = elm;
 
         // increase the size
-        map->base.size++;
+        map->collection.size++;
     }
 
     return 0;
@@ -164,10 +164,10 @@
         prev->next = elm->next;
     }
     // free element
-    cxFree(hash_map->base.base.allocator, (void *) elm->key.data);
-    cxFree(hash_map->base.base.allocator, elm);
+    cxFree(hash_map->base.collection.allocator, (void *) elm->key.data);
+    cxFree(hash_map->base.collection.allocator, elm);
     // decrease size
-    hash_map->base.base.size--;
+    hash_map->base.collection.size--;
 }
 
 /**
@@ -203,7 +203,7 @@
                 if (destroy) {
                     cx_invoke_destructor(map, elm->data);
                 } else {
-                    if (map->base.store_pointer) {
+                    if (map->collection.store_pointer) {
                         data = *(void **) elm->data;
                     } else {
                         data = elm->data;
@@ -254,7 +254,7 @@
     struct cx_iterator_s const *iter = it;
     struct cx_hash_map_s const *map = iter->src_handle.c;
     struct cx_hash_map_element_s *elm = iter->elem_handle;
-    if (map->base.base.store_pointer) {
+    if (map->base.collection.store_pointer) {
         return *(void **) elm->data;
     } else {
         return elm->data;
@@ -315,7 +315,7 @@
         iter->kv_data.value = NULL;
     } else {
         iter->kv_data.key = &elm->key;
-        if (map->base.base.store_pointer) {
+        if (map->base.collection.store_pointer) {
             iter->kv_data.value = *(void **) elm->data;
         } else {
             iter->kv_data.value = elm->data;
@@ -330,7 +330,7 @@
     CxIterator iter;
 
     iter.src_handle.c = map;
-    iter.elem_count = map->base.size;
+    iter.elem_count = map->collection.size;
 
     switch (type) {
         case CX_MAP_ITERATOR_PAIRS:
@@ -342,7 +342,7 @@
             iter.base.current = cx_hash_map_iter_current_key;
             break;
         case CX_MAP_ITERATOR_VALUES:
-            iter.elem_size = map->base.elem_size;
+            iter.elem_size = map->collection.elem_size;
             iter.base.current = cx_hash_map_iter_current_value;
             break;
         default:
@@ -357,7 +357,7 @@
     iter.slot = 0;
     iter.index = 0;
 
-    if (map->base.size > 0) {
+    if (map->collection.size > 0) {
         struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
         struct cx_hash_map_element_s *elm = hash_map->buckets[0];
         while (elm == NULL) {
@@ -365,7 +365,7 @@
         }
         iter.elem_handle = elm;
         iter.kv_data.key = &elm->key;
-        if (map->base.store_pointer) {
+        if (map->collection.store_pointer) {
             iter.kv_data.value = *(void **) elm->data;
         } else {
             iter.kv_data.value = elm->data;
@@ -413,14 +413,14 @@
 
     // initialize base members
     map->base.cl = &cx_hash_map_class;
-    map->base.base.allocator = allocator;
+    map->base.collection.allocator = allocator;
 
     if (itemsize > 0) {
-        map->base.base.store_pointer = false;
-        map->base.base.elem_size = itemsize;
+        map->base.collection.store_pointer = false;
+        map->base.collection.elem_size = itemsize;
     } else {
-        map->base.base.store_pointer = true;
-        map->base.base.elem_size = sizeof(void *);
+        map->base.collection.store_pointer = true;
+        map->base.collection.elem_size = sizeof(void *);
     }
 
     return (CxMap *) map;
@@ -428,11 +428,11 @@
 
 int cxMapRehash(CxMap *map) {
     struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
-    if (map->base.size > ((hash_map->bucket_count * 3) >> 2)) {
+    if (map->collection.size > ((hash_map->bucket_count * 3) >> 2)) {
 
-        size_t new_bucket_count = (map->base.size * 5) >> 1;
+        size_t new_bucket_count = (map->collection.size * 5) >> 1;
         struct cx_hash_map_element_s **new_buckets = cxCalloc(
-                map->base.allocator,
+                map->collection.allocator,
                 new_bucket_count, sizeof(struct cx_hash_map_element_s *)
         );
 
@@ -472,7 +472,7 @@
 
         // assign result to the map
         hash_map->bucket_count = new_bucket_count;
-        cxFree(map->base.allocator, hash_map->buckets);
+        cxFree(map->collection.allocator, hash_map->buckets);
         hash_map->buckets = new_buckets;
     }
     return 0;
--- a/src/linked_list.c	Thu May 23 20:31:37 2024 +0200
+++ b/src/linked_list.c	Thu May 23 20:43:04 2024 +0200
@@ -501,10 +501,10 @@
         cx_linked_list const *list,
         size_t index
 ) {
-    if (index >= list->base.base.size) {
+    if (index >= list->base.collection.size) {
         return NULL;
-    } else if (index > list->base.base.size / 2) {
-        return cx_linked_list_at(list->end, list->base.base.size - 1, CX_LL_LOC_PREV, index);
+    } else if (index > list->base.collection.size / 2) {
+        return cx_linked_list_at(list->end, list->base.collection.size - 1, CX_LL_LOC_PREV, index);
     } else {
         return cx_linked_list_at(list->begin, 0, CX_LL_LOC_NEXT, index);
     }
@@ -517,15 +517,15 @@
 ) {
 
     // create the new new_node
-    cx_linked_list_node *new_node = cxMalloc(list->base.allocator,
-                                             sizeof(cx_linked_list_node) + list->base.elem_size);
+    cx_linked_list_node *new_node = cxMalloc(list->collection.allocator,
+                                             sizeof(cx_linked_list_node) + list->collection.elem_size);
 
     // sortir if failed
     if (new_node == NULL) return 1;
 
     // initialize new new_node
     new_node->prev = new_node->next = NULL;
-    memcpy(new_node->payload, elem, list->base.elem_size);
+    memcpy(new_node->payload, elem, list->collection.elem_size);
 
     // insert
     cx_linked_list *ll = (cx_linked_list *) list;
@@ -536,7 +536,7 @@
     );
 
     // increase the size and return
-    list->base.size++;
+    list->collection.size++;
     return 0;
 }
 
@@ -547,7 +547,7 @@
         size_t n
 ) {
     // out-of bounds and corner case check
-    if (index > list->base.size || n == 0) return 0;
+    if (index > list->collection.size || n == 0) return 0;
 
     // find position efficiently
     cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
@@ -566,7 +566,7 @@
     // we can add the remaining nodes and immedately advance to the inserted node
     char const *source = array;
     for (size_t i = 1; i < n; i++) {
-        source += list->base.elem_size;
+        source += list->collection.elem_size;
         if (0 != cx_ll_insert_at(list, node, source)) {
             return i;
         }
@@ -601,27 +601,27 @@
                           CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
 
     // adjust size
-    list->base.size--;
+    list->collection.size--;
 
     // free and return
-    cxFree(list->base.allocator, node);
+    cxFree(list->collection.allocator, node);
 
     return 0;
 }
 
 static void cx_ll_clear(struct cx_list_s *list) {
-    if (list->base.size == 0) return;
+    if (list->collection.size == 0) return;
 
     cx_linked_list *ll = (cx_linked_list *) list;
     cx_linked_list_node *node = ll->begin;
     while (node != NULL) {
         cx_invoke_destructor(list, node->payload);
         cx_linked_list_node *next = node->next;
-        cxFree(list->base.allocator, node);
+        cxFree(list->collection.allocator, node);
         node = next;
     }
     ll->begin = ll->end = NULL;
-    list->base.size = 0;
+    list->collection.size = 0;
 }
 
 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE
@@ -634,12 +634,12 @@
         size_t i,
         size_t j
 ) {
-    if (i >= list->base.size || j >= list->base.size) return 1;
+    if (i >= list->collection.size || j >= list->collection.size) return 1;
     if (i == j) return 0;
 
     // perform an optimized search that finds both elements in one run
     cx_linked_list *ll = (cx_linked_list *) list;
-    size_t mid = list->base.size / 2;
+    size_t mid = list->collection.size / 2;
     size_t left, right;
     if (i < j) {
         left = i;
@@ -671,7 +671,7 @@
         // chose the closest to begin / end
         size_t closest;
         size_t other;
-        size_t diff2boundary = list->base.size - right - 1;
+        size_t diff2boundary = list->collection.size - right - 1;
         if (left <= diff2boundary) {
             closest = left;
             other = right;
@@ -707,7 +707,7 @@
         }
     }
 
-    if (list->base.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) {
+    if (list->collection.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) {
         cx_linked_list_node *prev = nleft->prev;
         cx_linked_list_node *next = nright->next;
         cx_linked_list_node *midstart = nleft->next;
@@ -739,9 +739,9 @@
     } else {
         // swap payloads to avoid relinking
         char buf[CX_LINKED_LIST_SWAP_SBO_SIZE];
-        memcpy(buf, nleft->payload, list->base.elem_size);
-        memcpy(nleft->payload, nright->payload, list->base.elem_size);
-        memcpy(nright->payload, buf, list->base.elem_size);
+        memcpy(buf, nleft->payload, list->collection.elem_size);
+        memcpy(nleft->payload, nright->payload, list->collection.elem_size);
+        memcpy(nright->payload, buf, list->collection.elem_size);
     }
 
     return 0;
@@ -768,21 +768,21 @@
                 (void **) &node,
                 ll->begin,
                 CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                list->base.cmpfunc, elem
+                list->collection.cmpfunc, elem
         );
         if (node != NULL) {
             cx_invoke_destructor(list, node->payload);
             cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
                                   CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
-            list->base.size--;
-            cxFree(list->base.allocator, node);
+            list->collection.size--;
+            cxFree(list->collection.allocator, node);
         }
         return index;
     } else {
         return cx_linked_list_find(
                 ((cx_linked_list *) list)->begin,
                 CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                list->base.cmpfunc, elem
+                list->collection.cmpfunc, elem
         );
     }
 }
@@ -791,7 +791,7 @@
     cx_linked_list *ll = (cx_linked_list *) list;
     cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end,
                         CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                        list->base.cmpfunc);
+                        list->collection.cmpfunc);
 }
 
 static void cx_ll_reverse(struct cx_list_s *list) {
@@ -807,7 +807,7 @@
     cx_linked_list *right = (cx_linked_list *) other;
     return cx_linked_list_compare(left->begin, right->begin,
                                   CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                                  list->base.cmpfunc);
+                                  list->collection.cmpfunc);
 }
 
 static bool cx_ll_iter_valid(void const *it) {
@@ -826,8 +826,8 @@
         cx_invoke_destructor(list, node->payload);
         cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
                               CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
-        list->base.size--;
-        cxFree(list->base.allocator, node);
+        list->collection.size--;
+        cxFree(list->collection.allocator, node);
     } else {
         iter->index++;
         cx_linked_list_node *node = iter->elem_handle;
@@ -847,8 +847,8 @@
         cx_invoke_destructor(list, node->payload);
         cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
                               CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
-        list->base.size--;
-        cxFree(list->base.allocator, node);
+        list->collection.size--;
+        cxFree(list->collection.allocator, node);
     } else {
         iter->index--;
         cx_linked_list_node *node = iter->elem_handle;
@@ -871,8 +871,8 @@
     iter.index = index;
     iter.src_handle.c = list;
     iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index);
-    iter.elem_size = list->base.elem_size;
-    iter.elem_count = list->base.size;
+    iter.elem_size = list->collection.elem_size;
+    iter.elem_count = list->collection.size;
     iter.base.valid = cx_ll_iter_valid;
     iter.base.current = cx_ll_iter_current;
     iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next;
@@ -895,8 +895,8 @@
         iter->index += prepend * (0 == result);
         return result;
     } else {
-        int result = cx_ll_insert_element(list, list->base.size, elem);
-        iter->index = list->base.size;
+        int result = cx_ll_insert_element(list, list->collection.size, elem);
+        iter->index = list->collection.size;
         return result;
     }
 }
@@ -908,11 +908,11 @@
     while (node) {
         cx_invoke_destructor(list, node->payload);
         void *next = node->next;
-        cxFree(list->base.allocator, node);
+        cxFree(list->collection.allocator, node);
         node = next;
     }
 
-    cxFree(list->base.allocator, list);
+    cxFree(list->collection.allocator, list);
 }
 
 static cx_list_class cx_linked_list_class = {
@@ -944,13 +944,13 @@
     if (list == NULL) return NULL;
 
     list->base.cl = &cx_linked_list_class;
-    list->base.base.allocator = allocator;
+    list->base.collection.allocator = allocator;
 
     if (elem_size > 0) {
-        list->base.base.elem_size = elem_size;
-        list->base.base.cmpfunc = comparator;
+        list->base.collection.elem_size = elem_size;
+        list->base.collection.cmpfunc = comparator;
     } else {
-        list->base.base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
+        list->base.collection.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
         cxListStorePointers((CxList *) list);
     }
 
--- a/src/list.c	Thu May 23 20:31:37 2024 +0200
+++ b/src/list.c	Thu May 23 20:43:04 2024 +0200
@@ -47,14 +47,14 @@
 
 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) {
     // cast away const - this is the hacky thing
-    struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
+    struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
     cx_pl_cmpfunc_impl = l->cmpfunc;
     l->cmpfunc = cx_pl_cmpfunc;
 }
 
 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) {
     // cast away const - this is the hacky thing
-    struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
+    struct cx_collection_s *l = (struct cx_collection_s*) &list->collection;
     l->cmpfunc = cx_pl_cmpfunc_impl;
 }
 
@@ -180,7 +180,7 @@
 };
 
 void cxListStoreObjects(CxList *list) {
-    list->base.store_pointer = false;
+    list->collection.store_pointer = false;
     if (list->climpl != NULL) {
         list->cl = list->climpl;
         list->climpl = NULL;
@@ -188,8 +188,8 @@
 }
 
 void cxListStorePointers(CxList *list) {
-    list->base.elem_size = sizeof(void *);
-    list->base.store_pointer = true;
+    list->collection.elem_size = sizeof(void *);
+    list->collection.store_pointer = true;
     list->climpl = list->cl;
     list->cl = &cx_pointer_list_class;
 }
@@ -221,7 +221,7 @@
         __attribute__((__unused__)) struct cx_list_s const *list,
         struct cx_list_s const *other
 ) {
-    if (other->base.size == 0) return 0;
+    if (other->collection.size == 0) return 0;
     return -1;
 }
 
@@ -286,7 +286,7 @@
 ) {
     if (
         // if one is storing pointers but the other is not
-        (list->base.store_pointer ^ other->base.store_pointer) ||
+        (list->collection.store_pointer ^ other->collection.store_pointer) ||
 
         // if one class is wrapped but the other is not
         ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
@@ -296,13 +296,13 @@
          (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
     ) {
         // lists are definitely different - cannot use internal compare function
-        if (list->base.size == other->base.size) {
+        if (list->collection.size == other->collection.size) {
             CxIterator left = list->cl->iterator(list, 0, false);
             CxIterator right = other->cl->iterator(other, 0, false);
-            for (size_t i = 0; i < list->base.size; i++) {
+            for (size_t i = 0; i < list->collection.size; i++) {
                 void *leftValue = cxIteratorCurrent(left);
                 void *rightValue = cxIteratorCurrent(right);
-                int d = list->base.cmpfunc(leftValue, rightValue);
+                int d = list->collection.cmpfunc(leftValue, rightValue);
                 if (d != 0) {
                     return d;
                 }
@@ -311,7 +311,7 @@
             }
             return 0;
         } else {
-            return list->base.size < other->base.size ? -1 : 1;
+            return list->collection.size < other->collection.size ? -1 : 1;
         }
     } else {
         // lists are compatible
--- a/tests/test_hash_map.c	Thu May 23 20:31:37 2024 +0200
+++ b/tests/test_hash_map.c	Thu May 23 20:43:04 2024 +0200
@@ -42,19 +42,19 @@
         for(size_t i = 0 ; i < hmap->bucket_count ; i++) {
             CX_TEST_ASSERT(hmap->buckets[i] == NULL);
         }
-        CX_TEST_ASSERT(map->base.elem_size == 1);
-        CX_TEST_ASSERT(map->base.size == 0);
-        CX_TEST_ASSERT(map->base.allocator == allocator);
-        CX_TEST_ASSERT(!map->base.store_pointer);
-        CX_TEST_ASSERT(map->base.cmpfunc == NULL);
-        CX_TEST_ASSERT(map->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(map->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(map->base.destructor_data == NULL);
+        CX_TEST_ASSERT(map->collection.elem_size == 1);
+        CX_TEST_ASSERT(map->collection.size == 0);
+        CX_TEST_ASSERT(map->collection.allocator == allocator);
+        CX_TEST_ASSERT(!map->collection.store_pointer);
+        CX_TEST_ASSERT(map->collection.cmpfunc == NULL);
+        CX_TEST_ASSERT(map->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(map->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(map->collection.destructor_data == NULL);
         cxMapStorePointers(map);
-        CX_TEST_ASSERT(map->base.store_pointer);
-        CX_TEST_ASSERT(map->base.elem_size == sizeof(void *));
+        CX_TEST_ASSERT(map->collection.store_pointer);
+        CX_TEST_ASSERT(map->collection.elem_size == sizeof(void *));
         cxMapStoreObjects(map);
-        CX_TEST_ASSERT(!map->base.store_pointer);
+        CX_TEST_ASSERT(!map->collection.store_pointer);
 
         cxMapDestroy(map);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
@@ -73,10 +73,10 @@
         for (size_t i = 0; i < hmap->bucket_count; i++) {
             CX_TEST_ASSERT(hmap->buckets[i] == NULL);
         }
-        CX_TEST_ASSERT(map->base.size == 0);
-        CX_TEST_ASSERT(map->base.allocator == allocator);
-        CX_TEST_ASSERT(map->base.store_pointer);
-        CX_TEST_ASSERT(map->base.elem_size == sizeof(void *));
+        CX_TEST_ASSERT(map->collection.size == 0);
+        CX_TEST_ASSERT(map->collection.allocator == allocator);
+        CX_TEST_ASSERT(map->collection.store_pointer);
+        CX_TEST_ASSERT(map->collection.elem_size == sizeof(void *));
 
         cxMapDestroy(map);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
@@ -106,7 +106,7 @@
         int result = cxMapRehash(map);
         CX_TEST_ASSERT(result == 0);
         CX_TEST_ASSERT(((struct cx_hash_map_s *)map)->bucket_count == 25);
-        CX_TEST_ASSERT(map->base.size == 10);
+        CX_TEST_ASSERT(map->collection.size == 10);
 
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key 1"), "val 1"));
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key 2"), "val 2"));
@@ -161,11 +161,11 @@
         cxMapPut(map, "key 2", (void *) "val 2");
         cxMapPut(map, "key 3", (void *) "val 3");
 
-        CX_TEST_ASSERT(map->base.size == 3);
+        CX_TEST_ASSERT(map->collection.size == 3);
 
         cxMapClear(map);
 
-        CX_TEST_ASSERT(map->base.size == 0);
+        CX_TEST_ASSERT(map->collection.size == 0);
         CX_TEST_ASSERT(cxMapGet(map, "key 1") == NULL);
         CX_TEST_ASSERT(cxMapGet(map, "key 2") == NULL);
         CX_TEST_ASSERT(cxMapGet(map, "key 3") == NULL);
@@ -208,7 +208,7 @@
 
         // remove a string
         cxMapRemove(map, "s2");
-        CX_TEST_ASSERT(map->base.size == 3);
+        CX_TEST_ASSERT(map->collection.size == 3);
 
         // iterate
         bool s3found = false, s4found = false, s5found = false;
@@ -244,8 +244,8 @@
         cx_foreach(CxMapEntry*, entry, iter) {
             if (((char const *)entry->key->data)[4] % 2 == 1) cxIteratorFlagRemoval(iter);
         }
-        CX_TEST_ASSERT(map->base.size == 3);
-        CX_TEST_ASSERT(iter.index == map->base.size);
+        CX_TEST_ASSERT(map->collection.size == 3);
+        CX_TEST_ASSERT(iter.index == map->collection.size);
 
         CX_TEST_ASSERT(cxMapGet(map, "key 1") == NULL);
         CX_TEST_ASSERT(cxMapGet(map, "key 2") != NULL);
@@ -348,7 +348,7 @@
     CxAllocator *allocator = &talloc.base;
     CX_TEST_DO {
         CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
-        map->base.simple_destructor = test_simple_destructor;
+        map->collection.simple_destructor = test_simple_destructor;
         CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
     }
@@ -361,7 +361,7 @@
     CxAllocator *allocator = &talloc.base;
     CX_TEST_DO {
         CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
-        map->base.advanced_destructor = test_advanced_destructor;
+        map->collection.advanced_destructor = test_advanced_destructor;
         CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
     }
@@ -370,7 +370,8 @@
 
 CX_TEST(test_empty_map_size) {
     CX_TEST_DO {
-        CX_TEST_ASSERT(cxEmptyMap->base.size == 0);
+        CX_TEST_ASSERT(cxEmptyMap->collection.size == 0);
+        CX_TEST_ASSERT(cxMapSize(cxEmptyMap) == 0);
     }
 }
 
@@ -430,7 +431,7 @@
         cxMapPut(map, cx_mutstr("foo"), "bar");
         cxMapPut(map, cx_str("hallo"), "welt");
 
-        CX_TEST_ASSERT(map->base.size == 3);
+        CX_TEST_ASSERT(map->collection.size == 3);
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "test"), "test"));
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "foo"), "bar"));
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "hallo"), "welt"));
@@ -441,16 +442,16 @@
         cxMapDetach(map, hallo);
         cxMapPut(map, cx_hash_key_str("key"), "value");
 
-        CX_TEST_ASSERT(map->base.size == 2);
+        CX_TEST_ASSERT(map->collection.size == 2);
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "key"), "value"));
         CX_TEST_ASSERT(0 == strcmp(cxMapGet(map, "foo"), "bar"));
 
         void *r;
         r = cxMapRemoveAndGet(map, "key");
         r = cxMapRemoveAndGet(map, cx_str("foo"));
-        if (r != NULL) map->base.size = 47;
+        if (r != NULL) map->collection.size = 47;
 
-        CX_TEST_ASSERT(map->base.size == 0);
+        CX_TEST_ASSERT(map->collection.size == 0);
 
         cxMapDestroy(map);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
@@ -539,21 +540,21 @@
 
 static CX_TEST_SUBROUTINE(verify_map_contents, CxMap *map) {
     // verify that the reference map has same size (i.e. no other keys are mapped)
-    CX_TEST_ASSERT(map->base.size == test_map_reference_size());
+    CX_TEST_ASSERT(map->collection.size == test_map_reference_size());
 
     // verify key iterator
     {
         // collect the keys from the map iterator
         CxIterator keyiter = cxMapIteratorKeys(map);
         CX_TEST_ASSERT(keyiter.elem_size == sizeof(CxHashKey));
-        CX_TEST_ASSERT(keyiter.elem_count == map->base.size);
-        CxHashKey *keys = calloc(map->base.size, sizeof(CxHashKey));
+        CX_TEST_ASSERT(keyiter.elem_count == map->collection.size);
+        CxHashKey *keys = calloc(map->collection.size, sizeof(CxHashKey));
         cx_foreach(CxHashKey*, elem, keyiter) {
             keys[keyiter.index] = *elem;
         }
-        CX_TEST_ASSERT(keyiter.index == map->base.size);
+        CX_TEST_ASSERT(keyiter.index == map->collection.size);
         // verify that all keys are mapped to values in reference map
-        for (size_t i = 0 ; i < map->base.size ; i++) {
+        for (size_t i = 0 ; i < map->collection.size ; i++) {
             cxmutstr ksz = cx_strdup(cx_strn(keys[i].data, keys[i].len));
             CX_TEST_ASSERT(test_map_reference_get(ksz.ptr) != NULL);
             cx_strfree(&ksz);
@@ -566,15 +567,15 @@
         // by using that the values in our test data are unique strings
         // we can re-use a similar approach as above
         CxIterator valiter = cxMapIteratorValues(map);
-        CX_TEST_ASSERT(valiter.elem_size == map->base.elem_size);
-        CX_TEST_ASSERT(valiter.elem_count == map->base.size);
-        char const** values = calloc(map->base.size, sizeof(char const*));
+        CX_TEST_ASSERT(valiter.elem_size == map->collection.elem_size);
+        CX_TEST_ASSERT(valiter.elem_count == map->collection.size);
+        char const** values = calloc(map->collection.size, sizeof(char const*));
         cx_foreach(char const*, elem, valiter) {
             values[valiter.index] = elem;
         }
-        CX_TEST_ASSERT(valiter.index == map->base.size);
+        CX_TEST_ASSERT(valiter.index == map->collection.size);
         // verify that all values are present in the reference map
-        for (size_t i = 0 ; i < map->base.size ; i++) {
+        for (size_t i = 0 ; i < map->collection.size ; i++) {
             bool found = false;
             for (size_t j = 0; j < test_map_reference_len ; j++) {
                 if (test_map_reference[j].value == values[i]) {
@@ -591,16 +592,16 @@
     {
         CxIterator pairiter = cxMapIterator(map);
         CX_TEST_ASSERT(pairiter.elem_size == sizeof(CxMapEntry));
-        CX_TEST_ASSERT(pairiter.elem_count == map->base.size);
-        struct test_map_kv *pairs = calloc(map->base.size, sizeof(struct test_map_kv));
+        CX_TEST_ASSERT(pairiter.elem_count == map->collection.size);
+        struct test_map_kv *pairs = calloc(map->collection.size, sizeof(struct test_map_kv));
         cx_foreach(CxMapEntry*, entry, pairiter) {
             CxHashKey const *key = entry->key;
             pairs[pairiter.index].key = cx_strdup(cx_strn(key->data, key->len)).ptr;
             pairs[pairiter.index].value = entry->value;
         }
-        CX_TEST_ASSERT(pairiter.index == map->base.size);
+        CX_TEST_ASSERT(pairiter.index == map->collection.size);
         // verify that all pairs are present in the reference map
-        for (size_t i = 0 ; i < map->base.size ; i++) {
+        for (size_t i = 0 ; i < map->collection.size ; i++) {
             CX_TEST_ASSERT(test_map_reference_get(pairs[i].key) == pairs[i].value);
             // this was strdup'ed
             free((void*)pairs[i].key);
--- a/tests/test_list.c	Thu May 23 20:31:37 2024 +0200
+++ b/tests/test_list.c	Thu May 23 20:43:04 2024 +0200
@@ -622,7 +622,7 @@
 
 CX_TEST(test_empty_list_size) {
     CX_TEST_DO {
-        CX_TEST_ASSERT(cxEmptyList->base.size == 0);
+        CX_TEST_ASSERT(cxEmptyList->collection.size == 0);
         CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0);
     }
 }
@@ -706,13 +706,13 @@
     CX_TEST_DO {
         CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int));
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == alloc);
-        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_int);
+        CX_TEST_ASSERT(list->collection.allocator == alloc);
+        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int);
         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
         cxListDestroy(list);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
@@ -724,13 +724,13 @@
     CxList *list = cxLinkedListCreateSimple(sizeof(int));
     CX_TEST_DO {
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(list->base.cmpfunc == NULL);
+        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
+        CX_TEST_ASSERT(list->collection.cmpfunc == NULL);
         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
     }
     cxListDestroy(list);
@@ -741,7 +741,7 @@
     CX_TEST_DO {
         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
         cxListStorePointers(list);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(void *));
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void *));
         CX_TEST_ASSERT(list->cl != NULL);
         CX_TEST_ASSERT(list->climpl != NULL);
         CX_TEST_ASSERT(cxListIsStoringPointers(list));
@@ -757,13 +757,13 @@
     CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
     CX_TEST_DO {
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(void*));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_ptr);
+        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
+        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr);
         CX_TEST_ASSERT(cxListIsStoringPointers(list));
     }
     cxListDestroy(list);
@@ -776,13 +776,13 @@
     CX_TEST_DO {
         CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8);
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == alloc);
-        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_int);
+        CX_TEST_ASSERT(list->collection.allocator == alloc);
+        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int);
         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
         cxListDestroy(list);
         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
@@ -794,13 +794,13 @@
     CxList *list = cxArrayListCreateSimple(sizeof(int), 8);
     CX_TEST_DO {
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(int));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(int));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(list->base.cmpfunc == NULL);
+        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
+        CX_TEST_ASSERT(list->collection.cmpfunc == NULL);
         CX_TEST_ASSERT(!cxListIsStoringPointers(list));
     }
     cxListDestroy(list);
@@ -810,13 +810,13 @@
     CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8);
     CX_TEST_DO {
         CX_TEST_ASSERT(list != NULL);
-        CX_TEST_ASSERT(list->base.elem_size == sizeof(void*));
-        CX_TEST_ASSERT(list->base.simple_destructor == NULL);
-        CX_TEST_ASSERT(list->base.advanced_destructor == NULL);
-        CX_TEST_ASSERT(list->base.destructor_data == NULL);
+        CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*));
+        CX_TEST_ASSERT(list->collection.simple_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.advanced_destructor == NULL);
+        CX_TEST_ASSERT(list->collection.destructor_data == NULL);
         CX_TEST_ASSERT(cxListSize(list) == 0);
-        CX_TEST_ASSERT(list->base.allocator == cxDefaultAllocator);
-        CX_TEST_ASSERT(list->base.cmpfunc == cx_cmp_ptr);
+        CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator);
+        CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr);
         CX_TEST_ASSERT(cxListIsStoringPointers(list));
     }
     cxListDestroy(list);
@@ -848,7 +848,7 @@
     CX_TEST_DO {
         int item = 0;
         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
-        list->base.simple_destructor = test_fake_simple_int_destr;
+        list->collection.simple_destructor = test_fake_simple_int_destr;
         cxListAdd(list, &item);
         cxListDestroy(list);
         CX_TEST_ASSERT(item == 42);
@@ -862,8 +862,8 @@
     CX_TEST_DO {
         void *item = cxMalloc(alloc, sizeof(int));
         CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
-        list->base.destructor_data = alloc;
-        list->base.advanced_destructor = (cx_destructor_func2) cxFree;
+        list->collection.destructor_data = alloc;
+        list->collection.advanced_destructor = (cx_destructor_func2) cxFree;
         cxListAdd(list, item);
         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
         cxListDestroy(list);
@@ -894,7 +894,7 @@
     CX_TEST_DO {
         int item = 0;
         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
-        list->base.simple_destructor = test_fake_simple_int_destr;
+        list->collection.simple_destructor = test_fake_simple_int_destr;
         cxListAdd(list, &item);
         cxListDestroy(list);
         CX_TEST_ASSERT(item == 42);
@@ -908,8 +908,8 @@
     CX_TEST_DO {
         void *item = cxMalloc(alloc, sizeof(int));
         CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
-        list->base.destructor_data = alloc;
-        list->base.advanced_destructor = (cx_destructor_func2) cxFree;
+        list->collection.destructor_data = alloc;
+        list->collection.advanced_destructor = (cx_destructor_func2) cxFree;
         cxListAdd(list, item);
         CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
         cxListDestroy(list);
@@ -1207,8 +1207,8 @@
     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
 
     CxIterator iter = cxListIterator(list);
-    CX_TEST_ASSERT(iter.elem_size == list->base.elem_size);
-    CX_TEST_ASSERT(iter.elem_count == list->base.size);
+    CX_TEST_ASSERT(iter.elem_size == list->collection.elem_size);
+    CX_TEST_ASSERT(iter.elem_count == list->collection.size);
     size_t i = 0;
     cx_foreach(int*, x, iter) {
         CX_TEST_ASSERT(i == iter.index);
@@ -1225,8 +1225,8 @@
     CX_TEST_ASSERT(i == 0);
     i = len / 2;
     CxIterator mut_iter = cxListMutIteratorAt(list, i);
-    CX_TEST_ASSERT(mut_iter.elem_size == list->base.elem_size);
-    CX_TEST_ASSERT(mut_iter.elem_count == list->base.size);
+    CX_TEST_ASSERT(mut_iter.elem_size == list->collection.elem_size);
+    CX_TEST_ASSERT(mut_iter.elem_count == list->collection.size);
     size_t j = 0;
     cx_foreach(int*, x, mut_iter) {
         CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2);
@@ -1395,7 +1395,7 @@
 roll_out_test_combos(simple_destr, {
     const size_t len = 60;
     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
-    list->base.simple_destructor = simple_destr_test_fun;
+    list->collection.simple_destructor = simple_destr_test_fun;
     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
     free(testdata);
 })
@@ -1403,7 +1403,7 @@
 roll_out_test_combos(advanced_destr, {
     const size_t len = 75;
     int *testdata = int_test_data_added_to_list(list, isptrlist, len);
-    list->base.advanced_destructor = advanced_destr_test_fun;
+    list->collection.advanced_destructor = advanced_destr_test_fun;
     CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
     free(testdata);
 })

mercurial