// Copyright 2023 alexevier // licensed under the zlib license #ifndef lexlib_vec_h #define lexlib_vec_h #include #include"common.h" /* Structure of Vector |head |access pointer| |size_t |any type | |len|cap|tze|data..........| this makes it posible to use as a normal array without going through struct.data[777]; just vec[777]. it just should not be freed/reallocated direcly; use lexlibVecNew(), lexlibVecDelete(), lexlibVecResize(). a example can be found at the end of this header. */ // just a way of declaring a lexlib vec to make it easier to spot // and avoid confusion with a normal array/ptr. #define LexlibVec(T) T* // create a new initialized vector, all elements are zero'ed. // len can be 0. // its undefined behavior to use the vector for a different type. // returns NULL on error (can't allocate memory). #define lexlibVecNew(len, T) lexlibVecNew_(len, sizeof(T)) LEXLIB_EXTERN void *lexlibVecNew_(size_t len, size_t typeSize); // delete a vector and its data. // does nothing if NULL. LEXLIB_EXTERN void lexlibVecDelete(void *vec); // get element from vector. // returns NULL if out of bounds (index >= vec.len). LEXLIB_EXTERN void *lexlibVecGet(const void *vec, size_t index); // push a element onto the vector; copies the object. // WARNING other pointers of the vector itself may be dangling afterwards. // returns 0 on success, nonzero otherwise (couldn't reallocate vector). #define lexlibVecPush(V, O) lexlibVecPush_((void**)&(V), O) LEXLIB_EXTERN int lexlibVecPush_(void **vec, const void *obj); // pops the last element off the vector. LEXLIB_EXTERN void lexlibVecPop(void *vec); // insert a element in the vector; copies the object. // shifts all the elements after to the right. // if index is out of bounds (index > vec.len) it will fail. // WARNING other pointers of the vector itself may be dangling afterwards. // returns 0 on success, nonzero otherwise (couldn't reallocate or invalid index). #define lexlibVecInsert(V, I, O) lexlibVecInsert_((void**)&(V), I, O) LEXLIB_EXTERN int lexlibVecInsert_(void **vec, size_t index, const void *obj); // remove a element in the vector. // shifts all the elements after to the left. // if index is out of bounds (index >= vec.len) it will fail. // returns 0 on success, nonzero otherwise (invalid index). LEXLIB_EXTERN int lexlibVecRemove(void *vec, size_t index); // resize a vector; will truncate. // WARNING other pointers of the vector itself may be dangling afterwards. // returns 0 on success, nonzero otherwise (couldn't reallocate). LEXLIB_EXTERN int lexlibVecResize(void **vec, size_t newcap); // find the first ocurrence of obj. // performs memcmp for each element; O(n) // returns NULL if the element can't be found. LEXLIB_EXTERN void *lexlibVecFind(const void *vec, const void *obj); // swap 2 elements. // returns 0 on success, nonzero otherwise (invalid index/failed to allocate tmp buffer). LEXLIB_EXTERN int lexlibVecSwap(void *vec, size_t a, size_t b); // clear the data contained by the vector. // doesn't deallocate. LEXLIB_EXTERN void lexlibVecClear(void *vec); // get the count of elements. LEXLIB_EXTERN size_t lexlibVecLen(const void *vec); // get the current capacity of the vector. LEXLIB_EXTERN size_t lexlibVecCap(const void *vec); #endif /* void lexlibVecExample(void){ // create a new vector for floats. // can aslo be declared as "float *vec = ...;" LexlibVec(float) vec = lexlibVecNew(0, *vec); float value = 777.0f; float pi = 3.14f; // push new values to the vector lexlibVecPush(vec, &value); lexlibVecPush(vec, &(float){1.234f}); // insert value lexlibVecInsert(vec, 0, &pi); // remove lexlibVecRemove(vec, 1); // access if(vec[0] != 3.14f){ printf("vec[0] is not 3.14\n"); abort(); } if(vec[1] != 1.234f){ printf("vec[1] is not 1.234\n"); abort(); } // delete/free the vector lexlibVecDelete(vec); } */