General notes:
- API macros may evaluate their first argument—the pointer to the container—multiple times, so never use expressions with side effects (e.g.
&our_containers[ ++i ]) for that argument. In GCC and Clang, attempting to do so will cause a compiler warning. All other arguments are only evaluated once. - If
CC_NO_SHORT_NAMESwas declared, all API macros and functions are prefixed withcc_. - Duplicating a container handle via assignment and then operating on the duplicate will invalidate the original. Hence, only create a duplicate via assignment (including through function parameters and return values) if you have finished with the original.
- An iterator is a pointer to an element in the container or to the associated
end(orr_end, if the container supports it). In the documentation below, these pointers are referred to as "pointer-iterators". - In the documentation below,
el_tyis the container's element type andkey_tyis the container's key type (where applicable).
The following can be defined before including the library in any file:
#define CC_NO_SHORT_NAMES-
By default, CC exposes API macros without the
cc_prefix.
Define this flag to withhold the unprefixed names.
The following can be defined anywhere and affect all calls to API macros where the definition is visible:
#define CC_REALLOC our_realloc-
Causes API macros to use a custom
reallocfunction rather than the one in the standard library.
#define CC_FREE our_free-
Causes API macros to use a custom
freefunction rather than the one in the standard library.
The following function-like macros operate on all containers:
void init( <any container type> *cntr )-
Initializes
cntrfor use.
This call cannot fail (it does not allocate memory).
<any container type> initialized( <same container type> *cntr )-
Returns an initialized instance of the same type as
cntr.
This call cannot fail (it does not allocate memory).
The call is a constant expression and can therefore be used to initialize global containers at the site of their declaration, e.g.:vec( int ) our_vec = initialized( &our_vec );
bool init_clone( <any container type> *cntr, <same container type> *src )-
Initializes
cntras a shallow copy ofsrc.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
size_t size( <any container type> *cntr )-
Returns the number of elements.
void clear( <any container type> *cntr )-
Erases all elements, calling the element and key types' destructors if they exist (unless cntr is a string).
void cleanup( <any container type> *cntr )-
Erases all elements (calling the element and key types' destructors if they exist, unless the container is a string), frees any other memory associated with the container, and initializes the container for reuse.
el_ty *first( <any container type> *cntr )-
Returns a pointer-iterator to the first element, or an
endpointer-iterator if the container is empty.
el_ty *next( <any container type> *cntr, el_ty *i )-
Returns a pointer-iterator to the element after the one pointed to by
i.
Ifipoints to the last element, the return value is anendpointer-iterator.
Ifipoints tor_end, the return value is a pointer-iterator to the first element, or anendpointer-iterator if the container is empty.
el_ty *end( <any container type> *cntr )-
Returns an
endpointer-iterator for the container.
for_each( <any container type> *cntr, i_name )-
Creates a loop iterating over all elements from first to last.
This macro declares a pointer-iterator (el_ty *) namedi_name.
It is equivalent tofor( el_ty *i_name = first( cntr ); i_name != end( cntr ); i_name = next( cntr, i_name ) )and should be followed by the loop body.
A vec is a dynamic array that stores elements in contiguous memory.
Vector pointer-iterators (including end) are invalidated by any API calls that cause memory reallocation.
The following function-like macros operate on vectors:
vec( el_ty ) cntr-
Declares an uninitialized vector named
cntr.
size_t cap( vec( el_ty ) *cntr )-
Returns the current capacity.
bool reserve( vec( el_ty ) *cntr, size_t n )-
Ensures that the the capacity is large enough to accommodate
nelements.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool resize( vec( el_ty ) *cntr, size_t n )-
Sets the number of elements to
n.
Ifnis above the current size, the new elements are uninitialized.
Ifnis below the current size, the element type's destructor (if it exists) is called for each erased element.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool shrink( vec( el_ty ) *cntr )-
Shrinks the capacity to the current size.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
el_ty *get( vec( el_ty ) *cntr, size_t i )-
Returns a pointer-iterator to the element at index
i.
el_ty *push( vec( el_ty ) *cntr, el_ty el )-
Inserts
elat the end of the vector.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *push_n( vec( el_ty ) *cntr, el_ty *els, size_t n )-
Inserts
nelements from arrayelsat the end of the vector.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
el_ty *insert( vec( el_ty ) *cntr, size_t i, el_ty el )-
Inserts
elat indexi.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *insert_n( vec( el_ty ) *cntr, size_t i, el_ty *els, size_t n )-
Inserts
nelements from arrayelsat indexi.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
el_ty *erase( vec( el_ty ) *cntr, size_t i )-
Erases the element at index
i, calling the element type's destructor if it exists.
Returns a pointer-iterator to the element after the erased element, or anendpointer-iterator if there is no subsequent element.
el_ty *erase_n( vec( el_ty ) *cntr, size_t i, size_t n )-
Erases
nelements beginning at indexi, calling the element type's destructor, if it exists, for each erased element.
Returns a pointer-iterator to the element after the erased elements, or anendpointer-iterator if there is no subsequent element.
el_ty *last( vec( el_ty ) *cntr )-
Returns a pointer-iterator to the last element.
This call is synonymous withget( cntr, size( cntr ) - 1 )and assumes that the vector is not empty.
A list is a doubly linked list.
List pointer-iterators (including r_end and end) are not invalidated by any API calls besides init and cleanup, unless they point to erased elements.
The following function-like macros operate on lists:
list( el_ty ) cntr-
Declares an uninitialized list named
cntr.
el_ty *insert( list( el_ty ) *cntr, el_ty *i, el_ty el )-
Inserts
elbefore pointer-iteratori.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *push( list( el_ty ) *cntr, el_ty el )-
Inserts
elat the end of the list.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
This call is synonymous withinsert( cntr, end( cntr ), el ).
el_ty *erase( list( el_ty ) *cntr, el_ty *i )-
Erases the element pointed to by pointer-iterator
i, calling the element type's destructor if it exists.
Returns a pointer-iterator to the element afteri, or anendpointer-iterator ifiwas the last element.
bool splice( list( el_ty ) *cntr, el_ty *i, list( el_ty ) src, el_ty *src_i )-
Removes the element pointed to by pointer-iterator
src_ifromsrcand inserts it before the element pointed to by pointer-iteratoriincntr.
Returnstrue, orfalseif unsuccessful.
This call only allocates memory, and therefore can only fail, if the list has not had any element inserted, pushed, or spliced into it since it was initialized.
el_ty *last( list( el_ty ) *cntr )-
Returns a pointer-iterator to the last element, or an
r_endpointer-iterator if the list is empty.
el_ty *prev( list( el_ty ) *cntr, el_ty *i )-
Returns a pointer-iterator to the element before the one pointed to by
i.
Ifipoints to the first element, the return value is anr_endpointer-iterator.
Ifipoints toend, then the return value is a pointer-iterator to the last element, or anr_endpointer-iterator if the list is empty.
el_ty *r_end( list( el_ty ) *cntr )-
Returns an
r_end(reverse end) pointer-iterator for the list.
r_for_each( list( el_ty ) *cntr, i_name )-
Creates a loop iterating over all elements from last to first.
This macro declares anel_ty *pointer-iterator namedi_name.
It is equivalent tofor( el_ty *i_name = last( cntr ); i_name != r_end( cntr ); i_name = prev( cntr, i_name ) )and should be followed by the body of the loop.
A map is an unordered associative container mapping elements to keys, implemented as a hybrid open-addressing, chained hash table.
Map pointer-iterators (including end) may be invalidated by any API calls that cause memory reallocation.
The following function-like macros operate on maps:
map( key_ty, el_ty ) cntr-
Declares an uninitialized map named
cntr.
key_tymust be a type, or alias for a type, for which comparison and hash functions have been defined (this requirement is enforced internally such that neglecting it causes a compiler error).
For types with in-built comparison and hash functions, and for details on how to declare new comparison and hash functions, see Destructor, comparison, and hash functions and custom max load factors below.
size_t cap( map( key_ty, el_ty ) *cntr )-
Returns the current capacity, i.e. bucket count.
Note that the number of elements a map can accommodate without rehashing is not its capacity but its capacity multiplied by the max load factor associated with its key type.
bool reserve( map( key_ty, el_ty ) *cntr, size_t n )-
Ensures that the capacity is large enough to accommodate
nelements without rehashing.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool shrink( map( key_ty, el_ty ) *cntr )-
Shrinks the capacity to best accommodate the current size.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
el_ty *insert( map( key_ty, el_ty ) *cntr, key_ty key, el_ty el )-
Inserts element
elwith the specified key.
If an element with the same key already exists, the existing element is replaced.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *get( map( key_ty, el_ty ) *cntr, key_ty key )-
Returns a pointer-iterator to the element with the specified key, or
NULLif no such element exists.
el_ty *get_or_insert( map( key_ty, el_ty ) *cntr, key_ty key, el_ty el )-
Inserts element
elif no element with the specified key already exists.
Returns a pointer-iterator to the new element if it was inserted, or a pointer-iterator to the existing element with the same key, orNULLin the case of memory allocation failure.
Determine whether an element was inserted by comparing the map's size before and after the call.
const key_ty *key_for( map( key_ty, el_ty ) *cntr, el_ty *i )-
Returns a
constpointer to the key for the element pointed to by pointer-iteratori.
bool erase( map( key_ty, el_ty ) *cntr, key_ty key )-
Erases the element with the specified key, if it exists.
Returnstrueif an element was erased, orfalseif no such element exists.
el_ty *erase_itr( map( key_ty, el_ty ) *cntr, el_ty *i )-
Erases the element pointed to by pointer-iterator
i.
Returns a pointer-iterator to the next element in the map, or anendpointer-iterator if the erased element was the last one.
for_each( map( key_ty, el_ty ) *cntr, key_ptr_name, i_name )-
Creates a loop iterating over all elements from first to last, with easy access to the corresponding keys.
This macro declares a pointer to the key (const key_ty *) namedkey_ptr_nameand a pointer-iterator (el_ty *) namedi_name.
It should be followed by the body of the loop.
A set is an unordered associative container for elements without a separate key, implemented as a hybrid open-addressing, chained hash table.
Set pointer-iterators (including end) may be invalidated by any API calls that cause memory reallocation.
The following function-like macros operate on sets:
set( el_ty ) cntr-
Declares an uninitialized set named
cntr.
el_tymust be a type, or alias for a type, for which comparison and hash functions have been defined (this requirement is enforced internally such that neglecting it causes a compiler error).
For types with in-built comparison and hash functions, and for details on how to declare new comparison and hash functions, see Destructor, comparison, and hash functions and custom max load factors below.
size_t cap( set( el_ty ) *cntr )-
Returns the current capacity, i.e. bucket count.
Note that the number of elements a set can accommodate without rehashing is not its capacity but its capacity multiplied by the max load factor associated with its key type.
bool reserve( set( el_ty ) *cntr, size_t n )-
Ensures that the capacity is large enough to accommodate
nelements without rehashing.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool shrink( set( el_ty ) *cntr )-
Shrinks the capacity to best accommodate the current size.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
el_ty *insert( set( el_ty ) *cntr, el_ty el )-
Inserts element
el.
If the element already exists, the existing element is replaced.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *get( set( el_ty ) *cntr, el_ty el )-
Returns a pointer-iterator to element
el, orNULLif no such element exists.
el_ty *get_or_insert( set( el_ty ) *cntr, el_ty el )-
Inserts element
elif it does not already exist.
Returns a pointer-iterator to the new element if it was inserted, or a pointer-iterator to the existing element, orNULLin the case of memory allocation failure.
Determine whether an element was inserted by comparing the set's size before and after the call.
bool erase( set( el_ty ) *cntr, el_ty el )-
Erases the element
el, if it exists.
Returnstrueif an element was erased, orfalseif no such element exists.
el_ty *erase_itr( set( el_ty ) *cntr, el_ty *i )-
Erases the element pointed to by pointer-iterator
i.
Returns a pointer-iterator to the next element in the set, or anendpointer-iterator if the erased element was the last one.
An omap is an ordered associative container mapping elements to keys, implemented as a red-black tree.
Ordered map pointer-iterators (including r_end and end) are not invalidated by any API calls besides init and cleanup, unless they point to erased elements.
The following function-like macros operate on ordered maps:
omap( key_ty, el_ty ) cntr-
Declares an uninitialized ordered map named
cntr.
key_tymust be a type, or alias for a type, for which a comparison function has been defined (this requirement is enforced internally such that neglecting it causes a compiler error).
For types with in-built comparison functions, and for details on how to declare new comparison functions, see Destructor, comparison, and hash functions and custom max load factors below.
el_ty *insert( omap( key_ty, el_ty ) *cntr, key_ty key, el_ty el )-
Inserts element
elwith the specified key.
If an element with the same key already exists, the existing element is replaced.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *get( omap( key_ty, el_ty ) *cntr, key_ty key )-
Returns a pointer-iterator to the element with the specified key, or
NULLif no such element exists.
el_ty *get_or_insert( omap( key_ty, el_ty ) *cntr, key_ty key, el_ty el )-
Inserts element
elif no element with the specified key already exist.
Returns a pointer-iterator to the new element if it was inserted, or a pointer-iterator to the existing element with the same key, orNULLin the case of memory allocation failure.
Determine whether an element was inserted by comparing the ordered map's size before and after the call.
const key_ty *key_for( omap( key_ty, el_ty ) *cntr, el_ty *i )-
Returns a
constpointer to the key for the element pointed to by pointer-iteratori.
bool erase( omap( key_ty, el_ty ) *cntr, key_ty key )-
Erases the element with the specified key, if it exists.
Returnstrueif an element was erased, orfalseif no such element exists.
el_ty *erase_itr( omap( key_ty, el_ty ) *cntr, el_ty *i )-
Erases the element pointed to by pointer-iterator
i.
Returns a pointer-iterator to the next element in the ordered map, or an end pointer-iterator if the erased element was the last one.
el_ty *first( omap( key_ty, el_ty ) *cntr, key_ty key )-
Returns a pointer-iterator to the first element with a key greater than or equal to the specified key, or an
endpointer-iterator if no such element exists.
el_ty *last( omap( key_ty, el_ty ) *cntr )-
Returns a pointer-iterator to the last element, or an
r_endpointer-iterator if the ordered map is empty.
el_ty *last( omap( key_ty, el_ty ) *cntr, key_ty key )-
Returns a pointer-iterator to the last element with a key less than or equal to the specified key, or an
r_endpointer-iterator if the ordered map is empty.
el_ty *prev( omap( key_ty, el_ty ) *cntr, el_ty *i )-
Returns a pointer-iterator to the element before the one pointed to by
i.
Ifipoints to the first element, the value returned is anr_endpointer-iterator.
Ifipoints toend, then the value returned points to the last element, or is anr_endpointer-iterator if the ordered map is empty.
el_ty *r_end( omap( key_ty, el_ty ) *cntr )-
Returns an
r_end(reverse end) pointer-iterator for the ordered map.
for_each( omap( key_ty, el_ty ) *cntr, key_ptr_name, i_name )-
Creates a loop iterating over all elements from first to last, with easy access to the corresponding keys.
This macro declares a pointer to the key (const key_ty *) namedkey_ptr_nameand a pointer-iterator (el_ty *) namedi_name.
It should be followed by the body of the loop.
r_for_each( omap( key_ty, el_ty ) *cntr, i_name )-
Creates a loop iterating over all elements from last to first.
This macro declares anel_ty *pointer-iterator namedi_name.
It is equivalent tofor( el_ty *i_name = last( cntr ); i_name != r_end( cntr ); i_name = prev( cntr, i_name ) )and should be followed by the body of the loop.
r_for_each( omap( key_ty, el_ty ) *cntr, key_ptr_name, i_name )-
Creates a loop iterating over all elements from last to first, with easy access to the corresponding keys.
This macro declares a pointer to the key (const key_ty *) namedkey_ptr_nameand a pointer-iterator (el_ty *) namedi_name.
It should be followed by the body of the loop.
An oset is an ordered associative container for elements without a separate key, implemented as a red-black tree.
Ordered set pointer-iterators (including r_end and end) may be invalidated by any API calls that cause memory reallocation.
The following function-like macros operate on ordered sets:
oset( el_ty ) cntr-
Declares an uninitialized ordered set named
cntr.
el_tymust be a type, or alias for a type, for which a comparison function has been defined (this requirement is enforced internally such that neglecting it causes a compiler error).
For types with in-built comparison functions, and for details on how to declare new comparison functions, see Destructor, comparison, and hash functions and custom max load factors below.
el_ty *insert( oset( el_ty ) *cntr, el_ty el )-
Inserts element
el.
If the element already exists, the existing element is replaced.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *get( oset( el_ty ) *cntr, el_ty el )-
Returns a pointer-iterator to element
el, orNULLif no such element exists.
el_ty *get_or_insert( oset( el_ty ) *cntr, el_ty el )-
Inserts element
elif it does not already exist.
Returns a pointer-iterator to the new element if it was inserted, or a pointer-iterator to the existing element, orNULLin the case of memory allocation failure.
Determine whether an element was inserted by comparing the ordered set's size before and after the call.
bool erase( oset( el_ty ) *cntr, el_ty el )-
Erases the element
el, if it exists.
Returnstrueif an element was erased, orfalseif no such element exists.
el_ty *erase_itr( oset( el_ty ) *cntr, el_ty *i )-
Erases the element pointed to by pointer-iterator
i.
Returns a pointer-iterator to the next element in the ordered set, or anendpointer-iterator if the erased element was the last one.
el_ty *first( oset( key_ty, el_ty ) *cntr, el_ty el )-
Returns a pointer-iterator to the first element greater than or equal to
el, or anendpointer-iterator if no such element exists.
el_ty *last( oset( el_ty ) *cntr )-
Returns a pointer-iterator to the last element, or an
r_endpointer-iterator if the ordered set is empty.
el_ty *last( oset( key_ty, el_ty ) *cntr, el_ty el )-
Returns a pointer-iterator to the last element less than or equal to
el, or anendpointer-iterator if no such element exists.
el_ty *prev( oset( el_ty ) *cntr, el_ty *i )-
Returns a pointer-iterator to the element before the one pointed to by
i.
Ifipoints to the first element, the return value is anr_endpointer-iterator.
Ifipoints toend, then the pointer-iterator returned points to the last element, or is anr_endpointer-iterator if the ordered set is empty.
el_ty *r_end( oset( el_ty ) *cntr )-
Returns an
r_end(reverse end) pointer-iterator for the ordered set.
r_for_each( oset( el_ty ) *cntr, i_name )-
Creates a loop iterating over all elements from last to first.
This macro declares anel_ty *pointer-iterator namedi_name.
It is equivalent tofor( el_ty *i_name = last( cntr ); i_name != r_end( cntr ); i_name = prev( cntr, i_name ) )and should be followed by the body of the loop.
An str is a dynamic, null-terminated array representing a sequence of characters.
Default hash, comparison, and memory-freeing destructor functions exist for all CC string types.
When CC strings are used as the key and/or element type of another container, many API macros that operate on the container may alternatively take, as their key and/or element argument, a regular C string of the corresponding character type. For more details, see Heterogeneous string insertion and lookup below.
String pointer-iterators (including end) are invalidated by any API calls that cause memory reallocation.
The following function-like macros operate on strings:
str( el_ty ) cntr-
Declares an uninitialized string named
cntr.
el_tymust bechar,unsigned char,signed char,char8_t,char16_t,char32_t, or an alias for one of these types.
size_t cap( str( el_ty ) *cntr )-
Returns the current capacity, i.e. the number of elements that the string can accommodate (not including the null terminator) without reallocating its internal buffer.
bool reserve( str( el_ty ) *cntr, size_t n )-
Ensures that the capacity is large enough to accommodate
nelements.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool resize( str( el_ty ) *cntr, size_t n, el_ty fill_character )-
Sets the number of elements to
n. Ifnis above the current size, the new elements are initialized tofill_character.
Ifnis below the current size, no destructor is called for any erased element, even if a destructor for the element type has been defined.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
bool shrink( str( el_ty ) *cntr )-
Shrinks the capacity to the current size.
Returnstrue, orfalseif unsuccessful due to memory allocation failure.
el_ty *get( str( el_ty ) *cntr, size_t i )-
Returns a pointer-iterator to the element at index
i.
el_ty *push( str( el_ty ) *cntr, el_ty el )-
Inserts
elat the end of the string.
Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *push_fmt( str( el_ty ) *cntr, ... )-
Inserts up to 32 formatted values, provided as variadic arguments, at the end of the string.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
Each variadic argument must be one of the following:-
A null-terminated array of elements of the same type as
el_ty(i.e. a C string). -
A CC string with the same element type.
-
A fundamental integer type (
bool,char,unsigned char,signed char,unsigned short,short,unsigned int,int,unsigned long,long,unsigned long long, orlong long) or alias for such a type. -
A fundamental floating-point type (
floatordouble). -
A
voidpointer (to be formatted as a memory address). -
The return value of one of the following functions:
-
integer_dec( int min_digits )Causes subsequent integer arguments to be formatted as decimal integers.
min_digitsspecifies the minimum number of digits, and if the formatted integer is shorter than this number, it is padded with leading zeros. -
integer_hex( int min_digits )Causes subsequent integer arguments to be formatted as unsigned hexadecimal integers.
min_digitsspecifies the minimum number of digits, and if the formatted integer is shorter than this number, it is padded with leading zeros. -
integer_oct( int min_digits )Causes subsequent integer arguments to be formatted as unsigned octal integers.
min_digitsspecifies the minimum number of digits, and if the formatted integer is shorter than this number, it is padded with leading zeros. -
float_dec( int precision )Causes subsequent floating-point arguments to be formatted as decimal floating-point numbers.
precisionspecifies the number of decimal places to include. -
float_hex( int precision )Causes subsequent floating-point arguments to be formatted as hexadecimal floating-point numbers.
precisionspecifies the number of decimal places to include. -
float_sci( int precision )Causes subsequent floating-point arguments to be formatted using scientific notation.
precisionspecifies the number of decimal places to include. -
float_shortest( int significant_digits )Causes subsequent floating-point arguments to be formatted as decimal floating-point numbers or using scientific notation, depending on which representation is shorter.
significant_digitsspecifies the maximum number of significant digits to include.
-
Arguments are type-promoted as follows:
bool,unsigned char,unsigned short,unsigned int,unsigned long->unsigned long long.signed char,short,int,long, ->long long.char->long longorunsigned long long, depending on whethercharis signed.float->double.
By default, integer arguments are formatted as decimal integers with a minimum of one digit, and floating-point arguments are formatted as decimal floating-point numbers with two decimal places.
For formatting, C and CC strings ofchar16_tandchar32_telements are assumed to be encoded as UTF-16 and UTF-32, respectively. -
el_ty *push_n( str( el_ty ) *cntr, el_ty *els, size_t n )-
Inserts
nelements from arrayelsat the end of the string.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
el_ty *insert( str( el_ty ) *cntr, size_t i, el_ty el )-
Inserts
elat indexi. Returns a pointer-iterator to the new element, orNULLin the case of memory allocation failure.
el_ty *insert_fmt( str( el_ty ) *cntr, size_t i, ... )-
Inserts up to 32 formatted values, provided as variadic arguments, at index
i.
Each variadic argument must be one of the possibilities listed in the above documentation forpush_fmt, and the same type-promotions and encoding assumptions apply.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
el_ty *insert_n( str( el_ty ) *cntr, size_t i, el_ty *els, size_t n )-
Inserts
nelements from arrayelsat indexi.
Returns a pointer-iterator to the first new element, orNULLin the case of memory allocation failure.
el_ty *erase( str( el_ty ) *cntr, size_t i )-
Erases the element at index
i.
No destructor is called for the erased element, even if a destructor for the element type has been defined.
Returns a pointer-iterator to the element after the erased element, or an end pointer-iterator if there is no subsequent element.
el_ty *erase_n( str( el_ty ) *cntr, size_t i, size_t n )-
Erases
nelements beginning at indexi.
No destructor is called for erased elements, even if a destructor for the element type has been defined.
Returns a pointer-iterator to the element after the erased elements, or an end pointer-iterator if there is no subsequent element.
el_ty *last( str( el_ty ) *cntr )-
Returns a pointer-iterator to the last element.
This call is synonymous withget( cntr, size( cntr ) - 1 )and assumes that the string is not empty.
This part of the API allows the user to define custom destructor, comparison, and hash functions and max load factors for a type.
Once these functions are defined, any container using that type for its elements or keys will call them automatically.
Once the max load factor is defined, any map using the type for its keys and any set using the type for its elements will use the defined load factor to determine when rehashing is necessary.
#define CC_DTOR ty, { function body }
#include "cc.h"-
Defines a destructor for type
ty.
The signature of the function isvoid ( ty val ).
#define CC_CMPR ty, { function body }
#include "cc.h"-
Defines a comparison function for type
ty.
The signature of the function isint ( ty val_1, ty val_2 ).
The function should return0ifval_1andval_2are equal, a negative integer ifval_1is less thanval_2, and a positive integer ifval_1is greater thanval_2.
#define CC_HASH ty, { function body }
#include "cc.h"-
Defines a hash function for type
ty.
The signature of the function issize_t ( ty val ).
The function should return the hash ofval.
#define CC_LOAD ty, max_load_factor-
Defines the max load factor for type
ty.
max_load_factorshould be afloatordoublebetween0.0and1.0.
The default max load factor is0.9.
Trivial example:
typedef struct { int x; } our_type;
#define CC_DTOR our_type, { printf( "!%d\n", val.x ); }
#define CC_CMPR our_type, { return val_1.x < val_2.x ? -1 : val_1.x > val_2.x; }
#define CC_HASH our_type, { return val.x * 2654435761ull; }
#define CC_LOAD our_type, 0.5
#include "cc.h"Notes:
- These functions are
inlineand havestaticscope, so you need to either redefine them in each translation unit from which they should be called or (preferably) define them in a shared header. For structs or unions, a sensible place to define them is immediately after the definition of the struct or union. - Only one destructor, comparison, or hash function or max load factor should be defined by the user for each type.
- Including
cc.hin these cases does not include the full header, so you still need to include it separately at the top of your files. - In-built comparison and hash functions are already defined for the following types:
char,unsigned char,signed char,unsigned short,short,unsigned int,int,unsigned long,long,unsigned long long,long long,size_t, null-terminated C strings (char *andconst char *). Defining a comparison or hash function for one of these types will overwrite the in-built function.
When CC strings are used as the key and/or element type of another container, most API macros that operate on the container may alternatively take, as their key and/or element argument, a regular C string of the corresponding character type. In this case, CC automatically converts the C string into a CC string.
The API macros that support heterogeneous insertion are push, insert and get_or_insert.
The API macros that support heterogeneous lookup are get and erase. In this case, CC performs no memory allocations.
Trivial example:
map( str( char ), str( char ) ) our_map = initialized( &our_map );
if( insert( &our_map, "France", "Paris" ) ) // Heterogeneous insertion.
{
str( char ) *el = get( &our_map, "France" ); // Heterogeneous lookup.
printf( first( el ) );
// Printed: Paris
}