diff --git a/Single-Header/dn_single_header.cpp b/Single-Header/dn_single_header.cpp index 7002f7e..59cc025 100644 --- a/Single-Header/dn_single_header.cpp +++ b/Single-Header/dn_single_header.cpp @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2026-06-18 16:40:52 +// Generated by the DN single header generator 2026-06-18 18:20:05 // DN: Single header generator commented out => #if defined(_CLANGD) // #define DN_H_WITH_OS 1 @@ -2939,9 +2939,9 @@ DN_API DN_USize DN_Str8Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_Str8FindResult find = DN_Str8FindStr8(DN_Str8Advance(it, 1), DN_Str8Lit("\""), DN_Str8EqCase_Sensitive); DN_Assert(find.found); item = find.start_to_before_match; - it = DN_Str8BSplit(find.after_match_to_end_of_buffer, DN_Str8Lit(",")).rhs; + it = DN_Str8BSplit(find.after_match_to_end_of_buffer, delimiter).rhs; } else { - DN_Str8BSplitResult sub_split = DN_Str8BSplit(it, DN_Str8Lit(",")); + DN_Str8BSplitResult sub_split = DN_Str8BSplit(it, delimiter); item = sub_split.lhs; it = sub_split.rhs; } @@ -2956,7 +2956,7 @@ DN_API DN_USize DN_Str8Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, return result; } -DN_API DN_Str8SplitResult DN_Str8SplitArena(DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitFlags mode) +DN_API DN_Str8SplitResult DN_Str8SplitArena(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitFlags mode, DN_Arena *arena) { DN_Str8SplitResult result = {}; DN_USize count = DN_Str8Split(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode); @@ -7438,12 +7438,12 @@ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USi // Compute the range to erase DN_USize start = 0, end = 0; if (count < 0) { - // Erase backwards from begin_index, inclusive of begin_index - // Range: [begin_index + count + 1, begin_index + 1) - // Which is: [begin_index - abs(count) + 1, begin_index + 1) + // Erase backwards from begin_index, not inclusive of begin_index + // Range: [begin_index + count, begin_index) + // Which is: [begin_index - abs(count), begin_index) DN_USize abs_count = DN_Abs(count); - start = (begin_index + 1 > abs_count) ? (begin_index + 1 - abs_count) : 0; - end = begin_index + 1; + start = (begin_index > abs_count) ? (begin_index - abs_count) : 0; + end = begin_index; } else { start = begin_index; end = begin_index + count; @@ -7471,7 +7471,14 @@ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USi } result.items_erased = erase_count; - result.it_index = start ? start - 1 : start; + // NOTE: If we are erasing from the current index of the iterator to the end of the array then + // there's no more elements in the array to iterate. So the returned index should b + // one-past-last index + if (begin_index == start && end >= *size) { + result.it_index = *size; + } else { + result.it_index = start ? start - 1 : 0; + } return result; } @@ -15108,7 +15115,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 2); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15117,9 +15124,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable); - int expected[] = {0, 1, 2, 6, 7, 8, 9}; + int expected[] = {0, 1, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 1); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15128,9 +15135,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable); - int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9}; + int expected[] = {0, 1, 2, 3, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 5); + DN_UT_AssertF(&result, erase.it_index == 3, "lhs=%zu", erase.it_index); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15141,7 +15148,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 8, 9, 5, 6, 7}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 2); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15150,9 +15157,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable); - int expected[] = {0, 1, 2, 7, 8, 9, 6}; + int expected[] = {0, 1, 7, 8, 9, 5, 6}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 1); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15161,10 +15168,10 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable); - int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - DN_UT_Assert(&result, erase.items_erased == 1); + int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + DN_UT_Assert(&result, erase.items_erased == 0); DN_UT_Assert(&result, erase.it_index == 0); - DN_UT_Assert(&result, size == 9); + DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15185,7 +15192,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15194,7 +15201,7 @@ static DN_UTCore DN_TST_BaseArray() DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 10); } @@ -15202,7 +15209,7 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); } for (DN_UT_Test(&result, "Invalid input - empty array")) { @@ -15210,7 +15217,7 @@ static DN_UTCore DN_TST_BaseArray() DN_USize size = 0; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 0); } @@ -15220,7 +15227,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 10); + DN_UT_Assert(&result, erase.it_index == 9); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15247,77 +15254,11 @@ static DN_UTCore DN_TST_BaseVArray() DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); } - for (DN_UT_Test(&result, "Test stable erase, 1 item, the '2' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase, 1 item, the '1' value from the array")) { - DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - DN_ArrayErase erase_enums[] = {DN_ArrayErase_Stable, DN_ArrayErase_Unstable}; - for (DN_UT_Test(&result, "Test un/stable erase, OOB")) { - for (DN_ArrayErase erase : erase_enums) { - DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_OS_VArrayEraseRange(&array, DN_ArrayCountU(array_literal) /*begin_index*/, DN_ArrayCountU(array_literal) + 100 /*count*/, erase); - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - } - - for (DN_UT_Test(&result, "Test flipped begin/end index stable erase, 2 items, the '15, 3' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test flipped begin/end index unstable erase, 2 items, the '4, 5' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10, 11, 12}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test stable erase range, 2+1 (oob) item, the '13, 14, +1 OOB' value from the array")) { - DN_OS_VArrayEraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase range, 3+1 (oob) item, the '11, 12, +1 OOB' value from the array")) { - DN_OS_VArrayEraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test stable erase -overflow OOB, erasing the '0, 13' value from the array")) { - DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {14, 6, 7, 8}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase +overflow OOB, erasing the '7, 8' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {14, 6}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test adding an array of items after erase")) { + for (DN_UT_Test(&result, "Test adding an array of items")) { DN_U32 array_literal[] = {0, 1, 2, 3}; DN_OS_VArrayAddArray(&array, array_literal, DN_ArrayCountU(array_literal)); - DN_U32 expected_literal[] = {14, 6, 0, 1, 2, 3}; + DN_U32 expected_literal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3}; DN_UT_Assert(&result, array.size == DN_ArrayCountU(expected_literal)); DN_UT_Assert(&result, DN_Memcmp(array.data, expected_literal, DN_ArrayCountU(expected_literal) * sizeof(expected_literal[0])) == 0); } @@ -17206,9 +17147,9 @@ void DN_Demo() // NOTE: DN_HexFromBytes { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); unsigned char bytes[2] = {0xFA, 0xCE}; - DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), scratch.arena); + DN_Str8 hex = DN_HexFromPtrBytesArena(bytes, sizeof(bytes), &scratch.arena, DN_TrimLeadingZero_No); DN_Assert(DN_Str8Eq(hex, DN_Str8Lit("face"))); // NOTE: Guaranteed to be null-terminated DN_TCScratchEnd(&scratch); } @@ -17604,7 +17545,7 @@ void DN_Demo() // If 'tmp_path' is written to successfuly, the file will be copied over into // 'path'. if (0) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_ErrSink *error = DN_TCErrSinkBegin(DN_ErrSinkMode_Nil); DN_OS_FileWriteAllSafe(/*path*/ DN_Str8Lit("C:/Home/my.txt"), /*buffer*/ DN_Str8Lit("Hello world"), error); DN_ErrSinkEndLogErrorF(error, ""); @@ -17729,8 +17670,8 @@ void DN_Demo() DN_ProfilerNewFrame(&profiler); DN_ProfilerZone zone = DN_ProfilerBeginZone(&profiler, DN_Str8Lit("Main Loop"), DemoZone_MainLoop); DN_OS_SleepMs(100); - DN_ProfilerEndZone(&profiler, zone); - DN_ProfilerDump(&profiler); + DN_ProfilerEndZone(zone); + DN_ProfilerFmtToStdout(&profiler); } } #endif @@ -17797,7 +17738,7 @@ void DN_Demo() // Int -> U32: 0 or UINT32_MAX // Int -> U64: 0 or UINT64_MAX - // NOTE: DN_OS_StackTrace + // NOTE: DN_StackTrace // Emit stack traces at the calling site that these functions are invoked // from. // @@ -17814,23 +17755,23 @@ void DN_Demo() // the debug APIs are aware of how to resolve the new addresses imported // into the address space. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); - // NOTE: DN_OS_StackTraceWalk + // NOTE: DN_StackTraceFromArena // // Generate a stack trace as a series of addresses to the base of the // functions on the call-stack at the current instruction pointer. The // addresses are stored in order from the current executing function // first to the most ancestor function last in the walk. - DN_StackTraceWalkResult walk = DN_StackTraceWalk(scratch.arena, /*depth limit*/ 128); + DN_StackTrace walk = DN_StackTraceFromArena(&scratch.arena, /*depth limit*/ 128); // Loop over the addresses produced in the stack trace - for (DN_StackTraceWalkResultIterator it = {}; DN_StackTraceWalkResultIterate(&it, &walk);) { + for (DN_StackTraceIterator it = {}; DN_StackTraceIterate(&it, &walk);) { // NOTE: DN_StackTraceRawFrameToFrame // // Converts the base address into a human readable stack trace // entry (e.g. address, line number, file and function name). - DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(scratch.arena, it.raw_frame); + DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(&scratch.arena, it.raw_frame); // You may then print out the frame like so if (0) @@ -17847,7 +17788,7 @@ void DN_Demo() // Helper function to create a stack trace and automatically convert the // raw frames into human readable frames. This function effectively // calls 'Walk' followed by 'RawFrameToFrame'. - DN_StackTraceFrameSlice frames = DN_StackTraceGetFrames(scratch.arena, /*depth limit*/ 128); + DN_StackTraceFrameSlice frames = DN_StackTraceGetFrames(&scratch.arena, /*depth limit*/ 128); (void)frames; DN_TCScratchEnd(&scratch); @@ -17862,8 +17803,8 @@ void DN_Demo() // The returned string's 'size' member variable does *not* include this // additional null-terminating byte. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8AllocArena(scratch.arena, /*size*/ 1, DN_ZMem_Yes); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8AllocArena(/*size*/ 1, DN_ZMem_Yes, &scratch.arena); DN_Assert(string.size == 1); DN_Assert(string.data[string.size] == 0); // It is null-terminated! DN_TCScratchEnd(&scratch); @@ -17943,13 +17884,13 @@ void DN_Demo() // always be a newly allocated copy, irrespective of if any replacements // were done or not. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"), - /*find*/ DN_Str8Lit("Foo"), - /*replace*/ DN_Str8Lit("Moo"), - /*start_index*/ 1, - /*arena*/ scratch.arena, - /*eq_case*/ DN_Str8EqCase_Sensitive); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"), + /*find*/ DN_Str8Lit("Foo"), + /*replace*/ DN_Str8Lit("Moo"), + /*start_index*/ 1, + /*arena*/ &scratch.arena, + /*eq_case*/ DN_Str8EqCase_Sensitive); DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Foo Moo Bar"))); DN_TCScratchEnd(&scratch); } @@ -17962,8 +17903,8 @@ void DN_Demo() // Reverse segment delimits the string counting 'segment_size' from the back // of the string. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8Segment(scratch.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8Segment(&scratch.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); DN_Assert(DN_Str8Eq(string, DN_Str8Lit("123,456,789"))); DN_TCScratchEnd(&scratch); } @@ -17972,12 +17913,12 @@ void DN_Demo() { // Splits the string at each delimiter into substrings occuring prior and // after until the next delimiter. - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); { - DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena, - /*string*/ DN_Str8Lit("192.168.8.1"), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*string*/ DN_Str8Lit("192.168.8.1"), /*delimiter*/ DN_Str8Lit("."), - /*mode*/ DN_Str8SplitIncludeEmptyStrings_No); + DN_Str8SplitFlags_ExcludeEmptyStrings, + &scratch.arena); DN_Assert(splits.count == 4); DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("192")) && DN_Str8Eq(splits.data[1], DN_Str8Lit("168")) && @@ -17988,10 +17929,10 @@ void DN_Demo() // You can include empty strings that occur when splitting by setting // the split mode to include empty strings. { - DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena, - /*string*/ DN_Str8Lit("a--b"), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*string*/ DN_Str8Lit("a--b"), /*delimiter*/ DN_Str8Lit("-"), - /*mode*/ DN_Str8SplitIncludeEmptyStrings_Yes); + DN_Str8SplitFlags_Nil, + &scratch.arena); DN_Assert(splits.count == 3); DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("a")) && DN_Str8Eq(splits.data[1], DN_Str8Lit("")) && @@ -18131,13 +18072,14 @@ void DN_Demo() // caller's arena. If arena aliasing occurs, with ASAN on, generally // the library will trap and report use-after-poison once violated. { - DN_TCScratch scratch_a = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch_a = DN_TCScratchBeginArena(nullptr, 0); // Now imagine we call a function where we pass scratch_a.arena down // into it .. If we call scratch again, we need to pass in the arena // to prevent aliasing. - DN_TCScratch scratch_b = DN_TCScratchBegin(&scratch_a.arena, 1); - DN_Assert(scratch_a.arena != scratch_b.arena); + DN_Arena *conflicts[] = {&scratch_a.arena}; + DN_TCScratch scratch_b = DN_TCScratchBeginArena(conflicts, DN_ArrayCountU(conflicts)); + DN_Assert(scratch_a.arena.mem != scratch_b.arena.mem); DN_TCScratchEnd(&scratch_b); DN_TCScratchEnd(&scratch_a); @@ -18165,7 +18107,7 @@ void DN_Demo() // NOTE: DN_CVT_AgeFromU64 { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8x128 string = DN_AgeStr8FromSecF64(DN_SecFromHours(2) + DN_SecFromMins(30), DN_AgeUnit_All); DN_Assert(DN_Str8Eq(DN_Str8FromStruct(&string), DN_Str8Lit("2h 30m"))); DN_TCScratchEnd(&scratch); @@ -18286,12 +18228,12 @@ void DN_Demo() if (0) { // Generate the error string for the last Win32 API called that return // an error value. - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_OSW32Error get_last_error = DN_OS_W32LastError(scratch.arena); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_OSW32Error get_last_error = DN_OS_W32LastError(&scratch.arena); printf("Error (%lu): %.*s", get_last_error.code, DN_Str8PrintFmt(get_last_error.msg)); // Alternatively, pass in the error code directly - DN_OSW32Error error_msg_for_code = DN_OS_W32ErrorCodeToMsg(scratch.arena, /*error_code*/ 0); + DN_OSW32Error error_msg_for_code = DN_OS_W32ErrorCodeToMsg(&scratch.arena, /*error_code*/ 0); printf("Error (%lu): %.*s", error_msg_for_code.code, DN_Str8PrintFmt(error_msg_for_code.msg)); DN_TCScratchEnd(&scratch); } @@ -18526,7 +18468,7 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { - DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); + DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena); return result; } #define DN_CSV_CPP diff --git a/Single-Header/dn_single_header.h b/Single-Header/dn_single_header.h index 187de8e..596ee7f 100644 --- a/Single-Header/dn_single_header.h +++ b/Single-Header/dn_single_header.h @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2026-06-18 16:40:52 +// Generated by the DN single header generator 2026-06-18 18:20:05 #if !defined(DN_H) #define DN_H @@ -1090,12 +1090,6 @@ struct DN_Allocator void* context; }; -struct DN_ArenaStatsStr8x64 -{ - DN_Str8x64 info; - DN_Str8x64 hwm; -}; - enum DN_ArenaReset { DN_ArenaReset_No, @@ -1253,6 +1247,7 @@ enum DN_Str8FindFlag_ typedef DN_USize DN_Str8SplitFlags; enum DN_Str8SplitFlags_ { + DN_Str8SplitFlags_Nil = 0, DN_Str8SplitFlags_ExcludeEmptyStrings = 1 << 0, DN_Str8SplitFlags_HandleQuotedStrings = 1 << 1, }; @@ -7226,7 +7221,7 @@ DN_API bool DN_OS_FileWriteF (D DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_ErrSink *err); DN_API void DN_OS_FileClose (DN_OSFile *file); -DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_ErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator allocator, DN_Str8 path, DN_ErrSink *err); DN_API DN_Str8 DN_OS_FileReadAllArena (DN_Arena *arena, DN_Str8 path, DN_ErrSink *err); DN_API DN_Str8 DN_OS_FileReadAllPool (DN_Pool *pool, DN_Str8 path, DN_ErrSink *err); diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index a6159f6..b6dfbe9 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -2931,9 +2931,9 @@ DN_API DN_USize DN_Str8Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_Str8FindResult find = DN_Str8FindStr8(DN_Str8Advance(it, 1), DN_Str8Lit("\""), DN_Str8EqCase_Sensitive); DN_Assert(find.found); item = find.start_to_before_match; - it = DN_Str8BSplit(find.after_match_to_end_of_buffer, DN_Str8Lit(",")).rhs; + it = DN_Str8BSplit(find.after_match_to_end_of_buffer, delimiter).rhs; } else { - DN_Str8BSplitResult sub_split = DN_Str8BSplit(it, DN_Str8Lit(",")); + DN_Str8BSplitResult sub_split = DN_Str8BSplit(it, delimiter); item = sub_split.lhs; it = sub_split.rhs; } @@ -2948,7 +2948,7 @@ DN_API DN_USize DN_Str8Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, return result; } -DN_API DN_Str8SplitResult DN_Str8SplitArena(DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitFlags mode) +DN_API DN_Str8SplitResult DN_Str8SplitArena(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitFlags mode, DN_Arena *arena) { DN_Str8SplitResult result = {}; DN_USize count = DN_Str8Split(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode); diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index 516ed71..34b3b4b 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -943,12 +943,6 @@ struct DN_Allocator void* context; }; -struct DN_ArenaStatsStr8x64 -{ - DN_Str8x64 info; - DN_Str8x64 hwm; -}; - enum DN_ArenaReset { DN_ArenaReset_No, @@ -1106,6 +1100,7 @@ enum DN_Str8FindFlag_ typedef DN_USize DN_Str8SplitFlags; enum DN_Str8SplitFlags_ { + DN_Str8SplitFlags_Nil = 0, DN_Str8SplitFlags_ExcludeEmptyStrings = 1 << 0, DN_Str8SplitFlags_HandleQuotedStrings = 1 << 1, }; diff --git a/Source/Base/dn_base_containers.cpp b/Source/Base/dn_base_containers.cpp index f618075..d969478 100644 --- a/Source/Base/dn_base_containers.cpp +++ b/Source/Base/dn_base_containers.cpp @@ -114,12 +114,12 @@ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USi // Compute the range to erase DN_USize start = 0, end = 0; if (count < 0) { - // Erase backwards from begin_index, inclusive of begin_index - // Range: [begin_index + count + 1, begin_index + 1) - // Which is: [begin_index - abs(count) + 1, begin_index + 1) + // Erase backwards from begin_index, not inclusive of begin_index + // Range: [begin_index + count, begin_index) + // Which is: [begin_index - abs(count), begin_index) DN_USize abs_count = DN_Abs(count); - start = (begin_index + 1 > abs_count) ? (begin_index + 1 - abs_count) : 0; - end = begin_index + 1; + start = (begin_index > abs_count) ? (begin_index - abs_count) : 0; + end = begin_index; } else { start = begin_index; end = begin_index + count; @@ -147,7 +147,14 @@ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USi } result.items_erased = erase_count; - result.it_index = start ? start - 1 : start; + // NOTE: If we are erasing from the current index of the iterator to the end of the array then + // there's no more elements in the array to iterate. So the returned index should b + // one-past-last index + if (begin_index == start && end >= *size) { + result.it_index = *size; + } else { + result.it_index = start ? start - 1 : 0; + } return result; } diff --git a/Source/Extra/dn_bin_pack.cpp b/Source/Extra/dn_bin_pack.cpp index e2ab4d9..46432ab 100644 --- a/Source/Extra/dn_bin_pack.cpp +++ b/Source/Extra/dn_bin_pack.cpp @@ -201,6 +201,6 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { - DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); + DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena); return result; } diff --git a/Source/Extra/dn_cgen.cpp b/Source/Extra/dn_cgen.cpp index 0c4d5a1..0da7df7 100644 --- a/Source/Extra/dn_cgen.cpp +++ b/Source/Extra/dn_cgen.cpp @@ -356,7 +356,7 @@ DN_API DN_CGenMapNodeToEnum DN_CGen_MapNodeToEnumOrExit(MD_Node const *node, DN_ DN_Str8BuilderAppendF(&builder, DN_Cast(char *) "%s'%.*s'", index ? ", " : "", DN_Str8PrintFmt(validator->node_string)); } - DN_Str8 error_msg = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_Str8 error_msg = DN_Str8FromStr8BuilderArena(&builder, tmem.arena); DN_TCScratchEnd(&tmem); MD_PrintMessageFmt(stderr, loc, MD_MessageKind_Error, DN_Cast(char *) "%.*s", DN_Str8PrintFmt(error_msg)); DN_OS_Exit(DN_Cast(uint32_t) - 1); @@ -390,7 +390,7 @@ DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_ErrSink *err, ch DN_Str8BuilderAppendFV(&builder, fmt, args); va_end(args); - DN_Str8 msg = DN_Str8BuilderBuild(&builder, err->arena); + DN_Str8 msg = DN_Str8FromStr8BuilderArena(&builder, err->arena); DN_TCScratchEnd(&tmem); DN_OS_ErrSinkAppendF(err, DN_Cast(uint32_t) - 1, "%.*s", DN_Str8PrintFmt(msg)); } @@ -413,7 +413,7 @@ DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *he } if (!result) { - DN_Str8 missing_headers = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_Str8 missing_headers = DN_Str8FromStr8BuilderArena(&builder, tmem.arena); DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, @@ -957,7 +957,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_Str8PrintFmt(cpp_array_size_str8), DN_Str8PrintFmt(cpp_array_size_field_str8)); - DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_Str8 line = DN_Str8FromStr8BuilderArena(&builder, tmem.arena); DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } } else { @@ -1026,7 +1026,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_Str8BuilderAppendF(&builder, "/*array_size*/ 0, "); DN_Str8BuilderAppendF(&builder, "/*array_size_field*/ NULL},"); - DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_Str8 line = DN_Str8FromStr8BuilderArena(&builder, tmem.arena); DN_TCScratchEnd(&tmem); DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } @@ -1117,7 +1117,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil // NOTE: DN_TypeField length DN_Str8BuilderAppendF(&builder, "/*count*/ %.*s},", DN_Str8PrintFmt(fields_count)); - DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_Str8 line = DN_Str8FromStr8BuilderArena(&builder, tmem.arena); DN_TCScratchEnd(&tmem); DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } diff --git a/Source/Extra/dn_demo.cpp b/Source/Extra/dn_demo.cpp index d9d3961..37f78da 100644 --- a/Source/Extra/dn_demo.cpp +++ b/Source/Extra/dn_demo.cpp @@ -30,9 +30,9 @@ void DN_Demo() // NOTE: DN_HexFromBytes { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); unsigned char bytes[2] = {0xFA, 0xCE}; - DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), scratch.arena); + DN_Str8 hex = DN_HexFromPtrBytesArena(bytes, sizeof(bytes), &scratch.arena, DN_TrimLeadingZero_No); DN_Assert(DN_Str8Eq(hex, DN_Str8Lit("face"))); // NOTE: Guaranteed to be null-terminated DN_TCScratchEnd(&scratch); } @@ -428,7 +428,7 @@ void DN_Demo() // If 'tmp_path' is written to successfuly, the file will be copied over into // 'path'. if (0) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_ErrSink *error = DN_TCErrSinkBegin(DN_ErrSinkMode_Nil); DN_OS_FileWriteAllSafe(/*path*/ DN_Str8Lit("C:/Home/my.txt"), /*buffer*/ DN_Str8Lit("Hello world"), error); DN_ErrSinkEndLogErrorF(error, ""); @@ -553,8 +553,8 @@ void DN_Demo() DN_ProfilerNewFrame(&profiler); DN_ProfilerZone zone = DN_ProfilerBeginZone(&profiler, DN_Str8Lit("Main Loop"), DemoZone_MainLoop); DN_OS_SleepMs(100); - DN_ProfilerEndZone(&profiler, zone); - DN_ProfilerDump(&profiler); + DN_ProfilerEndZone(zone); + DN_ProfilerFmtToStdout(&profiler); } } #endif @@ -621,7 +621,7 @@ void DN_Demo() // Int -> U32: 0 or UINT32_MAX // Int -> U64: 0 or UINT64_MAX - // NOTE: DN_OS_StackTrace + // NOTE: DN_StackTrace // Emit stack traces at the calling site that these functions are invoked // from. // @@ -638,23 +638,23 @@ void DN_Demo() // the debug APIs are aware of how to resolve the new addresses imported // into the address space. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); - // NOTE: DN_OS_StackTraceWalk + // NOTE: DN_StackTraceFromArena // // Generate a stack trace as a series of addresses to the base of the // functions on the call-stack at the current instruction pointer. The // addresses are stored in order from the current executing function // first to the most ancestor function last in the walk. - DN_StackTraceWalkResult walk = DN_StackTraceWalk(scratch.arena, /*depth limit*/ 128); + DN_StackTrace walk = DN_StackTraceFromArena(&scratch.arena, /*depth limit*/ 128); // Loop over the addresses produced in the stack trace - for (DN_StackTraceWalkResultIterator it = {}; DN_StackTraceWalkResultIterate(&it, &walk);) { + for (DN_StackTraceIterator it = {}; DN_StackTraceIterate(&it, &walk);) { // NOTE: DN_StackTraceRawFrameToFrame // // Converts the base address into a human readable stack trace // entry (e.g. address, line number, file and function name). - DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(scratch.arena, it.raw_frame); + DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(&scratch.arena, it.raw_frame); // You may then print out the frame like so if (0) @@ -671,7 +671,7 @@ void DN_Demo() // Helper function to create a stack trace and automatically convert the // raw frames into human readable frames. This function effectively // calls 'Walk' followed by 'RawFrameToFrame'. - DN_StackTraceFrameSlice frames = DN_StackTraceGetFrames(scratch.arena, /*depth limit*/ 128); + DN_StackTraceFrameSlice frames = DN_StackTraceGetFrames(&scratch.arena, /*depth limit*/ 128); (void)frames; DN_TCScratchEnd(&scratch); @@ -686,8 +686,8 @@ void DN_Demo() // The returned string's 'size' member variable does *not* include this // additional null-terminating byte. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8AllocArena(scratch.arena, /*size*/ 1, DN_ZMem_Yes); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8AllocArena(/*size*/ 1, DN_ZMem_Yes, &scratch.arena); DN_Assert(string.size == 1); DN_Assert(string.data[string.size] == 0); // It is null-terminated! DN_TCScratchEnd(&scratch); @@ -767,13 +767,13 @@ void DN_Demo() // always be a newly allocated copy, irrespective of if any replacements // were done or not. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"), - /*find*/ DN_Str8Lit("Foo"), - /*replace*/ DN_Str8Lit("Moo"), - /*start_index*/ 1, - /*arena*/ scratch.arena, - /*eq_case*/ DN_Str8EqCase_Sensitive); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"), + /*find*/ DN_Str8Lit("Foo"), + /*replace*/ DN_Str8Lit("Moo"), + /*start_index*/ 1, + /*arena*/ &scratch.arena, + /*eq_case*/ DN_Str8EqCase_Sensitive); DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Foo Moo Bar"))); DN_TCScratchEnd(&scratch); } @@ -786,8 +786,8 @@ void DN_Demo() // Reverse segment delimits the string counting 'segment_size' from the back // of the string. { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8 string = DN_Str8Segment(scratch.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8 string = DN_Str8Segment(&scratch.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); DN_Assert(DN_Str8Eq(string, DN_Str8Lit("123,456,789"))); DN_TCScratchEnd(&scratch); } @@ -796,12 +796,12 @@ void DN_Demo() { // Splits the string at each delimiter into substrings occuring prior and // after until the next delimiter. - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); { - DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena, - /*string*/ DN_Str8Lit("192.168.8.1"), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*string*/ DN_Str8Lit("192.168.8.1"), /*delimiter*/ DN_Str8Lit("."), - /*mode*/ DN_Str8SplitIncludeEmptyStrings_No); + DN_Str8SplitFlags_ExcludeEmptyStrings, + &scratch.arena); DN_Assert(splits.count == 4); DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("192")) && DN_Str8Eq(splits.data[1], DN_Str8Lit("168")) && @@ -812,10 +812,10 @@ void DN_Demo() // You can include empty strings that occur when splitting by setting // the split mode to include empty strings. { - DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena, - /*string*/ DN_Str8Lit("a--b"), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*string*/ DN_Str8Lit("a--b"), /*delimiter*/ DN_Str8Lit("-"), - /*mode*/ DN_Str8SplitIncludeEmptyStrings_Yes); + DN_Str8SplitFlags_Nil, + &scratch.arena); DN_Assert(splits.count == 3); DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("a")) && DN_Str8Eq(splits.data[1], DN_Str8Lit("")) && @@ -955,13 +955,14 @@ void DN_Demo() // caller's arena. If arena aliasing occurs, with ASAN on, generally // the library will trap and report use-after-poison once violated. { - DN_TCScratch scratch_a = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch_a = DN_TCScratchBeginArena(nullptr, 0); // Now imagine we call a function where we pass scratch_a.arena down // into it .. If we call scratch again, we need to pass in the arena // to prevent aliasing. - DN_TCScratch scratch_b = DN_TCScratchBegin(&scratch_a.arena, 1); - DN_Assert(scratch_a.arena != scratch_b.arena); + DN_Arena *conflicts[] = {&scratch_a.arena}; + DN_TCScratch scratch_b = DN_TCScratchBeginArena(conflicts, DN_ArrayCountU(conflicts)); + DN_Assert(scratch_a.arena.mem != scratch_b.arena.mem); DN_TCScratchEnd(&scratch_b); DN_TCScratchEnd(&scratch_a); @@ -989,7 +990,7 @@ void DN_Demo() // NOTE: DN_CVT_AgeFromU64 { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8x128 string = DN_AgeStr8FromSecF64(DN_SecFromHours(2) + DN_SecFromMins(30), DN_AgeUnit_All); DN_Assert(DN_Str8Eq(DN_Str8FromStruct(&string), DN_Str8Lit("2h 30m"))); DN_TCScratchEnd(&scratch); @@ -1110,12 +1111,12 @@ void DN_Demo() if (0) { // Generate the error string for the last Win32 API called that return // an error value. - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_OSW32Error get_last_error = DN_OS_W32LastError(scratch.arena); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_OSW32Error get_last_error = DN_OS_W32LastError(&scratch.arena); printf("Error (%lu): %.*s", get_last_error.code, DN_Str8PrintFmt(get_last_error.msg)); // Alternatively, pass in the error code directly - DN_OSW32Error error_msg_for_code = DN_OS_W32ErrorCodeToMsg(scratch.arena, /*error_code*/ 0); + DN_OSW32Error error_msg_for_code = DN_OS_W32ErrorCodeToMsg(&scratch.arena, /*error_code*/ 0); printf("Error (%lu): %.*s", error_msg_for_code.code, DN_Str8PrintFmt(error_msg_for_code.msg)); DN_TCScratchEnd(&scratch); } diff --git a/Source/Extra/dn_tests.cpp b/Source/Extra/dn_tests.cpp index daeca15..5e68f37 100644 --- a/Source/Extra/dn_tests.cpp +++ b/Source/Extra/dn_tests.cpp @@ -1222,7 +1222,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 2); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1231,9 +1231,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable); - int expected[] = {0, 1, 2, 6, 7, 8, 9}; + int expected[] = {0, 1, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 1); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1242,9 +1242,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable); - int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9}; + int expected[] = {0, 1, 2, 3, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 5); + DN_UT_AssertF(&result, erase.it_index == 3, "lhs=%zu", erase.it_index); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1255,7 +1255,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 8, 9, 5, 6, 7}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 2); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1264,9 +1264,9 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable); - int expected[] = {0, 1, 2, 7, 8, 9, 6}; + int expected[] = {0, 1, 7, 8, 9, 5, 6}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 3); + DN_UT_Assert(&result, erase.it_index == 1); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1275,10 +1275,10 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable); - int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - DN_UT_Assert(&result, erase.items_erased == 1); + int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + DN_UT_Assert(&result, erase.items_erased == 0); DN_UT_Assert(&result, erase.it_index == 0); - DN_UT_Assert(&result, size == 9); + DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1299,7 +1299,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1308,7 +1308,7 @@ static DN_UTCore DN_TST_BaseArray() DN_USize size = 10; DN_ArrayEraseResult erase = DN_ArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 10); } @@ -1316,7 +1316,7 @@ static DN_UTCore DN_TST_BaseArray() int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); } for (DN_UT_Test(&result, "Invalid input - empty array")) { @@ -1324,7 +1324,7 @@ static DN_UTCore DN_TST_BaseArray() DN_USize size = 0; DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable); DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 0); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 0); } @@ -1334,7 +1334,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 10); + DN_UT_Assert(&result, erase.it_index == 9); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1361,77 +1361,11 @@ static DN_UTCore DN_TST_BaseVArray() DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); } - for (DN_UT_Test(&result, "Test stable erase, 1 item, the '2' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase, 1 item, the '1' value from the array")) { - DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - DN_ArrayErase erase_enums[] = {DN_ArrayErase_Stable, DN_ArrayErase_Unstable}; - for (DN_UT_Test(&result, "Test un/stable erase, OOB")) { - for (DN_ArrayErase erase : erase_enums) { - DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_OS_VArrayEraseRange(&array, DN_ArrayCountU(array_literal) /*begin_index*/, DN_ArrayCountU(array_literal) + 100 /*count*/, erase); - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - } - - for (DN_UT_Test(&result, "Test flipped begin/end index stable erase, 2 items, the '15, 3' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test flipped begin/end index unstable erase, 2 items, the '4, 5' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10, 11, 12}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test stable erase range, 2+1 (oob) item, the '13, 14, +1 OOB' value from the array")) { - DN_OS_VArrayEraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase range, 3+1 (oob) item, the '11, 12, +1 OOB' value from the array")) { - DN_OS_VArrayEraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test stable erase -overflow OOB, erasing the '0, 13' value from the array")) { - DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable); - DN_U32 array_literal[] = {14, 6, 7, 8}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test unstable erase +overflow OOB, erasing the '7, 8' value from the array")) { - DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable); - DN_U32 array_literal[] = {14, 6}; - DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); - DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); - } - - for (DN_UT_Test(&result, "Test adding an array of items after erase")) { + for (DN_UT_Test(&result, "Test adding an array of items")) { DN_U32 array_literal[] = {0, 1, 2, 3}; DN_OS_VArrayAddArray(&array, array_literal, DN_ArrayCountU(array_literal)); - DN_U32 expected_literal[] = {14, 6, 0, 1, 2, 3}; + DN_U32 expected_literal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3}; DN_UT_Assert(&result, array.size == DN_ArrayCountU(expected_literal)); DN_UT_Assert(&result, DN_Memcmp(array.data, expected_literal, DN_ArrayCountU(expected_literal) * sizeof(expected_literal[0])) == 0); } diff --git a/Source/OS/dn_os.h b/Source/OS/dn_os.h index c92b16a..8366ef5 100644 --- a/Source/OS/dn_os.h +++ b/Source/OS/dn_os.h @@ -368,7 +368,7 @@ DN_API bool DN_OS_FileWriteF (D DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_ErrSink *err); DN_API void DN_OS_FileClose (DN_OSFile *file); -DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_ErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator allocator, DN_Str8 path, DN_ErrSink *err); DN_API DN_Str8 DN_OS_FileReadAllArena (DN_Arena *arena, DN_Str8 path, DN_ErrSink *err); DN_API DN_Str8 DN_OS_FileReadAllPool (DN_Pool *pool, DN_Str8 path, DN_ErrSink *err);