From e0cae3029de30fbb8c992d6032b8844e0d9e093d Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Tue, 11 Apr 2017 21:05:40 +1000 Subject: [PATCH] Switch darray implementation to C++ with templates --- build.bat | 2 +- dqn.h | 430 +++++++++++++++------------------------------- dqn_unit_test.cpp | 224 ++++++++++++------------ 3 files changed, 248 insertions(+), 408 deletions(-) diff --git a/build.bat b/build.bat index 355c91d..92bf34f 100644 --- a/build.bat +++ b/build.bat @@ -34,7 +34,7 @@ REM wd4100 ignore: unused argument parameters REM wd4201 ignore: nonstandard extension used: nameless struct/union REM wd4189 ignore: local variable is initialised but not referenced -set CompileFlags=-EHa- -GR- -Oi -MT -Z7 -W4 -WX -wd4100 -wd4201 -wd4189 -FC -O2 +set CompileFlags=-EHa- -GR- -Oi -MT -Z7 -W4 -WX -wd4100 -wd4201 -wd4189 -FC -Od REM Include directories set IncludeFlags= diff --git a/dqn.h b/dqn.h index 7778b82..44efa79 100644 --- a/dqn.h +++ b/dqn.h @@ -20,6 +20,11 @@ //////////////////////////////////////////////////////////////////////////////// #include "stdint.h" #include "math.h" +#define STB_SPRINTF_IMPLEMENTATION + +#ifdef _WIN32 + #define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK); +#endif #define LOCAL_PERSIST static #define FILE_SCOPE static @@ -51,88 +56,31 @@ typedef float f32; //////////////////////////////////////////////////////////////////////////////// // DArray - Dynamic Array //////////////////////////////////////////////////////////////////////////////// -// The DArray stores metadata in the header and returns you a pointer straight -// to the data, to allow direct read/modify access. Adding elements should be -// done using the provided functions since it manages internal state. - -/* - Example Usage: - - uint32_t *uintArray = DQN_DARRAY_INIT(uint32_t, 16); - uint32_t numberA = 48; - uint32_t numberB = 52; - DQN_DARRAY_PUSH(&uintArray, &numberA); - DQN_DARRAY_PUSH(&uintArray, &numberB); - - for (uint32_t i = 0; i < dqn_darray_get_num_items(uintArray); i++) - { - printf(%d\n", uintArray[i]); - } - - dqn_darray_free(uintArray); - */ - -// Typical operations should not require using the header directly, and it's -// recommended to use the API, but it can be used to have a faster way to track -// metadata. -typedef struct DqnDArrayHeader +template +struct DqnArray { - u32 index; - u32 itemSize; - u32 capacity; - u32 signature; + u64 count; + u64 capacity; + T *data; +}; - void *data; -} DqnDArrayHeader; +template +bool dqn_darray_init (DqnArray *array, size_t capacity); +template +bool dqn_darray_grow (DqnArray *array); +template +bool dqn_darray_push(DqnArray *array, T item); +template +T *dqn_darray_get (DqnArray *array, u64 index); +template +bool dqn_darray_clear(DqnArray *array); +template +bool dqn_darray_free (DqnArray *array); +template +bool dqn_darray_remove(DqnArray *array, u64 index); +template +bool dqn_darray_remove_stable(DqnArray *array, u64 index); -// Returns the DArray header IF is a valid DArray -// Returns NULL IF not a valid DArray -DQN_FILE_SCOPE DqnDArrayHeader *dqn_darray_get_header(void *array); - -// The init macro RETURNS a pointer to your type, you can index this as normal -// with array notation []. -// u32 type - The data type to initiate a dynamic array with -// u32 startingCapacity - Initial number of available slots -#define DQN_DARRAY_INIT(type, startingCapacity) \ - (type *)dqn_darray_init_internal(sizeof(type), startingCapacity) - -// Pass in the pointer returned by DQN_DARRAY_INIT. If the pointer is not -// a valid DArray pointer, this will return 0. -DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array); -DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array); - -// Returns true and array modified in-place IF -// - The capacity change was successful OR -// - The newCapacity is equal to current capacity (no changes). -// Returns false and array is unmodified IF -// - Invalid DArray passed in OR realloc failed OR -// - More items in array than new capacity -DQN_FILE_SCOPE bool dqn_darray_capacity_change(void **array, i32 newCapacity); - -// WARNING: This macro currently asserts if it's unable to push elements -// void **array - the address of the pointer returned by DQN_DARRAY_INIT -// void item - the object to insert -#define DQN_DARRAY_PUSH(array, item) \ - { \ - if (dqn_darray_capacity_grow_if_need_internal((void **)array)) \ - { \ - DqnDArrayHeader *header = dqn_darray_get_header(*array); \ - *array[header->index++] = item; \ - } \ - else \ - { \ - DQN_ASSERT(DQN_INVALID_CODE_PATH); \ - } \ - } - -DQN_FILE_SCOPE bool dqn_darray_clear (void *array); -DQN_FILE_SCOPE bool dqn_darray_remove (void *array, u32 index); -DQN_FILE_SCOPE bool dqn_darray_remove_stable(void *array, u32 index); - -// Pass in the pointer returned by DQN_DARRAY_INIT. Returns if the free was -// successful. This will return false if the array is not a valid DArray and -// won't touch the pointer. -DQN_FILE_SCOPE bool dqn_darray_free(void *array); //////////////////////////////////////////////////////////////////////////////// // Math //////////////////////////////////////////////////////////////////////////////// @@ -335,6 +283,9 @@ DQN_FILE_SCOPE i32 dqn_rnd_pcg_range(DqnRandPCGState *pcg, i32 min, i32 max); #ifdef DQN_IMPLEMENTATION #undef DQN_IMPLEMENTATION +// Enable sprintf implementation only when we enable DQN implementation +#define STB_SPRINTF_IMPLEMENTATION + #ifdef _WIN32 #define DQN_WIN32 @@ -345,239 +296,140 @@ DQN_FILE_SCOPE i32 dqn_rnd_pcg_range(DqnRandPCGState *pcg, i32 min, i32 max); //////////////////////////////////////////////////////////////////////////////// // DArray - Dynamic Array //////////////////////////////////////////////////////////////////////////////// -#define DQN_DARRAY_SIGNATURE_INTERNAL 0xAC83DB81 -FILE_SCOPE void *dqn_darray_init_internal(u32 itemSize, u32 startingCapacity) +// Implementation taken from Milton, developed by Serge at +// https://github.com/serge-rgb/milton#license +template +bool dqn_darray_init(DqnArray *array, size_t capacity) { - if (startingCapacity <= 0 || itemSize == 0) return NULL; + if (!array) return false; - u32 metadataSize = sizeof(DqnDArrayHeader); - u32 storageSize = itemSize * startingCapacity; + array->data = (T *)calloc((size_t)capacity, sizeof(T)); + if (!array->data) return false; - void *memory = calloc(1, metadataSize + storageSize); - if (!memory) return NULL; - - DqnDArrayHeader *array = (DqnDArrayHeader *)memory; - array->signature = DQN_DARRAY_SIGNATURE_INTERNAL; - array->itemSize = itemSize; - array->capacity = startingCapacity; - array->data = (u8 *)memory + metadataSize; - - return array->data; + array->count = 0; + array->capacity = capacity; + return true; } -DQN_FILE_SCOPE DqnDArrayHeader *dqn_darray_get_header(void *array) +template +bool dqn_darray_grow(DqnArray *array) { - if (!array) return NULL; + if (!array || !array->data) return false; - DqnDArrayHeader *result = (DqnDArrayHeader *)((u8 *)array - sizeof(DqnDArrayHeader)); - if (result->signature != DQN_DARRAY_SIGNATURE_INTERNAL) return NULL; + const f32 GROWTH_FACTOR = 1.2f; + size_t newCapacity = (size_t)(array->capacity * GROWTH_FACTOR); + if (newCapacity == array->capacity) newCapacity++; + T *newMem = (T *)realloc(array->data, (size_t)(newCapacity * sizeof(T))); + if (newMem) + { + array->data = newMem; + array->capacity = newCapacity; + return true; + } + else + { + return false; + } +} + +template +bool dqn_darray_push(DqnArray *array, T item) +{ + if (!array) return false; + + if (array->count >= array->capacity) + { + if (!dqn_darray_grow(array)) return false; + } + + DQN_ASSERT(array->count < array->capacity); + array->data[array->count++] = item; + + return true; +} + +template +T *dqn_darray_get(DqnArray *array, u64 index) +{ + T *result = NULL; + if (index >= 0 && index <= array->count) result = &array->data[index]; return result; } -DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array) +template +bool dqn_darray_clear(DqnArray *array) { - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (!header) return 0; - return header->capacity; -} - -DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array) -{ - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (!header) return 0; - return header->index; -} - -DQN_FILE_SCOPE bool dqn_darray_capacity_change(void **array, u32 newCapacity) -{ - DqnDArrayHeader *header = dqn_darray_get_header(*array); - if (!header) return false; - if (header->capacity == newCapacity) return true; - - if (newCapacity > header->index) + if (array) { - u32 metadataSize = sizeof(DqnDArrayHeader); - u32 storageSize = header->itemSize * newCapacity; - void *newMem = realloc(header, metadataSize + storageSize); - if (newMem) - { - header = (DqnDArrayHeader *)newMem; - header->capacity = newCapacity; - header->data = (u8 *)newMem + metadataSize; - *array = header->data; - - return true; - } - else - { - return false; - } - } - else - { - return false; - } -} - -FILE_SCOPE bool dqn_darray_capacity_grow_if_need_internal(void **array) -{ - DqnDArrayHeader *header = dqn_darray_get_header(*array); - if (!header) return false; - - if (header->index >= header->capacity) - { - const f32 GROWTH_FACTOR = 1.2f; - u32 newCapacity = (i32)(header->capacity * GROWTH_FACTOR); - if (newCapacity == header->capacity) newCapacity++; - - return dqn_darray_capacity_change(array, newCapacity); + array->count = 0; + return true; } + return false; +} + +template +bool dqn_darray_free(DqnArray *array) +{ + if (array && array->data) + { + free(array->data); + array->count = 0; + array->capacity = 0; + return true; + } + + return false; +} + +template +bool dqn_darray_remove(DqnArray *array, u64 index) +{ + if (!array) return false; + if (index >= array->count) return false; + + bool firstElementAndOnlyElement = (index == 0 && array->count == 1); + bool isLastElement = (index == (array->count - 1)); + if (firstElementAndOnlyElement || isLastElement) + { + array->count--; + return true; + } + + array->data[index] = array->data[array->count - 1]; + array->count--; return true; } -bool dqn_darray_push_internal(void **array, void *element, u32 itemSize) +template +bool dqn_darray_remove_stable(DqnArray *array, u64 index) { - if (!element || !array) return false; + if (!array) return false; + if (index >= array->count) return false; - DqnDArrayHeader *header = dqn_darray_get_header(*array); - if (!header || header->itemSize != itemSize) return false; + bool firstElementAndOnlyElement = (index == 0 && array->count == 1); + bool isLastElement = (index == (array->count - 1)); + if (firstElementAndOnlyElement || isLastElement) + { + array->count--; + return true; + } - // NOTE: Array is grown before this step happens. If at this point it still - // doesn't fit then we've had a mem alloc problem. - if (header->index >= header->capacity) - return false; + size_t itemToRemoveByteOffset = (size_t)(index * sizeof(T)); + size_t oneAfterItemToRemoveByteOffset = (size_t)((index + 1) * sizeof(T)); + size_t lastItemByteOffset = (size_t)(array->count * sizeof(T)); + size_t numBytesToMove = lastItemByteOffset - oneAfterItemToRemoveByteOffset; - u32 arrayOffset = header->itemSize * header->index++; - DQN_ASSERT(header->index <= header->capacity); - u8 *dataPtr = (u8 *)header->data; - - void *dest = (void *)&dataPtr[arrayOffset]; - void *src = element; - memcpy(dest, src, header->itemSize); + u8 *bytePtr = (u8 *)array->data; + u8 *dest = &bytePtr[itemToRemoveByteOffset]; + u8 *src = &bytePtr[oneAfterItemToRemoveByteOffset]; + memmove(dest, src, numBytesToMove); + array->count--; return true; } -DQN_FILE_SCOPE bool dqn_darray_clear(void *array) -{ - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (header) - { - header->index = 0; - return true; - } - - return false; -} - -DQN_FILE_SCOPE bool dqn_darray_remove(void *array, u32 index) -{ - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (header) - { - // NOTE: header->index is the index where the next entry will be push to - // Array is empty, or index is out of bounds - if (header->index == 0 || index >= header->index) return false; - - // If it's the first entry we just need to decrement index - if (index == 0 && header->index == 1) - { - header->index--; - return true; - } - - // If it's the last entry we just need to decrement index - if (index == (header->index - 1)) - { - header->index--; - return true; - } - - u32 lastEntryIndex = header->index - 1; - u32 lastEntryByteOffset = lastEntryIndex * header->itemSize; - u32 removeEntryIndex = index; - u32 removeEntryByteOffset = removeEntryIndex * header->itemSize; - - u8 *dataPtr = (u8 *)header->data; - void *dest = (void *)&dataPtr[removeEntryByteOffset]; - void *src = (void *)&dataPtr[lastEntryByteOffset]; - memcpy(dest, src, header->itemSize); - - header->index--; - - return true; - } - - return false; -} - -DQN_FILE_SCOPE bool dqn_darray_remove_stable(void *array, u32 index) -{ - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (header) - { - // NOTE: header->index is the index where the next entry will be push to - // Array is empty, or index is out of bounds - if (header->index == 0 || index >= header->index) return false; - - // If it's the last entry we just need to decrement index - if (index == (header->index - 1)) - { - header->index--; - return true; - } - - // If it's the first entry we just need to decrement index - if (index == 0 && header->index == 1) - { - header->index--; - return true; - } - - u32 removeEntryIndex = index; - u32 removeEntryByteOffset = removeEntryIndex * header->itemSize; - - u32 oneAfterRemove = index + 1; - u32 oneAfterRemoveByteOffset = oneAfterRemove * header->itemSize; - u32 endOfListIndex = header->index - 1; - u32 endOfListByteOffset = endOfListIndex * header->itemSize; - - u32 numBytesToShift = endOfListByteOffset - oneAfterRemoveByteOffset; - DQN_ASSERT(numBytesToShift <= (header->itemSize * header->capacity)); - - u8 *dataPtr = (u8 *)header->data; - void *dest = (void *)&dataPtr[removeEntryByteOffset]; - void *src = (void *)&dataPtr[oneAfterRemoveByteOffset]; - memmove(dest, src, endOfListByteOffset); - - header->index--; - return true; - } - - return false; -} - -DQN_FILE_SCOPE inline bool dqn_darray_free(void *array) -{ - DqnDArrayHeader *header = dqn_darray_get_header(array); - if (header) - { - header->index = 0; - header->itemSize = 0; - header->capacity = 0; - header->signature = 0; - - free(header); - return true; - } - else - { - return false; - } -} - //////////////////////////////////////////////////////////////////////////////// // Math //////////////////////////////////////////////////////////////////////////////// @@ -1387,7 +1239,6 @@ DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character) // File Operations //////////////////////////////////////////////////////////////////////////////// #ifdef DQN_WIN32 - #define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK); DQN_FILE_SCOPE bool dqn_win32_utf8_to_wchar(char *in, wchar_t *out, i32 outLen) { @@ -1690,14 +1541,13 @@ DQN_FILE_SCOPE i32 dqn_rnd_pcg_range(DqnRandPCGState *pcg, i32 min, i32 max) i32 const value = (i32)(dqn_rnd_pcg_nextf(pcg) * range); return min + value; } +#endif /* DQN_IMPLEMENTATION */ //////////////////////////////////////////////////////////////////////////////// // // STB_Sprintf // //////////////////////////////////////////////////////////////////////////////// -#define STB_SPRINTF_IMPLEMENTATION - // stb_sprintf - v1.02 - public domain snprintf() implementation // originally by Jeff Roberts / RAD Game Tools, 2015/10/20 // http://github.com/nothings/stb @@ -2896,5 +2746,3 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ - -#endif /* DQN_IMPLEMENTATION */ diff --git a/dqn_unit_test.cpp b/dqn_unit_test.cpp index aaebab9..07fd4c6 100644 --- a/dqn_unit_test.cpp +++ b/dqn_unit_test.cpp @@ -553,90 +553,89 @@ void dqn_vec_test() void dqn_darray_test() { { - DqnV2 *vecDArray = DQN_DARRAY_INIT(DqnV2, 1); - DQN_ASSERT(vecDArray); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 1); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 0); + DqnArray array = {}; + DQN_ASSERT(dqn_darray_init(&array, 1)); + DQN_ASSERT(array.capacity == 1); + DQN_ASSERT(array.count == 0); // Test basic insert { DqnV2 va = dqn_v2(5, 10); - DQN_DARRAY_PUSH(&vecDArray, va); + DQN_ASSERT(dqn_darray_push(&array, va)); - DqnV2 vb = vecDArray[0]; + DqnV2 vb = array.data[0]; DQN_ASSERT(dqn_v2_equals(va, vb)); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 1); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 1); + DQN_ASSERT(array.capacity == 1); + DQN_ASSERT(array.count == 1); } // Test array resizing and freeing { DqnV2 va = dqn_v2(10, 15); - DQN_DARRAY_PUSH(&vecDArray, va); + DQN_ASSERT(dqn_darray_push(&array, va)); - DqnV2 vb = vecDArray[0]; + DqnV2 vb = array.data[0]; DQN_ASSERT(dqn_v2_equals(va, vb) == false); - vb = vecDArray[1]; + vb = array.data[1]; DQN_ASSERT(dqn_v2_equals(va, vb) == true); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 2); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 2); + DQN_ASSERT(array.capacity == 2); + DQN_ASSERT(array.count == 2); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 3); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 3); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 3); + DQN_ASSERT(array.count == 3); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 4); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 4); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 4); + DQN_ASSERT(array.count == 4); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 5); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 5); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 5); + DQN_ASSERT(array.count == 5); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 6); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 6); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 6); + DQN_ASSERT(array.count == 6); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 7); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 7); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 7); + DQN_ASSERT(array.count == 7); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 8); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 8); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 8); + DQN_ASSERT(array.count == 8); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 9); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 9); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 9); + DQN_ASSERT(array.count == 9); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 10); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 10); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 10); + DQN_ASSERT(array.count == 10); - DQN_DARRAY_PUSH(&vecDArray, va); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 11); + DQN_ASSERT(dqn_darray_push(&array, va)); + DQN_ASSERT(array.capacity == 12); + DQN_ASSERT(array.count == 11); DqnV2 vc = dqn_v2(90, 100); - DQN_DARRAY_PUSH(&vecDArray, vc); - DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12); - DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 12); - DQN_ASSERT(dqn_v2_equals(vc, vecDArray[11])); + DQN_ASSERT(dqn_darray_push(&array, vc)); + DQN_ASSERT(array.capacity == 12); + DQN_ASSERT(array.count == 12); + DQN_ASSERT(dqn_v2_equals(vc, array.data[11])); - DQN_ASSERT(dqn_darray_free(vecDArray) == true); + DQN_ASSERT(dqn_darray_free(&array) == true); } } { - f32 *array = DQN_DARRAY_INIT(f32, 1); - DQN_ASSERT(array); - DQN_ASSERT(dqn_darray_get_capacity(array) == 1); - DQN_ASSERT(dqn_darray_get_num_items(array) == 0); - - dqn_darray_free(array); + DqnArray array = {}; + DQN_ASSERT(dqn_darray_init(&array, 1)); + DQN_ASSERT(array.capacity == 1); + DQN_ASSERT(array.count == 0); + dqn_darray_free(&array); } { @@ -645,47 +644,47 @@ void dqn_darray_test() DqnV2 c = dqn_v2(5, 6); DqnV2 d = dqn_v2(7, 8); - DqnV2 *array = DQN_DARRAY_INIT(DqnV2, 16); - DQN_ASSERT(array); - DQN_ASSERT(dqn_darray_remove(array, 0) == false); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 0); + DqnArray array = {}; + DQN_ASSERT(dqn_darray_init(&array, 16)); + DQN_ASSERT(dqn_darray_remove(&array, 0) == false); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 0); - DQN_ASSERT(dqn_darray_clear(array)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 0); + DQN_ASSERT(dqn_darray_clear(&array)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 0); - DQN_DARRAY_PUSH(&array, a); - DQN_DARRAY_PUSH(&array, b); - DQN_DARRAY_PUSH(&array, c); - DQN_DARRAY_PUSH(&array, d); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 4); + DQN_ASSERT(dqn_darray_push(&array, a)); + DQN_ASSERT(dqn_darray_push(&array, b)); + DQN_ASSERT(dqn_darray_push(&array, c)); + DQN_ASSERT(dqn_darray_push(&array, d)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 4); - DQN_ASSERT(dqn_darray_remove(array, 0)); - DQN_ASSERT(dqn_v2_equals(array[0], d)); - DQN_ASSERT(dqn_v2_equals(array[1], b)); - DQN_ASSERT(dqn_v2_equals(array[2], c)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 3); + DQN_ASSERT(dqn_darray_remove(&array, 0)); + DQN_ASSERT(dqn_v2_equals(array.data[0], d)); + DQN_ASSERT(dqn_v2_equals(array.data[1], b)); + DQN_ASSERT(dqn_v2_equals(array.data[2], c)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 3); - DQN_ASSERT(dqn_darray_remove(array, 2)); - DQN_ASSERT(dqn_v2_equals(array[0], d)); - DQN_ASSERT(dqn_v2_equals(array[1], b)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 2); + DQN_ASSERT(dqn_darray_remove(&array, 2)); + DQN_ASSERT(dqn_v2_equals(array.data[0], d)); + DQN_ASSERT(dqn_v2_equals(array.data[1], b)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 2); - DQN_ASSERT(dqn_darray_remove(array, 100) == false); - DQN_ASSERT(dqn_v2_equals(array[0], d)); - DQN_ASSERT(dqn_v2_equals(array[1], b)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 2); + DQN_ASSERT(dqn_darray_remove(&array, 100) == false); + DQN_ASSERT(dqn_v2_equals(array.data[0], d)); + DQN_ASSERT(dqn_v2_equals(array.data[1], b)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 2); - DQN_ASSERT(dqn_darray_clear(array)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 0); + DQN_ASSERT(dqn_darray_clear(&array)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 0); - dqn_darray_free(array); + dqn_darray_free(&array); } { @@ -694,43 +693,36 @@ void dqn_darray_test() DqnV2 c = dqn_v2(5, 6); DqnV2 d = dqn_v2(7, 8); - DqnV2 *array = DQN_DARRAY_INIT(DqnV2, 16); - DQN_ASSERT(array); + DqnArray array = {}; + DQN_ASSERT(dqn_darray_init(&array, 16)); - DQN_DARRAY_PUSH(&array, a); - DQN_DARRAY_PUSH(&array, b); - DQN_DARRAY_PUSH(&array, c); - DQN_DARRAY_PUSH(&array, d); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 4); + DQN_ASSERT(dqn_darray_push(&array, a)); + DQN_ASSERT(dqn_darray_push(&array, b)); + DQN_ASSERT(dqn_darray_push(&array, c)); + DQN_ASSERT(dqn_darray_push(&array, d)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 4); - dqn_darray_remove_stable(array, 0); - DQN_ASSERT(dqn_v2_equals(array[0], b)); - DQN_ASSERT(dqn_v2_equals(array[1], c)); - DQN_ASSERT(dqn_v2_equals(array[2], d)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 3); + dqn_darray_remove_stable(&array, 0); + DQN_ASSERT(dqn_v2_equals(array.data[0], b)); + DQN_ASSERT(dqn_v2_equals(array.data[1], c)); + DQN_ASSERT(dqn_v2_equals(array.data[2], d)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 3); - dqn_darray_remove_stable(array, 1); - DQN_ASSERT(dqn_v2_equals(array[0], b)); - DQN_ASSERT(dqn_v2_equals(array[1], d)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 2); + dqn_darray_remove_stable(&array, 1); + DQN_ASSERT(dqn_v2_equals(array.data[0], b)); + DQN_ASSERT(dqn_v2_equals(array.data[1], d)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 2); - dqn_darray_remove_stable(array, 1); - DQN_ASSERT(dqn_v2_equals(array[0], b)); - DQN_ASSERT(dqn_darray_get_capacity(array) == 16); - DQN_ASSERT(dqn_darray_get_num_items(array) == 1); - dqn_darray_free(array); + dqn_darray_remove_stable(&array, 1); + DQN_ASSERT(dqn_v2_equals(array.data[0], b)); + DQN_ASSERT(array.capacity == 16); + DQN_ASSERT(array.count == 1); + dqn_darray_free(&array); } - { - DQN_ASSERT(dqn_darray_clear(NULL) == false); - DQN_ASSERT(dqn_darray_clear(NULL) == false); - DQN_ASSERT(dqn_darray_free(NULL) == false); - } - - printf("dqn_darray_test(): Completed successfully\n"); }