diff -r 49cc0bbea6a9 -r 155bc3b0dcb3 docs/Writerside/topics/collection.h.md --- a/docs/Writerside/topics/collection.h.md Sat Feb 08 14:24:22 2025 +0100 +++ b/docs/Writerside/topics/collection.h.md Sat Feb 08 20:38:05 2025 +0100 @@ -1,24 +1,77 @@ # Collections - -Outdated - Rewrite! - - -Collections in UCX 3 have several common features. +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; + CX_COLLECTION_BASE; // adds a member named 'collection' struct my_collection_data_s *data; }; ``` -Based on this structure, this header provides some convenience macros for invoking the destructor functions -that are part of the basic collection members. -The idea of having destructor functions within a collection is that you can destroy the collection _and_ the -contents with one single function call. -When you are implementing a collection, you are responsible for invoking the destructors at the right places, e.g. -when removing (and deleting) elements in the collection, clearing the collection, or - the most prominent case - -destroying the collection. + +> 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: -You can always look at the UCX list and map implementations if you need some inspiration. +```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"} + + + +collection.h + +