Various fixes, string lib, start removing C-style API

This commit is contained in:
Doyle Thai 2017-10-28 19:58:09 +11:00
parent 5533ad0b68
commit bfa00944c6
4 changed files with 11334 additions and 760 deletions

View File

@ -31,7 +31,7 @@ REM Zi enables debug data, Z7 combines the debug files into one.
REM W4 warning level 4 REM W4 warning level 4
REM WX treat warnings as errors REM WX treat warnings as errors
REM wd4201 ignore: nonstandard extension used: nameless struct/union REM wd4201 ignore: nonstandard extension used: nameless struct/union
set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -WX -wd4201 -FC -O2 -wd4127 set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -WX -wd4201 -FC -Od -wd4127
REM Include directories REM Include directories
set IncludeFlags= set IncludeFlags=

1645
dqn.h

File diff suppressed because it is too large Load Diff

View File

@ -973,95 +973,96 @@ void VecTest()
printf("VecTest(): Completed successfully\n"); printf("VecTest(): Completed successfully\n");
} }
void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI) void ArrayTestMemAPIInternal(const DqnMemAPI memAPI)
{ {
PrintHeader("Array with Default Mem API Test"); printf("Array with Default Mem API Test");
DqnArray<DqnV2> array = {};
if (1) if (1)
{ {
DQN_ASSERT(DqnArray_Init(array, 1, memAPI)); DQN_ASSERT(array.Init(1, memAPI));
DQN_ASSERT(array->capacity == 1); DQN_ASSERT(array.max == 1);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array.count == 0);
// Test basic insert // Test basic insert
if (1) if (1)
{ {
DqnV2 va = DqnV2_2f(5, 10); DqnV2 va = DqnV2_2f(5, 10);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DqnV2 vb = array->data[0]; DqnV2 vb = array.data[0];
DQN_ASSERT(DqnV2_Equals(va, vb)); DQN_ASSERT(DqnV2_Equals(va, vb));
DQN_ASSERT(array->capacity == 1); DQN_ASSERT(array.max == 1);
DQN_ASSERT(array->count == 1); DQN_ASSERT(array.count == 1);
} }
// Test array resizing and freeing // Test array resizing and freeing
if (1) if (1)
{ {
DqnV2 va = DqnV2_2f(10, 15); DqnV2 va = DqnV2_2f(10, 15);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DqnV2 vb = array->data[0]; DqnV2 vb = array.data[0];
DQN_ASSERT(DqnV2_Equals(va, vb) == false); DQN_ASSERT(DqnV2_Equals(va, vb) == false);
vb = array->data[1]; vb = array.data[1];
DQN_ASSERT(DqnV2_Equals(va, vb) == true); DQN_ASSERT(DqnV2_Equals(va, vb) == true);
DQN_ASSERT(array->capacity == 2); DQN_ASSERT(array.max == 2);
DQN_ASSERT(array->count == 2); DQN_ASSERT(array.count == 2);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 3); DQN_ASSERT(array.max == 3);
DQN_ASSERT(array->count == 3); DQN_ASSERT(array.count == 3);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 4); DQN_ASSERT(array.max == 4);
DQN_ASSERT(array->count == 4); DQN_ASSERT(array.count == 4);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 5); DQN_ASSERT(array.max == 5);
DQN_ASSERT(array->count == 5); DQN_ASSERT(array.count == 5);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 6); DQN_ASSERT(array.max == 6);
DQN_ASSERT(array->count == 6); DQN_ASSERT(array.count == 6);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 7); DQN_ASSERT(array.max == 7);
DQN_ASSERT(array->count == 7); DQN_ASSERT(array.count == 7);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 8); DQN_ASSERT(array.max == 8);
DQN_ASSERT(array->count == 8); DQN_ASSERT(array.count == 8);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 9); DQN_ASSERT(array.max == 9);
DQN_ASSERT(array->count == 9); DQN_ASSERT(array.count == 9);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 10); DQN_ASSERT(array.max == 10);
DQN_ASSERT(array->count == 10); DQN_ASSERT(array.count == 10);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(array.Push(va));
DQN_ASSERT(array->capacity == 12); DQN_ASSERT(array.max == 11);
DQN_ASSERT(array->count == 11); DQN_ASSERT(array.count == 11);
DqnV2 vc = DqnV2_2f(90, 100); DqnV2 vc = DqnV2_2f(90, 100);
DQN_ASSERT(DqnArray_Push(array, vc)); DQN_ASSERT(array.Push(vc));
DQN_ASSERT(array->capacity == 12); DQN_ASSERT(array.max == 12);
DQN_ASSERT(array->count == 12); DQN_ASSERT(array.count == 12);
DQN_ASSERT(DqnV2_Equals(vc, array->data[11])); DQN_ASSERT(DqnV2_Equals(vc, array.data[11]));
} }
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(array.Free());
if (1) if (1)
{ {
DQN_ASSERT(DqnArray_Init(array, 1, memAPI)); DQN_ASSERT(array.Init(1, memAPI));
DQN_ASSERT(array->capacity == 1); DQN_ASSERT(array.max == 1);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array.count == 0);
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(array.Free());
if (1) if (1)
{ {
@ -1070,46 +1071,46 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
DqnV2 c = DqnV2_2f(5, 6); DqnV2 c = DqnV2_2f(5, 6);
DqnV2 d = DqnV2_2f(7, 8); DqnV2 d = DqnV2_2f(7, 8);
DQN_ASSERT(DqnArray_Init(array, 16, memAPI)); DQN_ASSERT(array.Init(16, memAPI));
DQN_ASSERT(DqnArray_Remove(array, 0) == false); DQN_ASSERT(array.Remove(0) == false);
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array.count == 0);
DQN_ASSERT(DqnArray_Clear(array)); array.Clear();
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array.count == 0);
DQN_ASSERT(DqnArray_Push(array, a)); DQN_ASSERT(array.Push(a));
DQN_ASSERT(DqnArray_Push(array, b)); DQN_ASSERT(array.Push(b));
DQN_ASSERT(DqnArray_Push(array, c)); DQN_ASSERT(array.Push(c));
DQN_ASSERT(DqnArray_Push(array, d)); DQN_ASSERT(array.Push(d));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 4); DQN_ASSERT(array.count == 4);
DQN_ASSERT(DqnArray_Remove(array, 0)); DQN_ASSERT(array.Remove(0));
DQN_ASSERT(DqnV2_Equals(array->data[0], d)); DQN_ASSERT(DqnV2_Equals(array.data[0], d));
DQN_ASSERT(DqnV2_Equals(array->data[1], b)); DQN_ASSERT(DqnV2_Equals(array.data[1], b));
DQN_ASSERT(DqnV2_Equals(array->data[2], c)); DQN_ASSERT(DqnV2_Equals(array.data[2], c));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 3); DQN_ASSERT(array.count == 3);
DQN_ASSERT(DqnArray_Remove(array, 2)); DQN_ASSERT(array.Remove(2));
DQN_ASSERT(DqnV2_Equals(array->data[0], d)); DQN_ASSERT(DqnV2_Equals(array.data[0], d));
DQN_ASSERT(DqnV2_Equals(array->data[1], b)); DQN_ASSERT(DqnV2_Equals(array.data[1], b));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 2); DQN_ASSERT(array.count == 2);
DQN_ASSERT(DqnArray_Remove(array, 100) == false); DQN_ASSERT(array.Remove(100) == false);
DQN_ASSERT(DqnV2_Equals(array->data[0], d)); DQN_ASSERT(DqnV2_Equals(array.data[0], d));
DQN_ASSERT(DqnV2_Equals(array->data[1], b)); DQN_ASSERT(DqnV2_Equals(array.data[1], b));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 2); DQN_ASSERT(array.count == 2);
DQN_ASSERT(DqnArray_Clear(array)); array.Clear();
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array.count == 0);
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(array.Free());
if (1) if (1)
{ {
@ -1118,42 +1119,99 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
DqnV2 c = DqnV2_2f(5, 6); DqnV2 c = DqnV2_2f(5, 6);
DqnV2 d = DqnV2_2f(7, 8); DqnV2 d = DqnV2_2f(7, 8);
DQN_ASSERT(DqnArray_Init(array, 16, memAPI)); DQN_ASSERT(array.Init(16, memAPI));
DQN_ASSERT(DqnArray_Push(array, a)); DQN_ASSERT(array.Push(a));
DQN_ASSERT(DqnArray_Push(array, b)); DQN_ASSERT(array.Push(b));
DQN_ASSERT(DqnArray_Push(array, c)); DQN_ASSERT(array.Push(c));
DQN_ASSERT(DqnArray_Push(array, d)); DQN_ASSERT(array.Push(d));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 4); DQN_ASSERT(array.count == 4);
DqnArray_RemoveStable(array, 0); array.RemoveStable(0);
DQN_ASSERT(DqnV2_Equals(array->data[0], b)); DQN_ASSERT(DqnV2_Equals(array.data[0], b));
DQN_ASSERT(DqnV2_Equals(array->data[1], c)); DQN_ASSERT(DqnV2_Equals(array.data[1], c));
DQN_ASSERT(DqnV2_Equals(array->data[2], d)); DQN_ASSERT(DqnV2_Equals(array.data[2], d));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 3); DQN_ASSERT(array.count == 3);
DqnArray_RemoveStable(array, 1); array.RemoveStable(1);
DQN_ASSERT(DqnV2_Equals(array->data[0], b)); DQN_ASSERT(DqnV2_Equals(array.data[0], b));
DQN_ASSERT(DqnV2_Equals(array->data[1], d)); DQN_ASSERT(DqnV2_Equals(array.data[1], d));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 2); DQN_ASSERT(array.count == 2);
DqnArray_RemoveStable(array, 1); array.RemoveStable(1);
DQN_ASSERT(DqnV2_Equals(array->data[0], b)); DQN_ASSERT(DqnV2_Equals(array.data[0], b));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array.max == 16);
DQN_ASSERT(array->count == 1); DQN_ASSERT(array.count == 1);
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(array.Free());
printf("ArrayTestMemAPIInternal(): Completed successfully\n"); printf("ArrayTestMemAPIInternal(): Completed successfully\n");
} }
void ArrayTestRealData(DqnArray<char> *array)
{
#ifdef DQN_XPLATFORM_LAYER
size_t bufSize = 0;
u8 *buf = DqnFile_ReadEntireFileSimple("tests/google-10000-english.txt", &bufSize);
DQN_ASSERT(buf);
for (auto i = 0; i < bufSize; i++)
array->Push(buf[i]);
DQN_ASSERT((size_t)array->count == bufSize);
for (auto i = 0; i < array->count; i++)
DQN_ASSERT(array->data[i] == buf[i]);
DQN_ASSERT(array->Free());
free(buf);
printf("ArrayTestRealData(): Completed successfully\n");
#endif
}
void ArrayTest() void ArrayTest()
{ {
PrintHeader("Array Test"); PrintHeader("Array Test");
DqnArray<DqnV2> array = {}; if (1)
ArrayTestMemAPIInternal(&array, DqnMemAPI_DefaultUseCalloc()); {
ArrayTestMemAPIInternal(DqnMemAPI_HeapAllocator());
}
if (1)
{
if (1)
{
DqnArray<char> array = {};
DQN_ASSERT(array.Init(1));
ArrayTestRealData(&array);
}
if (1)
{
DqnMemStack stack = {}; stack.Init(DQN_MEGABYTE(1), true, 4);
DqnMemAPI memAPI = DqnMemAPI_StackAllocator(&stack);
if (1)
{
auto memGuard0 = stack.TempRegionGuard();
DqnArray<char> array = {};
DQN_ASSERT(array.Init(1, memAPI));
ArrayTestRealData(&array);
}
// Test reallocing strategies for memory stacks
if (1)
{
auto memGuard0 = stack.TempRegionGuard();
DqnArray<char> array = {};
DQN_ASSERT(array.Init(128, memAPI));
ArrayTestRealData(&array);
}
stack.Free();
}
}
printf("ArrayTest(): Completed successfully\n"); printf("ArrayTest(): Completed successfully\n");
} }
@ -1166,7 +1224,7 @@ void MemStackTest()
size_t allocSize = DQN_KILOBYTE(1); size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
const u32 ALIGNMENT = 4; const u32 ALIGNMENT = 4;
DqnMemStack_Init(&stack, allocSize, false, ALIGNMENT); stack.Init(allocSize, false, ALIGNMENT);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == allocSize); DQN_ASSERT(stack.block->size == allocSize);
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
@ -1174,9 +1232,8 @@ void MemStackTest()
// Alocate A // Alocate A
size_t sizeA = (size_t)(allocSize * 0.5f); size_t sizeA = (size_t)(allocSize * 0.5f);
void *resultA = DqnMemStack_Push(&stack, sizeA); void *resultA = stack.Push(sizeA);
u64 resultAddrA = *((u64 *)resultA); DQN_ASSERT(((intptr_t)resultA % ALIGNMENT) == 0);
DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == allocSize); DQN_ASSERT(stack.block->size == allocSize);
DQN_ASSERT(stack.block->used >= sizeA + 0 && stack.block->used <= sizeA + 3); DQN_ASSERT(stack.block->used >= sizeA + 0 && stack.block->used <= sizeA + 3);
@ -1189,9 +1246,8 @@ void MemStackTest()
DqnMemStackBlock *blockA = stack.block; DqnMemStackBlock *blockA = stack.block;
// Alocate B // Alocate B
size_t sizeB = (size_t)(allocSize * 2.0f); size_t sizeB = (size_t)(allocSize * 2.0f);
void *resultB = DqnMemStack_Push(&stack, sizeB); void *resultB = stack.Push(sizeB);
u64 resultAddrB = *((u64 *)resultB); DQN_ASSERT(((intptr_t)resultB % ALIGNMENT) == 0);
DQN_ASSERT(resultAddrB % ALIGNMENT == 0);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == DQN_KILOBYTE(2)); DQN_ASSERT(stack.block->size == DQN_KILOBYTE(2));
@ -1212,13 +1268,11 @@ void MemStackTest()
DqnMemStackBlock *blockB = stack.block; DqnMemStackBlock *blockB = stack.block;
// Check temp regions work // Check temp regions work
DqnMemStackTempRegion tempBuffer; DqnMemStackTempRegion tempBuffer = stack.TempRegionBegin();
DQN_ASSERT(DqnMemStackTempRegion_Begin(&tempBuffer, &stack));
size_t sizeC = 1024 + 1; size_t sizeC = 1024 + 1;
void *resultC = DqnMemStack_Push(tempBuffer.stack, sizeC); void *resultC = stack.Push(sizeC);
u64 resultAddrC = *((u64 *)resultC); DQN_ASSERT(((intptr_t)resultC % ALIGNMENT) == 0);
DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
DQN_ASSERT(stack.block != blockB && stack.block != blockA); DQN_ASSERT(stack.block != blockB && stack.block != blockA);
DQN_ASSERT(stack.block->used >= sizeC + 0 && stack.block->used <= sizeC + 3); DQN_ASSERT(stack.block->used >= sizeC + 0 && stack.block->used <= sizeC + 3);
DQN_ASSERT(stack.tempRegionCount == 1); DQN_ASSERT(stack.tempRegionCount == 1);
@ -1243,7 +1297,7 @@ void MemStackTest()
DQN_ASSERT(ptrC[i] == 3); DQN_ASSERT(ptrC[i] == 3);
// End temp region which should revert back to 2 linked stacks, A and B // End temp region which should revert back to 2 linked stacks, A and B
DqnMemStackTempRegion_End(tempBuffer); stack.TempRegionEnd(tempBuffer);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == sizeB); DQN_ASSERT(stack.block->size == sizeB);
DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3); DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
@ -1256,7 +1310,7 @@ void MemStackTest()
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
// Release the last linked stack from the push stack // Release the last linked stack from the push stack
DqnMemStack_FreeLastBlock(&stack); stack.FreeLastBlock();
// Which should return back to the 1st allocation // Which should return back to the 1st allocation
DQN_ASSERT(stack.block == blockA); DQN_ASSERT(stack.block == blockA);
@ -1267,7 +1321,7 @@ void MemStackTest()
DQN_ASSERT(!stack.block->prevBlock); DQN_ASSERT(!stack.block->prevBlock);
// Free once more to release stack A memory // Free once more to release stack A memory
DqnMemStack_FreeLastBlock(&stack); stack.FreeLastBlock();
DQN_ASSERT(!stack.block); DQN_ASSERT(!stack.block);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
DQN_ASSERT(stack.tempRegionCount == 0); DQN_ASSERT(stack.tempRegionCount == 0);
@ -1279,18 +1333,18 @@ void MemStackTest()
u8 memory[DQN_KILOBYTE(1)] = {}; u8 memory[DQN_KILOBYTE(1)] = {};
DqnMemStack stack = {}; DqnMemStack stack = {};
const u32 ALIGNMENT = 4; const u32 ALIGNMENT = 4;
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory), ALIGNMENT); stack.InitWithFixedMem(memory, DQN_ARRAY_COUNT(memory), ALIGNMENT);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock)); DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
// Allocation larger than stack mem size should fail // Allocation larger than stack mem size should fail
DQN_ASSERT(!DqnMemStack_Push(&stack, DQN_ARRAY_COUNT(memory) * 2)); DQN_ASSERT(!stack.Push(DQN_ARRAY_COUNT(memory) * 2));
// Check free does nothing // Check free does nothing
DqnMemStack_Free(&stack); stack.Free();
DqnMemStack_FreeLastBlock(&stack); stack.FreeLastBlock();
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock)); DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
@ -1304,20 +1358,20 @@ void MemStackTest()
size_t allocSize = DQN_KILOBYTE(1); size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
const u32 ALIGNMENT = 4; const u32 ALIGNMENT = 4;
DqnMemStack_InitWithFixedSize(&stack, allocSize, false, ALIGNMENT); stack.InitWithFixedSize(allocSize, false, ALIGNMENT);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == allocSize); DQN_ASSERT(stack.block->size == allocSize);
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
void *result = DqnMemStack_Push(&stack, (size_t)(0.5f * allocSize)); void *result = stack.Push((size_t)(0.5f * allocSize));
DQN_ASSERT(result); DQN_ASSERT(result);
// Allocating more should fail // Allocating more should fail
DQN_ASSERT(!DqnMemStack_Push(&stack, allocSize)); DQN_ASSERT(!stack.Push(allocSize));
// Freeing should work // Freeing should work
DqnMemStack_Free(&stack); stack.Free();
DQN_ASSERT(!stack.block); DQN_ASSERT(!stack.block);
} }
@ -1327,13 +1381,13 @@ void MemStackTest()
size_t firstBlockSize = DQN_KILOBYTE(1); size_t firstBlockSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
const u32 ALIGNMENT = 16; const u32 ALIGNMENT = 16;
DqnMemStack_Init(&stack, firstBlockSize, false, ALIGNMENT); stack.Init(firstBlockSize, false, ALIGNMENT);
DqnMemStackBlock *firstBlock = stack.block; DqnMemStackBlock *firstBlock = stack.block;
u8 *first = NULL; u8 *first = NULL;
{ {
u32 allocate40Bytes = 40; u32 allocate40Bytes = 40;
u8 *data = (u8 *)DqnMemStack_Push(&stack, allocate40Bytes); u8 *data = (u8 *)stack.Push(allocate40Bytes);
// Test that the allocation got aligned to 16 byte boundary // Test that the allocation got aligned to 16 byte boundary
DQN_ASSERT(data); DQN_ASSERT(data);
@ -1344,7 +1398,7 @@ void MemStackTest()
data[i] = 'a'; data[i] = 'a';
// Clear the block, but don't zero it out // Clear the block, but don't zero it out
DqnMemStack_ClearCurrBlock(&stack, false); stack.ClearCurrBlock(false);
for (u32 i = 0; i < allocate40Bytes; i++) for (u32 i = 0; i < allocate40Bytes; i++)
DQN_ASSERT(data[i] == 'a'); DQN_ASSERT(data[i] == 'a');
@ -1353,7 +1407,7 @@ void MemStackTest()
DQN_ASSERT(stack.block->size == firstBlockSize); DQN_ASSERT(stack.block->size == firstBlockSize);
// Reallocate the data // Reallocate the data
data = (u8 *)DqnMemStack_Push(&stack, firstBlockSize); data = (u8 *)stack.Push(firstBlockSize);
DQN_ASSERT(stack.block->size == firstBlockSize); DQN_ASSERT(stack.block->size == firstBlockSize);
DQN_ASSERT((size_t)data % ALIGNMENT == 0); DQN_ASSERT((size_t)data % ALIGNMENT == 0);
@ -1362,7 +1416,7 @@ void MemStackTest()
data[i] = 'b'; data[i] = 'b';
// Clear block and zero it out // Clear block and zero it out
DqnMemStack_ClearCurrBlock(&stack, true); stack.ClearCurrBlock(true);
for (u32 i = 0; i < firstBlockSize; i++) for (u32 i = 0; i < firstBlockSize; i++)
DQN_ASSERT(data[i] == 0); DQN_ASSERT(data[i] == 0);
@ -1374,7 +1428,7 @@ void MemStackTest()
DQN_ASSERT(stack.block->size == firstBlockSize); DQN_ASSERT(stack.block->size == firstBlockSize);
// Write out data to current block // Write out data to current block
data = (u8 *)DqnMemStack_Push(&stack, firstBlockSize); data = (u8 *)stack.Push(firstBlockSize);
for (u32 i = 0; i < firstBlockSize; i++) for (u32 i = 0; i < firstBlockSize; i++)
data[i] = 'c'; data[i] = 'c';
@ -1383,19 +1437,19 @@ void MemStackTest()
// Force it to allocate three new blocks and write out data to each // Force it to allocate three new blocks and write out data to each
size_t secondBlockSize = DQN_KILOBYTE(2); size_t secondBlockSize = DQN_KILOBYTE(2);
u8 *second = (u8 *)DqnMemStack_Push(&stack, secondBlockSize); u8 *second = (u8 *)stack.Push(secondBlockSize);
DqnMemStackBlock *secondBlock = stack.block; DqnMemStackBlock *secondBlock = stack.block;
for (u32 i = 0; i < secondBlockSize; i++) for (u32 i = 0; i < secondBlockSize; i++)
second[i] = 'd'; second[i] = 'd';
size_t thirdBlockSize = DQN_KILOBYTE(3); size_t thirdBlockSize = DQN_KILOBYTE(3);
u8 *third = (u8 *)DqnMemStack_Push(&stack, thirdBlockSize); u8 *third = (u8 *)stack.Push(thirdBlockSize);
DqnMemStackBlock *thirdBlock = stack.block; DqnMemStackBlock *thirdBlock = stack.block;
for (u32 i = 0; i < thirdBlockSize; i++) for (u32 i = 0; i < thirdBlockSize; i++)
third[i] = 'e'; third[i] = 'e';
size_t fourthBlockSize = DQN_KILOBYTE(4); size_t fourthBlockSize = DQN_KILOBYTE(4);
u8 *fourth = (u8 *)DqnMemStack_Push(&stack, fourthBlockSize); u8 *fourth = (u8 *)stack.Push(fourthBlockSize);
DqnMemStackBlock *fourthBlock = stack.block; DqnMemStackBlock *fourthBlock = stack.block;
for (u32 i = 0; i < fourthBlockSize; i++) for (u32 i = 0; i < fourthBlockSize; i++)
fourth[i] = 'f'; fourth[i] = 'f';
@ -1414,7 +1468,7 @@ void MemStackTest()
fakeBlock.memory = fakeBlockMem; fakeBlock.memory = fakeBlockMem;
fakeBlock.size = DQN_ARRAY_COUNT(fakeBlockMem); fakeBlock.size = DQN_ARRAY_COUNT(fakeBlockMem);
fakeBlock.used = 0; fakeBlock.used = 0;
DQN_ASSERT(!DqnMemStack_FreeMemBlock(&stack, &fakeBlock)); DQN_ASSERT(!stack.FreeMemBlock(&fakeBlock));
// Ensure that the actual blocks are still valid and freeing did nothing // Ensure that the actual blocks are still valid and freeing did nothing
DQN_ASSERT(firstBlock->size == firstBlockSize); DQN_ASSERT(firstBlock->size == firstBlockSize);
@ -1447,7 +1501,7 @@ void MemStackTest()
DQN_ASSERT(fourth[i] == 'f'); DQN_ASSERT(fourth[i] == 'f');
// Free the first block // Free the first block
DqnMemStack_FreeMemBlock(&stack, firstBlock); stack.FreeMemBlock(firstBlock);
// Revalidate state // Revalidate state
DQN_ASSERT(secondBlock->size == secondBlockSize); DQN_ASSERT(secondBlock->size == secondBlockSize);
@ -1473,7 +1527,7 @@ void MemStackTest()
DQN_ASSERT(fourth[i] == 'f'); DQN_ASSERT(fourth[i] == 'f');
// Free the third block // Free the third block
DqnMemStack_FreeMemBlock(&stack, thirdBlock); stack.FreeMemBlock(thirdBlock);
// Revalidate state // Revalidate state
DQN_ASSERT(secondBlock->size == secondBlockSize); DQN_ASSERT(secondBlock->size == secondBlockSize);
@ -1493,7 +1547,7 @@ void MemStackTest()
DQN_ASSERT(fourth[i] == 'f'); DQN_ASSERT(fourth[i] == 'f');
// Free the second block // Free the second block
DqnMemStack_FreeMemBlock(&stack, secondBlock); stack.FreeMemBlock(secondBlock);
// Revalidate state // Revalidate state
DQN_ASSERT(fourthBlock->size == fourthBlockSize); DQN_ASSERT(fourthBlock->size == fourthBlockSize);
@ -1504,7 +1558,7 @@ void MemStackTest()
DQN_ASSERT(fourth[i] == 'f'); DQN_ASSERT(fourth[i] == 'f');
// Free the stack // Free the stack
DqnMemStack_Free(&stack); stack.Free();
DQN_ASSERT(!stack.block); DQN_ASSERT(!stack.block);
} }
@ -1515,15 +1569,15 @@ void MemStackTest()
if (1) if (1)
{ {
DqnMemStack stack = {}; DqnMemStack stack = {};
DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true); stack.Init(DQN_KILOBYTE(1), true);
size_t allocSize = 512; size_t allocSize = 512;
void *alloc = DqnMemStack_Push(&stack, allocSize); void *alloc = stack.Push(allocSize);
DQN_ASSERT(stack.block->used == allocSize); DQN_ASSERT(stack.block->used == allocSize);
DQN_ASSERT(DqnMemStack_Pop(&stack, alloc, allocSize)); DQN_ASSERT(stack.Pop(alloc, allocSize));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DqnMemStack_Free(&stack); stack.Free();
} }
// Test pop on a non-byte aligned allocation. This checks to see if // Test pop on a non-byte aligned allocation. This checks to see if
@ -1531,15 +1585,15 @@ void MemStackTest()
if (1) if (1)
{ {
DqnMemStack stack = {}; DqnMemStack stack = {};
DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true); stack.Init(DQN_KILOBYTE(1), true);
size_t allocSize = 1; size_t allocSize = 1;
void *alloc = DqnMemStack_Push(&stack, allocSize); void *alloc = stack.Push(allocSize);
DQN_ASSERT(stack.block->used == DQN_ALIGN_POW_N(allocSize, stack.byteAlign)); DQN_ASSERT(stack.block->used == DQN_ALIGN_POW_N(allocSize, stack.byteAlign));
DQN_ASSERT(DqnMemStack_Pop(&stack, alloc, allocSize)); DQN_ASSERT(stack.Pop(alloc, allocSize));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DqnMemStack_Free(&stack); stack.Free();
} }
} }
} }
@ -1671,7 +1725,7 @@ void FileTest()
} }
DqnMemStack memStack = {}; DqnMemStack memStack = {};
DQN_ASSERT(DqnMemStack_Init(&memStack, DQN_MEGABYTE(1), true)); DQN_ASSERT(memStack.Init(DQN_MEGABYTE(1), true));
// Read data back in // Read data back in
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++) for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
{ {
@ -1682,7 +1736,7 @@ void FileTest()
bool result = DqnFile_Open(fileNames[i], file, permissions, DqnFileAction_OpenOnly); bool result = DqnFile_Open(fileNames[i], file, permissions, DqnFileAction_OpenOnly);
DQN_ASSERT(result); DQN_ASSERT(result);
u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, file->size); u8 *buffer = (u8 *)memStack.Push(file->size);
DQN_ASSERT(buffer); DQN_ASSERT(buffer);
size_t bytesRead = DqnFile_Read(&files[i], buffer, file->size); size_t bytesRead = DqnFile_Read(&files[i], buffer, file->size);
@ -1692,7 +1746,7 @@ void FileTest()
DQN_ASSERT(DqnStr_Cmp((char *)buffer, (writeData[i])) == 0); DQN_ASSERT(DqnStr_Cmp((char *)buffer, (writeData[i])) == 0);
// Delete when we're done with it // Delete when we're done with it
DQN_ASSERT(DqnMemStack_Pop(&memStack, buffer, file->size)); DQN_ASSERT(memStack.Pop(buffer, file->size));
DqnFile_Close(file); DqnFile_Close(file);
} }
@ -1701,7 +1755,7 @@ void FileTest()
size_t reqSize = 0; size_t reqSize = 0;
DQN_ASSERT(DqnFile_GetFileSize(fileNames[i], &reqSize)); DQN_ASSERT(DqnFile_GetFileSize(fileNames[i], &reqSize));
u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, reqSize); u8 *buffer = (u8 *)memStack.Push(reqSize);
DQN_ASSERT(buffer); DQN_ASSERT(buffer);
size_t bytesRead = 0; size_t bytesRead = 0;
@ -1710,7 +1764,7 @@ void FileTest()
// Verify the data is the same as we wrote out // Verify the data is the same as we wrote out
DQN_ASSERT(DqnStr_Cmp((char *)buffer, (writeData[i])) == 0); DQN_ASSERT(DqnStr_Cmp((char *)buffer, (writeData[i])) == 0);
DQN_ASSERT(DqnMemStack_Pop(&memStack, buffer, reqSize)); DQN_ASSERT(memStack.Pop(buffer, reqSize));
} }
DQN_ASSERT(DqnFile_Delete(fileNames[i])); DQN_ASSERT(DqnFile_Delete(fileNames[i]));
@ -1725,7 +1779,7 @@ void FileTest()
DqnFile_Open(fileNames[i], &dummy, permissions, DqnFileAction_OpenOnly); DqnFile_Open(fileNames[i], &dummy, permissions, DqnFileAction_OpenOnly);
DQN_ASSERT(!fileExists); DQN_ASSERT(!fileExists);
} }
DqnMemStack_Free(&memStack); memStack.Free();
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -1815,34 +1869,9 @@ FILE_SCOPE void JobQueueTest()
DqnLock_Delete(&globalJobQueueLock); DqnLock_Delete(&globalJobQueueLock);
} }
FILE_SCOPE inline bool Dqn_QuickSortLessThanU32(const void *const val1, const void *const val2)
{
const u32 *const a = (u32 *)val1;
const u32 *const b = (u32 *)val2;
return (*a) < (*b);
}
FILE_SCOPE inline void Dqn_QuickSortSwapU32(void *const val1, void *const val2)
{
u32 *a = (u32 *)val1;
u32 *b = (u32 *)val2;
DQN_SWAP(u32, *a, *b);
}
#include <algorithm> #include <algorithm>
void SortTest() void SortTest()
{ {
{
u32 array[] = {4, 8, 7, 5, 2, 3, 6};
Dqn_QuickSortC(array, sizeof(array[0]), DQN_ARRAY_COUNT(array), Dqn_QuickSortLessThanU32,
Dqn_QuickSortSwapU32);
for (u32 i = 0; i < DQN_ARRAY_COUNT(array) - 1; i++)
{
DQN_ASSERT(array[i] <= array[i + 1]);
}
}
PrintHeader("DqnSort vs std::Sort"); PrintHeader("DqnSort vs std::Sort");
DqnRandPCGState state = {}; DqnRandPCGState state = {};
DqnRnd_PCGInit(&state); DqnRnd_PCGInit(&state);
@ -1852,48 +1881,34 @@ void SortTest()
DQN_ASSERT(stack.Init(DQN_KILOBYTE(1), false)); DQN_ASSERT(stack.Init(DQN_KILOBYTE(1), false));
// Create array of ints // Create array of ints
u32 numInts = 1000000; u32 numInts = 1000000;
u32 sizeInBytes = sizeof(u32) * numInts; u32 sizeInBytes = sizeof(u32) * numInts;
u32 *dqnCArray = (u32 *)stack.Push(sizeInBytes);
u32 *dqnCPPArray = (u32 *)stack.Push(sizeInBytes); u32 *dqnCPPArray = (u32 *)stack.Push(sizeInBytes);
u32 *stdArray = (u32 *)stack.Push(sizeInBytes); u32 *stdArray = (u32 *)stack.Push(sizeInBytes);
DQN_ASSERT(dqnCArray && dqnCPPArray && stdArray); DQN_ASSERT(dqnCPPArray && stdArray);
f64 dqnCTimings[10] = {}; f64 dqnCPPTimings[2] = {};
f64 dqnCPPTimings[DQN_ARRAY_COUNT(dqnCTimings)] = {}; f64 stdTimings[DQN_ARRAY_COUNT(dqnCPPTimings)] = {};
f64 stdTimings[DQN_ARRAY_COUNT(dqnCTimings)] = {};
f64 dqnCAverage = 0;
f64 dqnCPPAverage = 0; f64 dqnCPPAverage = 0;
f64 stdAverage = 0; f64 stdAverage = 0;
for (u32 timingsIndex = 0; timingsIndex < DQN_ARRAY_COUNT(dqnCTimings); timingsIndex++) for (u32 timingsIndex = 0; timingsIndex < DQN_ARRAY_COUNT(dqnCPPTimings); timingsIndex++)
{ {
// Populate with random numbers // Populate with random numbers
for (u32 i = 0; i < numInts; i++) for (u32 i = 0; i < numInts; i++)
{ {
dqnCArray[i] = DqnRnd_PCGNext(&state); dqnCPPArray[i] = DqnRnd_PCGNext(&state);
dqnCPPArray[i] = dqnCArray[i];
stdArray[i] = dqnCPPArray[i]; stdArray[i] = dqnCPPArray[i];
} }
// Time Dqn_QuickSortC // Time Dqn_QuickSort
{ {
f64 start = DqnTimer_NowInS(); f64 start = DqnTimer_NowInS();
Dqn_QuickSortC(dqnCArray, sizeof(dqnCArray[0]), numInts, Dqn_QuickSortLessThanU32, Dqn_QuickSort<u32>(
Dqn_QuickSortSwapU32); dqnCPPArray, numInts,
f64 duration = DqnTimer_NowInS() - start; [](const u32 *const a, const u32 *const b) -> bool { return *a < *b; });
dqnCTimings[timingsIndex] = duration;
dqnCAverage += duration;
printf("[%02d]Dqn_QuickSortC: %f vs ", timingsIndex, dqnCTimings[timingsIndex]);
}
// Time Dqn_QuickSortC
{
f64 start = DqnTimer_NowInS();
Dqn_QuickSort(dqnCPPArray, numInts, Dqn_QuickSortLessThanU32);
f64 duration = DqnTimer_NowInS() - start; f64 duration = DqnTimer_NowInS() - start;
dqnCPPTimings[timingsIndex] = duration; dqnCPPTimings[timingsIndex] = duration;
@ -1913,26 +1928,22 @@ void SortTest()
printf("std::sort: %f\n", stdTimings[timingsIndex]); printf("std::sort: %f\n", stdTimings[timingsIndex]);
} }
// Validate algorithm is correct
for (u32 i = 0; i < numInts; i++) for (u32 i = 0; i < numInts; i++)
{ {
DQN_ASSERT_MSG(dqnCArray[i] == stdArray[i], "DqnArray[%d]: %d, stdArray[%d]: %d", i, DQN_ASSERT_MSG(dqnCPPArray[i] == stdArray[i], "DqnArray[%d]: %d, stdArray[%d]: %d", i,
dqnCArray[i], stdArray[i], i); dqnCPPArray[i], stdArray[i], i);
} }
} }
// Print averages // Print averages
if (1) if (1)
{ {
dqnCAverage /= (f64)DQN_ARRAY_COUNT(dqnCTimings);
dqnCPPAverage /= (f64)DQN_ARRAY_COUNT(dqnCPPTimings); dqnCPPAverage /= (f64)DQN_ARRAY_COUNT(dqnCPPTimings);
stdAverage /= (f64)DQN_ARRAY_COUNT(stdTimings); stdAverage /= (f64)DQN_ARRAY_COUNT(stdTimings);
printf("\n- Average Timings\n"); printf("\n- Average Timings\n");
printf(" Dqn_QuickSortC: %f vs Dqn_QuickSort: %f vs std::sort: %f\n\n", dqnCAverage, printf(" Dqn_QuickSort: %f vs std::sort: %f\n\n", dqnCPPAverage, stdAverage);
dqnCPPAverage, stdAverage);
} }
stack.Pop(stdArray, sizeInBytes);
stack.Pop(dqnCPPArray, sizeInBytes);
stack.Pop(dqnCArray, sizeInBytes);
stack.Free(); stack.Free();
} }
} }

10000
tests/google-10000-english.txt Normal file

File diff suppressed because it is too large Load Diff