Included are array list (vector) and linked list templates.
Types defined:
NAME
- the list, used as a pointer; public fields:NAME_iterator
- a list iterator, used as a value
Functions defined:
NAME *NAME_new(void)
- allocate a new listvoid NAME_free(NAME *list)
- free the listint NAME_size(const NAME *list)
- the number of list elementsint NAME_insert(NAME *list, TYPE value, int pos)
- inserts an item to positionpos
, returns0
on failureTYPE NAME_pop(NAME *list, int pos)
- removes the item at positionpos
fromlist
and returns itTYPE NAME_get(const NAME *list, int pos)
- retrieves the item at positionpos
void NAME_set(NAME *list, TYPE value, int pos)
- sets the item on positionpos
tovalue
NAME_iterator NAME_iterate(const NAME *list)
- creates a new list iterator,NAME_next
must be called before accessing the value at its positionint NAME_next(const NAME *list, NAME_iterator *iter)
- movesiter
to the next position, returns0
if there are no more elementsTYPE NAME_get_at(const NAME *list, NAME_iterator iter)
- returns the value at the current position ofiter
void NAME_set_at(NAME *list, TYPE value, NAME_iterator iter)
- sets the item at the current position ofiter
tovalue
int NAME_insert_at(NAME *list, TYPE value, NAME_iterator iter)
- insertsvalue
tolist
at the position ofiter
(cannot be used to append to the tail of the list)TYPE NAME_pop_at(NAME *list, NAME_iterator iter)
- removes the item at the position of the iterator
All int pos
parameters have a special value -1
, which is equivalent to NAME_size(list)
in insert and NAME_size(list)-1
in pop/get/set and insert/pop/get/set on that position are O(1) in both linked and array lists.
To iterate a list, do something like NAME_iterator i; for (i=NAME_iterate(list); NAME_next(list, &i);) { do_something(NAME_get_at(list, i)); }
See list-example.c for list examples and more documentation.
alist.h implements an array list (vector), which is basically an array that is reallocated to 1.5 times its length once more space is required.
Macros:
ALIST_PROTO(TYPE, NAME)
- macro for header entries for alist containing elements of typeTYPE
, namedNAME
ALIST(TYPE, NAME)
- macro for functions for alist
Types defined (fields not exported):
NAME
- a struct representing the arraylist; fields:int len
- number of list elements, decrement (but not below0
) to pop elements from the end of the listint cap
- the length of the underlying array, do not change its valueTYPE *arr
- the array ofTYPE
elements of lengthcap
, of which the firstlen
elements are defined
NAME_iterator
- a typedef ofint
representing an index in the array; inserting or popping an element prior to or at the position of the iterator invalidates it
Additional functions defined:
NAME *NAME_new_cap(int cap)
- allocates a new alist with initial capacitycap
(NAME_new
uses8
,cap < 2
is undefined);NAME_insert
will multiply the capacity by 1.5 each time it needs more spaceint NAME_resize(NAME *list, int size)
- reallocs the list's capacity tosize
, truncates elements ifsize < NAME_size(list)
The _at
functions are no faster than the versions used with an index; get and set are O(1), insert and pop are O(n) except on the tail, where they are O(1).
To manually iterate an alist, export its struct and do int i; for (i=0; i<list->len; ++i) { do_something(list->arr[i]); }
llist.h implements a singly-linked list.
Macros:
LLIST_PROTO(TYPE, NAME)
- macro for header entries for llist containingTYPE
elements, namedNAME
LLIST(TYPE, NAME)
- macro for functions for llist
Types defined (fields not exported):
NAME
- a struct representing the linked list; fields:int len
- number of elements in the list, has no effect on list functionsNAME_pair *first
- the first element in the listNAME_pair *last
- the last element in the list
NAME_pair
- a list element; fields:TYPE car
- the valueNAME_pair *cdr
- the next element in the list
NAME_iterator
- a struct used to traverse the list; inserting between the previous and current position of the iterator or popping the element iterator points to or the one before it invalidates it (technically, only_insert_at
and_pop_at
functions should not be used after the insert or pop of the previous element;_get_at
,_set_at
and_next
are still usable); fields:NAME_pair *prev
- the previous element in the list, used in_insert_at
and_pop_at
NAME_pair *curr
- the element the iterator points to
Additional functions defined:
NAME_pair *NAME_pair_new(TYPE value)
- allocates a new list element with the valuevalue
List inserts, pops, gets and sets on head and tail are O(1), O(n) elsewhere. _at
functions are all O(1).
To manually iterate a llist, export its struct and do NAME_pair *p; for (p=list->first; p; p=p->cdr) { do_something(p->car); }
Included is a hashmap template.
Macros:
HMAP_PROTO(KEY_TYPE, VALUE_TYPE, NAME)
- macro for header entries for a hashmap mappingKEY_TYPE
toVALUE_TYPE
, namedNAME
HMAP(KEY_TYPE, VALUE_TYPE, NAME, CMP_FUNC, HASH_FUNC)
- macro for hmap functions;int CMP_FUNC(KEY_TYPE a, KEY_TYPE b)
is used to compare keys (return a value<0
ifa<b
,0
whena==b
and>0
whena>b
) anduint32_t HASH_FUNC(KEY_TYPE key)
to generate hashes
Types defined (fields not exported):
NAME
- the hashmap; fields:int len
- the number of map entriesint cap
- the number of bucketsNAME_entry *buckets
- the hashmap bucketsdouble max_load
- the load (len/cap
) before growing to double size, default2.0
; negative to disable automatic growth at insertdouble min_load
- the load (len/cap
) before resizing to half size, default0.5
; negative to disable automatic shrinking at delete
NAME_bucket
- a bucket with entries for hash collisions; fields:int len
- the number of entries in the bucketint cap
- the length of theentries
arrayNAME_entry *entries
- an array with entries
NAME_entry
- a struct representing a map entry; fields:uint32_t hash
- the hash of the keyKEY_TYPE key
- the keyVALUE_TYPE value
- the value
NAME_iterator
- a struct used for traversing the map, invalidated with any delete or a set when no such key exists; fields:int bucket
- the index of the current bucketint entry
- the index of the entry in the current bucket
Functions defined:
NAME *NAME_new(void)
- callsNAME_new_cap(16)
NAME *NAME_new_cap(int cap)
- allocates a new hmap withcap
buckets.void NAME_free(NAME *map)
- frees the mapint NAME_size(const NAME *map)
- the number of entries currently in the mapint NAME_resize(NAME *map, int cap)
- resizes the map tocap
; returns1
on success and0
on malloc failureVALUE_TYPE NAME_get(const NAME *map, KEY_TYPE key)
- retrieves the item with keykey
; return value is the zeroedVALUE_TYPE
when no such key exists in the mapint NAME_contains(const NAME *map, KEY_TYPE key)
- returns1
ifkey
exists in the map,0
otherwiseVALUE_TYPE NAME_get_default(const NAME *map, KEY_TYPE key, VALUE_TYPE def)
- retrieves the entry with keykey
; returns the value of that entry if it exists anddef
if it doesn'tint NAME_get_contains(const NAME *map, KEY_TYPE key, VALUE_TYPE *value)
- sets*value
to the value associated withkey
(ifvalue != NULL
) and returns1
ifkey
exists in the map, otherwise it doesn't touch the valuevalue
points to and returns0
int NAME_set(NAME *map, KEY_TYPE key, VALUE_TYPE value)
- sets the map entry with keykey
tovalue
overwriting an existing entry with such key if it exists; returns0
on malloc failure,1
otherwiseint NAME_delete(NAME *map, KEY_TYPE key)
- removes the value associated withkey
from the map if it exists, otherwise does nothing; returns1
if an entry was deleted,0
otherwiseNAME_iterator NAME_iterate(NAME *map)
- creates a new map iterator,NAME_next
must be called before accessing the key or value at its positionint NAME_next(const NAME *map, NAME_iterator *iter)
- movesiter
to the next position, returns0
if there are no more entriesKEY_TYPE NAME_key_at(const NAME *map, NAME_iterator iter)
- returns the key at the current position of the iteratorVALUE_TYPE NAME_value_at(const NAME *map, NAME_iterator iter)
- returns the value at the current position of the iterator
The hashmap is automatically resized to twice its current capacity once its load reaches 2.0
and to half its size when the load falls under 0.5
.
See map-example.c for map examples and more documentation.
All code compiles with GCC with the following CFLAGS: -Wall -Werror -ansi -pedantic -pedantic-errors