Version 4.0 - tbd
------------------------
* adds cx_system_page_size() to allocator.h
* adds cxJsonFromString()
* changes cxFreeDefault() from a macro to a function so that it can be used as a simple destructor
* changes cxBufferReserve() to allow reducing the capacity
* changes the members of CxJson and CxJsonValue
* changes the return value of cxJsonObjIter() to CxMapIterator
* changes CxTree structure so that it now inherits CX_COLLECTION_BASE
* changes cxPropertiesLoad() to directly load properties from a file to a CxMap
* fixes cxJsonWrite() incorrectly returning non-zero when strings needed to be escaped
* fixes critical memory leak when using cxMapFree() on a kv-list that is using destructors
* fixes that overwriting items with cxMapPut() in a kv-list did not work
* fixes that cxReallocate(), cxReallocateArray(), cx_reallocate(), and cx_reallocatearray()
were not returning zero after freeing the memory when passed a size of zero
* removes the sort_members feature from CxJsonWriter
* removes the source and sink API from properties.h
Version 3.2 - 2025-11-30
------------------------
* adds cxMempoolTransfer() and cxMempoolTransferObject()
* adds support for different destruction strategies in CxMempool
* adds new key-value-based list implementation
+ adds support for integer keys to CxHashKey
* adds support for comparing arbitrary strings without explicit call to cx_strcast()
* adds clone, union, difference, and intersection functions for CxList and CxMap
* adds cxListContains() and cxMapContains()
* adds cxListReserve() and cxListShrink()
* adds cxListSet()
* adds cxListFirst() and cxListLast()
* adds cxListRemoveAndGetFirst() and cxListRemoveAndGetLast(),
and corresponding macro aliases cxListPopFront() and cxListPop()
* adds cxListEmplace(), cxListEmplaceAt(), cxListEmplaceArray(), cxListEmplaceArrayAt(), and cxMapEmplace()
* adds cxListInsertUnique() and cxListInsertUniqueArray()
* adds cx_array_insert_unique() and various convenience macros
* adds cx_linked_list_insert_unique() and cx_linked_list_insert_unique_chain()
* adds cxCollectionCompareFunc() to conveniently set a compare function for a collection
without needing to access the base struct manually
* adds cxBufferShrink()
* adds cxBufferPop()
* adds cxTreeSize()
* adds CX_PRIstr and CX_SFMT macros for formatting UCX strings
* adds cx_strcpy() and cx_strcpy_a()
* adds cxJsonArrRemove() and cxJsonObjRemove()
* adds cxStdlibAllocator and allows changes of cxDefaultAllocator
* improves performance of the CxList array list implementation
* changes over-aggressively declaring functions as static inline
* changes cx_str() and cx_mutstr() to allow NULL strings
* changes cx_strcast() to also accept C-strings as input
* changes grow strategy for the memory pool to reduce reallocations
* changes grow strategy for CxBuffer, which does now take the page size into account
* changes the implementation of cx_strreplacen() for improved efficiency
* changes all cxListIterator() and cxMapIterator() family of functions to also accept NULL as argument
* changes insert_element member function of CxList to accept NULL source and return a pointer to the inserted element
* changes the compare function wrapper for pointer lists so that it no longer invokes the actual compare function for NULL pointers
* changes struct cx_array_reallocator_s by replacing the four generic data members with two specifically named members
* changes cx_array_reserve() so that it reserves exactly the requested capacity (i.e., without overallocation)
* changes all other array functions to perform smart overallocation to avoid too many subsequent allocations
* changes that binary search and infimum always report the largest index, and supremum always reports the smallest index
when the found element appears more than once in the array
* fixes critical memory overflow in the stack-based array reallocator (this unfortunately breaks the function signature)
* fixes critical bug in cx_array_insert_sorted() that caused an infinite loop when inserting duplicates
* fixes mempool implementation not supporting NULL as argument for realloc
* fixes mempool implementation not supporting zero as size for realloc
* fixes that the elem_count member of an iterator was not updated after removing an element flagged by cxIteratorFlagRemoval()
* fixes that starting an iteration in a non-root node incorrectly continues iteration with the siblings of that node
* fixes unnecessary allocations in cx_strcat() family of functions
* fixes ineffective overflow check in cx_strcat() family of functions
* fixes errno value after failing cxBufferSeek() to be consistently EINVAL
* fixes implementation of cxBufferTerminate()
* fixes that cxBufferWrite() could auto-extend the buffer beyond the configured threshold
* fixes allocator arguments for some printf.h functions not being const
* fixes that cx_tree_search() did not investigate subtrees with equally good distance
* fixes that memory was freed by the wrong allocator in cx_vasprintf_a() when the underlying vsnprintf() failed
* removes all functions that create mutating iterators in favor of making all iterators possibly mutating
* removes the use of C23 attributes because they don't mix well with GNU attributes in GCC 15
Version 3.1 - 2025-02-11
------------------------
* adds properties.h
* adds tree.h
* adds json.h
* adds locale-independent string to number conversion functions
* adds reallocarray() like functions to allocator.h
* adds cxIterator() to create iterators over raw C arrays
* adds cxIteratorPtr() to create iterators over raw C pointer arrays
* adds cx_array_reallocator() and cx_array_default_reallocator
* adds several new array and list functions
* adds cxBufferReset()
* adds cxBufferAppend()
* adds cxBufferEnableFlushing() and cxBufferFlush()
* adds CX_BUFFER_COPY_ON_WRITE and CX_BUFFER_COPY_ON_EXTEND flags
* adds cxBufferWriteFunc and cxBufferReadFunc function pointers (for convenience)
* adds cx_cmp_ptr()
* adds cx_vcmp_* family of functions
* adds cx_sprintf() and several more variants
* adds runtime constants to read out the actual SBO sizes
* adds improved version of UCX 2 Test framework (now a self-contained header)
* adds cx_nmemb() utility function to common.h
* changes that CxMap returns own CxMapIterator to save memory in CxIterator
* changes name of cxBasicMempoolCreate() to cxMempoolCreateSimple()
* changes all functions, for which there is no dedicated xyz_a variant,
to accept NULL as allocator argument (in which case a default allocator will be used)
* changes the name of destroy functions that actually free the memory to better indicate their behavior
* changes cx_strcat variants to allow handling of ENOMEM
* changes cx_strcast() to also accept cxstring (and doing nothing in that case)
* changes the behavior of cxBufferSeek() to allow offset zero for SEEK_END
* moves cx_compare_func typedef to compare.h
* moves cx_szmul() to common.h
* moves stream copy functions to new streams.h
* removes cx_strupper() and cx_strlower() because they only do the right thing in special cases
* removes several *_m variants of functions in string.h in favor of automatic conversion
* removes utils.h
* removes flag_removal function from iterator
* removes cxMapDetach() and makes cxMapRemoveAndGet() compatible with both map variants
* removes the API for changing the store_pointer property of collections after their creation
* removes CMake
* removes GTest dependency
* removes flags to disable SBO in tests
* removes CX_LINKED_LIST_SWAP_SBO_SIZE (it's not really an optimization for linked lists)
* fixes cx_strcmp() and cx_strcasecmp() not being useful for lexicographic ordering
* fixes cx_hash_key_cxstr() evaluating the argument twice
* fixes critical bug that produced wrong results when comparing lists of different type but same size
* ends UCX 2.1 long term support
Version 3.0 - 2023-07-09
------------------------
* complete redesign from scratch
* collections can now store copies of objects and not just pointers
* collections are now dynamically implemented
* users of the library can specify own implementations of collections that work with the UCX API
* low level API for custom lists that do not use the UCX structures
* various fixes and improvements
* drops some other, rarely used, features
* removes testing implementation from the lib
Version 2.1 - 2019-12-30
------------------------
* adds string replace functions
* adds set operations for UcxList and UcxMap
* adds sstrcaseprefix() and sstrcasesuffix()
* improves Doxygen documentation in ucx/string.h
* adds UcxArray data type
* adds support for CMake builds, but main build system is still autotools
Version 2.0 - 2018-12-28
------------------------
* some uncritical bug fixes
* overflow of sstrnlen now returns SIZE_MAX instead of zero
* adds scstr_t - a const char* variant for sstr_t
* renames utility compare functions
Version 1.1 - 2018-05-14
------------------------
* adds missing 32 bit support to integer overflow checks
* adds ucx_buffer_to_sstr() macro
* adds ucx_avl_free_content()
* adds some more compare and distance functions in utils.h
* adds SFMT() and PRIsstr convenience macros
* destructor functions for *_free_content() functions are now optional
Version 1.0.1 - 2018-01-21
--------------------------
* some bug fixes
* adds integer overflow checks
Version 1.0 - 2017-10-28
------------------------
* first stable version of UCX released