Sat, 08 Feb 2025 20:38:05 +0100
adds documentation for destructor functions and collections
also invented some new macros for the collection.h
relates to #451
# Collections UCX defines common attributes for collections. If you want to implement an own collection data type that uses the same features, you can use the `CX_COLLECTION_BASE` macro at the beginning of your struct to roll out all members a usual UCX collection has. This macro will embed a structure in your collection that can be accessed with the member name `collection`. ```c struct my_fancy_collection_s { CX_COLLECTION_BASE; // adds a member named 'collection' struct my_collection_data_s *data; }; ``` > You can always look at the UCX list and map implementations if you need some inspiration. ## Base Attributes of a Collection The following attributes are declared by the `CX_COLLECTION_BASE` macro: | Attribute | Description | |-----------------------|----------------------------------------------------------------------------------------------------------------| | `allocator` | The [allocator](allocator.h.md) that shall be used for the collection data. | | `cmpfunc` | A function to [compare](compare.h.md) two elements. | | `elem_size` | The size of one element in bytes. | | `size` | The size, meaning the number of elements, currently stored. | | `simple_destructor` | An optional simple [destructor function](allocator.h.md#destructor-functions). | | `advanced_destructor` | An optional advanced destructor function. | | `destructor_data` | A pointer to the custom data that shall be passed to the advanced destructor. | | `store_pointer` | A `bool` indicating whether this collection stores pointers instead of the element's data. | | `sorted` | A `bool` indicating whether the elements are currently guaranteed sorted with respect to the compare function. | The attributes can be accessed directly via the `collection` member of your struct, or with the following convenience macros. ```C cxCollectionSize(c) cxCollectionElementSize(c) cxCollectionStoresPointers(c) cxCollectionSorted(c) ``` In each case the argument `c` is a pointer to your collection. The macro will then access the base data with `c->collection`. For working with destructors, the following macros are defined: ```C cxDefineDestructor(c, destr) cxDefineAdvancedDestructor(c, destr, data) // use in your collection's implementation cx_invoke_destructor(c, elem) // the following two should not be used cx_invoke_simple_destructor(c, elem) cx_invoke_advanced_destructor(c, elem) ``` With `cxDefineDestructor()` you can assign a simple [destructor function](allocator.h.md#destructor-functions) to an _instance_ of your collection. Similarly, you can assign an advanced destructor with custom `data` by using `cxDefineAdvancedDestructor`. Your collection _should_ be supporting destructors by invoking `cx_invoke_destructor()` whenever an element is removed from your collection _without_ being returned to the caller. This macro will invoke a simple destructor, if one is assigned, first, and then the advanced destructor (again, if assigned). > Destructor functions are always invoked with a pointer to the element in your collection. > If your collection is storing pointers (i.e. `cxCollectionStorePointers()` returns `true`) > the `cx_invoke_destructor()` will make sure that the pointer to the element is dereferenced first, > so that the destructor functions are _always_ invoked with pointer to the actual element. {style="note"} <seealso> <category ref="apidoc"> <a href="https://ucx.sourceforge.io/api/collection_8h.html">collection.h</a> </category> </seealso>