Vector ====== Tucker Evans v0.17, 2020-07-04 A basic vector, that hold pointers to your data structures. NOTE: There is currently no way to distinquish between a failed retrieval (pop, index, back, etc.) and returning a NULL value. Keep this in mind if you plan on storing NULL values in the vector, there are plans to fix this in the future. Types ----- +vec+ This structure holds all internal information regarding a vector. All functions (except constructors) expect a pointer to this struct as their first parameter. Functions --------- [[vec_new]] +vec* vec_new()+ ~~~~~~~~~~~~~~~~ Constructs an empty vector. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_new(); ---- `vec* vec_with_capacity(int capacity)` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Constructs an empty vector with space for +capacity+ items. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_with_capacity(16); ---- [[vec_size]] +int vec_size(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the number of elements in vector +self+. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_new(); assert(vec_size(vector) == 0); vec_push(vector, NULL); assert(vec_size(vector) == 1); ---- +int vec_capacity(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the maximun number of elements in vector +self+ before the buffer needs to be resized (does not take the current size into consideration). Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_with_capacity(16); assert(vec_capacity(vector) == 16); ---- [[vec_cp]] +vec* vec_cp(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~ Returns a copy of the vector +self+. All elements are kept in the same order. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_with_capacity(16); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec *new = vec_cp(vector); assert(strcmp(vec_pop, str2) == 0); assert(strcmp(vec_pop, str1) == 0); ---- [[vec_print]] +void vec_print(vec *self, (char* to_string(void*)))+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prints out the contents of the vector +self+ to +stdout+ (surounded by square brackets and separated by commas ','). +to_string+ is a function that takes a pointer to the type of elements stored in +self+ and returns a string representation. NOTE: Strings are freed after printing, therefore +strdup()+ should be used on any strings that are not for the sole purpose of printing here. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char* to_string(str) void *str; { return strdup(str); } int main() { char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_push(vector, str_dup(str3)); printf("VEC CONTENTS:\n\t") vec_print(vector, to_string) } ---- Output: ---- VEC_CONTENTS: [ONE,TWO,THREE] ---- [[vec_push]] +void vec_push(vec *self, void *item)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pushes +item+ into back of +self+. This may cause a resize of the internal buffer. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_new(); vec_push(vector, NULL); assert(vec_size(vector) == 1); ---- [[vec_pop]] +void* vec_pop(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ Pops an item off of the back of the vector +self+. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); assert(str_cmp(vec_pop(vector), str2) == 0); assert(str_cmp(vec_pop(vector), str1) == 0); ---- [[vec_back]] +void* vec_back(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the element at the back of the vector +self+. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); assert(strcmp(vec_back(vector), str2) == 0); ---- [[vec_set]] +void vec_set(vec *self, int index, void *item)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the element at position +index+ in +self+ to +item+. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_set(vector, 0, str2); assert(str_cmp(vec_pop(vector), str2) == 0); assert(str_cmp(vec_pop(vector), str2) == 0); ---- [[vec_index]] +void* vec_index(vec *self, int index)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the element at position +index+ of +self+. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_push(vector, str_dup(str3)); assert(str_cmp(vec_index(vector, 1), str2) == 0); ---- [[vec_insert]] +void vec_insert(vec *self, int index, void *item)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Inserts +item+ into vector +self+ at index +index+, all items after the index are pushed toward the end. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_insert(vector, 1, str_dup(str3)); assert(str_cmp(vec_index(vector, 1), str3) == 0); assert(str_cmp(vec_index(vector, 2), str2) == 0); ---- [[vec_remove]] +void vec_remove(vec *self, int index)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Element at position +index+ of +self+ is removed from vector and the remaining items are shifted towards the front. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_push(vector, str_dup(str3)); vec_remove(vector, 1); assert(vec_size == 2); assert(strcmp(vec_pop(vector), str3) == 0); assert(strcmp(vec_pop(vector), str1) == 0); ---- [[vec_swap]] +void vec_swap(vec *self, int i, int j)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Swaps elements at positions +i+ and +j+, does nothing if +i+ or +j+ are out of bounds. Examples ^^^^^^^^ [source,c] ---- #include "dvector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_swap(vector, 0, 1); assert(str_cmp(vec_index(vector, 0), str2) == 0); assert(str_cmp(vec_back(vector), str1) == 0); ---- [[vec_swap_pop]] +void* vec_swap_pop(vec *self, int index)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Swaps back element with item at +index+, and pops item now at back. Will return same element as +vec_remove(self, index)+. Does not keep order of elements, but faster that <>. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_push(vector, str_dup(str3)); assert(str_cmp(vec_swap_pop(vector, 2), str3) == 0); assert(str_cmp(vec_back(vector, str2) == 0); assert(vec_size == 2); ---- [[vec_truncate]] +void vec_truncate(vec *self, int size)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Truncates vector +self+ to +size+ elements, elements in positions > +size+ will no longer be accessable through +self+. Does nothing if +size+ > current number of elements. NOTE: Does not currently reduce memory footprint Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; char *str3 = "THREE"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_push(vector, str_dup(str3)); vec_truncate(vector, 1); assert(vec_size == 1); ---- [[vec_reserve]] +void vec_reserve(vec *self, int additional)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Reserves space for +additional+ items. May reserve more memory to avoid too many reallocations. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_with_capacity(16); vec_reserve(vector, 20); assert(vec_capacity(vector) >= 20); ---- [[vec_clear]] +void vec_clear(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Free all elements within vector +self+, and sets vector to empty (size 0). NOTE: Does not free internal memory of +self+ or +self+ itself, if this is desired <> should be called immediatly after this. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" #include char *str1 = "ONE"; char *str2 = "TWO"; vec *vector = vec_new(); vec_push(vector, str_dup(str1)); vec_push(vector, str_dup(str2)); vec_clear(vector); assert(vec_size(vector) == 0); vec_free(vector); ---- [[vec_free]] +void vec_free(vec *self)+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ Frees all internal memory and +self+. NOTE: All item pointers are still valid after a call to <>, <> should be called before if they are no longer needed to avoid memory leaks. Examples ^^^^^^^^ [source,c] ---- #include "vector.h" vec *vector = vec_new(); vec_free(vector); ----