Convert binary search to a C style impl
This commit is contained in:
+272
-203
@@ -2677,14 +2677,14 @@ DN_API DN_U8x32 DN_U8x32FromHexUnsafe(DN_Str8 hex_32b)
|
||||
DN_U8x32 result = {};
|
||||
hex_32b = DN_Str8TrimHexPrefix(hex_32b);
|
||||
DN_Assert(hex_32b.count <= sizeof(result.data) * 2);
|
||||
DN_BytesFromHexPtr(hex_32b.data, hex_32b.count, result.data, sizeof(result.data));
|
||||
DN_PtrBytesFromPtrHex(hex_32b.data, hex_32b.count, result.data, sizeof(result.data));
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U8x32FromResult DN_U8x32FromHex(DN_Str8 hex_32b)
|
||||
{
|
||||
DN_U8x32FromResult result = {};
|
||||
DN_USize bytes_written = DN_BytesFromHexPtr(hex_32b.data, hex_32b.count, result.value.data, sizeof(result.value.data));
|
||||
DN_USize bytes_written = DN_PtrBytesFromPtrHex(hex_32b.data, hex_32b.count, result.value.data, sizeof(result.value.data));
|
||||
if (bytes_written == sizeof(result.value.data))
|
||||
result.success = true;
|
||||
return result;
|
||||
@@ -4984,7 +4984,7 @@ DN_API DN_NibbleFromU8Result DN_NibbleFromU8(DN_U8 u8)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_BytesFromHex(DN_Str8 hex, void *dest, DN_USize dest_count)
|
||||
DN_API DN_USize DN_PtrBytesFromStr8Hex(DN_Str8 hex, void *dest, DN_USize dest_count)
|
||||
{
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(hex);
|
||||
DN_USize result = 0;
|
||||
@@ -5017,65 +5017,65 @@ DN_API DN_USize DN_BytesFromHex(DN_Str8 hex, void *dest, DN_USize dest_count)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_BytesFromHexArena(DN_Str8 hex, DN_Arena *arena)
|
||||
DN_API DN_USize DN_PtrBytesFromPtrHex(char const *hex, DN_USize hex_count, void *dest, DN_USize dest_count)
|
||||
{
|
||||
DN_Str8 result = DN_BytesFromHexPtrArena(hex.data, hex.count, arena);
|
||||
DN_USize result = DN_PtrBytesFromStr8Hex(DN_Str8FromPtr(hex, hex_count), dest, dest_count);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_BytesFromHexPtr(char const *hex, DN_USize hex_count, void *dest, DN_USize dest_count)
|
||||
DN_API DN_Str8 DN_Str8BytesFromStr8HexArena(DN_Str8 hex, DN_Arena *arena)
|
||||
{
|
||||
DN_USize result = DN_BytesFromHex(DN_Str8FromPtr(hex, hex_count), dest, dest_count);
|
||||
DN_Str8 result = DN_Str8BytesFromPtrHexArena(hex.data, hex.count, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_BytesFromHexPtrArena(char const *hex, DN_USize hex_count, DN_Arena *arena)
|
||||
DN_API DN_Str8 DN_Str8BytesFromPtrHexArena(char const *hex, DN_USize hex_count, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count % 2 == 0);
|
||||
DN_Str8 result = {};
|
||||
result.data = DN_ArenaNewArray(arena, char, hex_trimmed.count / 2, DN_ZMem_No);
|
||||
if (result.data)
|
||||
result.count = DN_BytesFromHex(hex_trimmed, result.data, hex_trimmed.count / 2);
|
||||
result.count = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, hex_trimmed.count / 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_BytesFromHexPtrPool(char const *hex, DN_USize hex_count, DN_Pool *pool)
|
||||
DN_API DN_Str8 DN_Str8BytesFromPtrHexPool(char const *hex, DN_USize hex_count, DN_Pool *pool)
|
||||
{
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count % 2 == 0);
|
||||
DN_Str8 result = {};
|
||||
result.data = DN_PoolNewArray(pool, char, hex_trimmed.count / 2);
|
||||
if (result.data)
|
||||
result.count = DN_BytesFromHex(hex_trimmed, result.data, hex_trimmed.count / 2);
|
||||
result.count = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, hex_trimmed.count / 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DN_API DN_U8x16 DN_BytesFromHex32Ptr(char const *hex, DN_USize hex_count)
|
||||
DN_API DN_U8x16 DN_U8x16FromPtrHex32(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x16 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_BytesFromHex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U8x32 DN_BytesFromHex64Ptr(char const *hex, DN_USize hex_count)
|
||||
DN_API DN_U8x32 DN_U8x32FromPtrHex64(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x32 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_BytesFromHex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_HexU64 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type)
|
||||
DN_API DN_HexU64 DN_HexU64FromU64(DN_U64 value, DN_HexFromU64Type type)
|
||||
{
|
||||
DN_HexU64 result = {};
|
||||
DN_USize count = DN_HexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No);
|
||||
DN_USize count = DN_PtrHexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No);
|
||||
result.count = DN_SaturateCastUSizeToU8(count);
|
||||
if (type == DN_HexFromU64Type_Uppercase) {
|
||||
for (DN_USize index = 0; index < result.count; index++)
|
||||
@@ -5084,7 +5084,7 @@ DN_API DN_HexU64 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_HexFromPtrBytes(void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_USize DN_PtrHexFromPtrBytes(void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
if ((bytes_count * 2) > hex_count)
|
||||
@@ -5116,57 +5116,57 @@ DN_API DN_USize DN_HexFromPtrBytes(void const *bytes, DN_USize bytes_count, void
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_HexFromPtrBytesArena(void const *bytes, DN_USize bytes_count, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_Str8 DN_Str8HexFromPtrBytesArena(void const *bytes, DN_USize bytes_count, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (bytes_count) {
|
||||
result.data = DN_ArenaNewArray(arena, char, bytes_count * 2, DN_ZMem_No);
|
||||
if (result.data)
|
||||
result.count = DN_HexFromPtrBytes(bytes, bytes_count, result.data, bytes_count * 2, trim_leading_z);
|
||||
result.count = DN_PtrHexFromPtrBytes(bytes, bytes_count, result.data, bytes_count * 2, trim_leading_z);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_HexFromStr8Bytes(DN_Str8 bytes, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_USize DN_PtrHexFromStr8Bytes(DN_Str8 bytes, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_USize result = DN_HexFromPtrBytes(bytes.data, bytes.count, hex, hex_count, trim_leading_z);
|
||||
DN_USize result = DN_PtrHexFromPtrBytes(bytes.data, bytes.count, hex, hex_count, trim_leading_z);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_HexFromStr8BytesArena(DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_Str8 DN_Str8HexFromStr8BytesArena(DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (bytes.count) {
|
||||
result.data = DN_ArenaNewArray(arena, char, bytes.count * 2, DN_ZMem_No);
|
||||
if (result.data)
|
||||
result.count = DN_HexFromStr8Bytes(bytes, result.data, bytes.count * 2, trim_leading_z);
|
||||
result.count = DN_PtrHexFromStr8Bytes(bytes, result.data, bytes.count * 2, trim_leading_z);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Hex32 DN_Hex32FromPtr16b(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_Hex32 DN_Hex32FromPtrBytes16(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_Hex32 result = {};
|
||||
DN_Assert(bytes_count * 2 == sizeof result.data - 1);
|
||||
result.count = DN_HexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
result.count = DN_PtrHexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
DN_Assert(result.count <= sizeof result.data - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Hex64 DN_Hex64FromPtr32b(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_Hex64 DN_Hex64FromPtrBytes32(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_Hex64 result = {};
|
||||
DN_Assert(bytes_count * 2 == sizeof result.data - 1);
|
||||
result.count = DN_HexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
result.count = DN_PtrHexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
DN_Assert(result.count <= sizeof result.data - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Hex128 DN_Hex128FromPtr64b(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
DN_API DN_Hex128 DN_Hex128FromPtrBytes64(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||
{
|
||||
DN_Hex128 result = {};
|
||||
DN_Assert(bytes_count * 2 == sizeof result.data - 1);
|
||||
result.count = DN_HexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
result.count = DN_PtrHexFromPtrBytes(bytes, bytes_count, result.data, sizeof result.data, trim_leading_z);
|
||||
DN_Assert(result.count <= sizeof result.data - 1);
|
||||
return result;
|
||||
}
|
||||
@@ -5746,7 +5746,7 @@ DN_API bool DN_QSortCompareStr8LexicographicDesc(void const* lhs, void const *rh
|
||||
DN_API bool DN_QSortCompareBytesLT(void const* lhs, void const *rhs, void *user_context)
|
||||
{
|
||||
DN_USize elem_size = *DN_Cast(DN_USize *)user_context;
|
||||
bool result = DN_Memcmp(lhs, rhs, elem_size) < 0;
|
||||
bool result = DN_Memcmp(lhs, rhs, elem_size) < 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5787,6 +5787,75 @@ DN_API void DN_QSortStr8LexicographicDesc(DN_Str8 *array, DN_USize array_size, D
|
||||
DN_QSort(array, array_size, sizeof(*array), /*user_context=*/ &eq_case, DN_QSortCompareStr8LexicographicDesc);
|
||||
}
|
||||
|
||||
DN_API bool DN_BSearchLessThanBytes(void const *lhs, void const *rhs, void *user_context)
|
||||
{
|
||||
DN_USize elem_size = *DN_Cast(DN_USize *)user_context;
|
||||
bool result = DN_Memcmp(lhs, rhs, elem_size) < 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_BSearchResult DN_BSearch(void const *array, DN_USize count, DN_USize elem_size, void const *find, DN_BSearchType type, void *user_context, DN_BSearchLessThanFunc *less_than)
|
||||
{
|
||||
DN_BSearchResult result = {};
|
||||
if (!array || count <= 0 || !less_than || !find)
|
||||
return result;
|
||||
|
||||
void const *end = DN_Cast(char *)array + (count * elem_size);
|
||||
void const *first = array;
|
||||
void const *last = end;
|
||||
while (first != last) {
|
||||
DN_USize dist = (DN_Cast(char *)last - DN_Cast(char *)first) / elem_size;
|
||||
void const *it = DN_Cast(char *)first + ((dist / 2) * elem_size);
|
||||
bool advance_first = false;
|
||||
if (type == DN_BSearchType_UpperBound)
|
||||
advance_first = !less_than(find, it, user_context);
|
||||
else
|
||||
advance_first = less_than(it, find, user_context);
|
||||
|
||||
if (advance_first)
|
||||
first = DN_Cast(char *)it + (1 * elem_size);
|
||||
else
|
||||
last = it;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DN_BSearchType_Match: {
|
||||
result.found = first != end && !less_than(find, first, user_context);
|
||||
} break;
|
||||
|
||||
case DN_BSearchType_LowerBound: /*FALLTHRU*/
|
||||
case DN_BSearchType_UpperBound: {
|
||||
result.found = first != end;
|
||||
} break;
|
||||
}
|
||||
|
||||
result.index = (DN_Cast(char *)first - DN_Cast(char *)array) / elem_size;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_BSearchResult DN_BSearchBytes(void const *array, DN_USize count, DN_USize elem_size, void const *find, DN_BSearchType type)
|
||||
{
|
||||
DN_BSearchResult result = DN_BSearch(array, count, elem_size, find, type, &elem_size, DN_BSearchLessThanBytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_BSearchResult DN_BSearchUSize(DN_USize const *array, DN_USize count, DN_USize find, DN_BSearchType type)
|
||||
{
|
||||
DN_BSearchResult result = DN_BSearchBytes(array, count, sizeof(*array), &find, type);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_BSearchResult DN_BSearchU64(DN_U64 const *array, DN_USize count, DN_U64 find, DN_BSearchType type)
|
||||
{
|
||||
DN_BSearchResult result = DN_BSearchBytes(array, count, sizeof(*array), &find, type);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_BSearchResult DN_BSearchU32(DN_U32 const *array, DN_USize count, DN_U32 find, DN_BSearchType type)
|
||||
{
|
||||
DN_BSearchResult result = DN_BSearchBytes(array, count, sizeof(*array), &find, type);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DN_PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL
|
||||
#define DN_PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL
|
||||
@@ -9301,6 +9370,109 @@ DN_API void DN_TestEnd(DN_TestCore *test)
|
||||
group->curr_entry = nullptr;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8FromTestCore(DN_TestCore const *test, DN_Arena *arena, DN_Str8FromTestCoreFlags flags)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
DN_USize padding_count = 100;
|
||||
DN_Str8 padding_line = DN_Str8FillF(&scratch.arena, padding_count, ".");
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour)
|
||||
padding_line = DN_Str8FromFmtANSIColourU8RGBArena(DN_ANSIColourMode_Fg, 64, 64, 64, &scratch.arena, "%.*s", DN_Str8PrintFmt(padding_line));
|
||||
|
||||
DN_V3F32 const good_colour = DN_V3F32From3N(0, 255, 0);
|
||||
DN_V3F32 const bad_colour = DN_V3F32From3N(255, 0, 0);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(arena);
|
||||
for (DN_ForItSize(group_it, DN_TestGroup const, test->groups, test->groups_count)) {
|
||||
DN_TestGroup const* group = group_it.data;
|
||||
DN_USize group_successes = 0;
|
||||
DN_USize group_failures = 0;
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6067) // _Param_(5) in call to 'DN_Str8BuilderAppendF' must be the address of a string. Actual type: 'const unsigned __int64'.
|
||||
DN_MSVC_WARNING_DISABLE(6271) // Extra argument passed to 'DN_Str8BuilderAppendF'.
|
||||
DN_Str8BuilderAppendF(&builder, "[%.*s] (%'zu test%s)\n", DN_Str8PrintFmt(group->name), group->entries_count, (group->entries_count > 1) ? "s" : "");
|
||||
DN_MSVC_WARNING_POP
|
||||
for (DN_ForItSize(entry_it, DN_TestEntry const, group->entries, group->entries_count)) {
|
||||
DN_TestEntry const* entry = entry_it.data;
|
||||
if (entry->failed)
|
||||
group_failures++;
|
||||
else
|
||||
group_successes++;
|
||||
|
||||
// NOTE: Extract the test name and pad the line with dots (.)
|
||||
DN_Str8 test_prefix = DN_Str8FromFmtArena(&scratch.arena, " [%zu/%zu] %.*s ", entry_it.index + 1, group->entries_count, DN_Str8PrintFmt(entry->name));
|
||||
if (test_prefix.count < padding_line.count) {
|
||||
DN_USize remaining = padding_line.count - test_prefix.count;
|
||||
DN_Str8 padder = DN_Str8Subset(padding_line, 0, remaining);
|
||||
test_prefix = DN_Str8AppendF(&scratch.arena, test_prefix, "%.*s", DN_Str8PrintFmt(padder));
|
||||
}
|
||||
|
||||
// NOTE: Construct the test line
|
||||
DN_Str8 outcome_str8 = entry->failed ? DN_Str8Lit("FAILED") : DN_Str8Lit("OK");
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour) {
|
||||
if (entry->failed)
|
||||
outcome_str8 = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, bad_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(outcome_str8));
|
||||
else
|
||||
outcome_str8 = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, good_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(outcome_str8));
|
||||
}
|
||||
|
||||
DN_F64 elapsed_ms = DN_OS_PerfCounterMs(entry->ts_begin, entry->ts_end);
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s %.*s (%.3fms)\n", DN_Str8PrintFmt(test_prefix), DN_Str8PrintFmt(outcome_str8), elapsed_ms);
|
||||
|
||||
// NOTE: Output the test diagnostics, populated on failure
|
||||
if (entry->failed) {
|
||||
for (DN_ForItSize(row_it, DN_TestDiagnosticRow, entry->diagnostics, entry->diagnostics_count)) {
|
||||
DN_USize row_count = 1;
|
||||
DN_Str8TableFlags table_flags = DN_Str8TableFlags_None;
|
||||
if (row_it.index == 0) {
|
||||
row_count++; // Header
|
||||
table_flags |= DN_Str8TableFlags_HasHeader;
|
||||
}
|
||||
|
||||
DN_USize col_count = 3; // Expression, Eval, Call site
|
||||
DN_USize row_index = 0;
|
||||
DN_Str8 *rows_str8 = DN_ArenaNewArrayZ(&scratch.arena, DN_Str8, row_count * col_count);
|
||||
if (row_it.index == 0) {
|
||||
rows_str8[row_index++] = DN_Str8Lit("Expr.");
|
||||
rows_str8[row_index++] = DN_Str8Lit("Eval.");
|
||||
rows_str8[row_index++] = DN_Str8Lit("Location");
|
||||
}
|
||||
|
||||
DN_TestDiagnosticRow *row = row_it.data;
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(row->call_site.file);
|
||||
rows_str8[row_index++] = row->expr;
|
||||
rows_str8[row_index++] = row->invariant;
|
||||
rows_str8[row_index++] = DN_Str8FromFmtArena(&scratch.arena, "%.*s:%u", DN_Str8PrintFmt(file_name), row->call_site.line);
|
||||
|
||||
DN_Str8 table = DN_Str8Table(rows_str8, row_count, col_count, table_flags, &scratch.arena);
|
||||
table = DN_Str8PadNewLinesArena(table, DN_Str8Lit(" "), &scratch.arena);
|
||||
DN_Str8BuilderAppendF(&builder, " %.*s\n", DN_Str8PrintFmt(table));
|
||||
if (row->message.count) {
|
||||
DN_Str8 line_break = DN_Str8LineBreakArena(row->message, 100, DN_Str8Lit("\n "), DN_Str8LineBreakMode_AtWord, &scratch.arena);
|
||||
DN_Str8BuilderAppendF(&builder, " User Message: %.*s\n", DN_Str8PrintFmt(line_break));
|
||||
}
|
||||
}
|
||||
DN_Str8BuilderAppendF(&builder, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
DN_F64 elapsed_ms = DN_OS_PerfCounterMs(group->ts_begin, group->ts_end);
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6067) // _Param_(3) in call to 'DN_Str8BuilderAppendF' must be the address of a string. Actual type: 'const unsigned __int64'.
|
||||
DN_MSVC_WARNING_DISABLE(6271) // Extra argument passed to 'DN_Str8BuilderAppendF'.
|
||||
DN_Str8 group_prefix = DN_Str8FromFmtArena(&scratch.arena, "%'zu/%'zu test%s", group_successes, group->entries_count, group_successes > 1 ? "s" :"");
|
||||
DN_MSVC_WARNING_POP
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour) {
|
||||
if (group_failures == 0)
|
||||
group_prefix = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, good_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(group_prefix));
|
||||
else
|
||||
group_prefix = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, bad_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(group_prefix));
|
||||
}
|
||||
DN_Str8BuilderAppendF(&builder, "\n %.*s passed in [%.*s] %.3fms (%zu failed)\n", DN_Str8PrintFmt(group_prefix), DN_Str8PrintFmt(group->name), elapsed_ms, group_failures);
|
||||
}
|
||||
|
||||
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_TestDiagnosticRow *DN_TestVerifySetupFmtV(DN_TestCore *test, DN_CallSite call_site, DN_Str8 expr, bool verify_failed, char const *fmt, va_list args)
|
||||
{
|
||||
DN_AssertF(test->curr_group, "Test group must be started before attempting to verify a test invariant");
|
||||
@@ -9442,8 +9614,8 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
|
||||
DN_TestDiagnosticRow *row = DN_TestVerifySetupFmtV(test, call_site, expr, verify_failed, fmt, args);
|
||||
va_end(args);
|
||||
if (row) {
|
||||
DN_Str8 bytes_hex = DN_HexFromStr8BytesArena(bytes, test->arena, DN_TrimLeadingZero_No);
|
||||
DN_Str8 expect_hex = DN_HexFromStr8BytesArena(expect, test->arena, DN_TrimLeadingZero_No);
|
||||
DN_Str8 bytes_hex = DN_Str8HexFromStr8BytesArena(bytes, test->arena, DN_TrimLeadingZero_No);
|
||||
DN_Str8 expect_hex = DN_Str8HexFromStr8BytesArena(expect, test->arena, DN_TrimLeadingZero_No);
|
||||
if (expect_eq)
|
||||
row->invariant = DN_Str8FromFmtArena(test->arena, "\"%.*s\" != \"%.*s\"", DN_Str8PrintFmt(bytes_hex), DN_Str8PrintFmt(expect_hex));
|
||||
else
|
||||
@@ -9451,109 +9623,6 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
|
||||
}
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8FromTestCore(DN_TestCore const *test, DN_Arena *arena, DN_Str8FromTestCoreFlags flags)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
DN_USize padding_count = 100;
|
||||
DN_Str8 padding_line = DN_Str8FillF(&scratch.arena, padding_count, ".");
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour)
|
||||
padding_line = DN_Str8FromFmtANSIColourU8RGBArena(DN_ANSIColourMode_Fg, 64, 64, 64, &scratch.arena, "%.*s", DN_Str8PrintFmt(padding_line));
|
||||
|
||||
DN_V3F32 const good_colour = DN_V3F32From3N(0, 255, 0);
|
||||
DN_V3F32 const bad_colour = DN_V3F32From3N(255, 0, 0);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(arena);
|
||||
for (DN_ForItSize(group_it, DN_TestGroup const, test->groups, test->groups_count)) {
|
||||
DN_TestGroup const* group = group_it.data;
|
||||
DN_USize group_successes = 0;
|
||||
DN_USize group_failures = 0;
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6067) // _Param_(5) in call to 'DN_Str8BuilderAppendF' must be the address of a string. Actual type: 'const unsigned __int64'.
|
||||
DN_MSVC_WARNING_DISABLE(6271) // Extra argument passed to 'DN_Str8BuilderAppendF'.
|
||||
DN_Str8BuilderAppendF(&builder, "[%.*s] (%'zu test%s)\n", DN_Str8PrintFmt(group->name), group->entries_count, (group->entries_count > 1) ? "s" : "");
|
||||
DN_MSVC_WARNING_POP
|
||||
for (DN_ForItSize(entry_it, DN_TestEntry const, group->entries, group->entries_count)) {
|
||||
DN_TestEntry const* entry = entry_it.data;
|
||||
if (entry->failed)
|
||||
group_failures++;
|
||||
else
|
||||
group_successes++;
|
||||
|
||||
// NOTE: Extract the test name and pad the line with dots (.)
|
||||
DN_Str8 test_prefix = DN_Str8FromFmtArena(&scratch.arena, " [%zu/%zu] %.*s ", entry_it.index + 1, group->entries_count, DN_Str8PrintFmt(entry->name));
|
||||
if (test_prefix.count < padding_line.count) {
|
||||
DN_USize remaining = padding_line.count - test_prefix.count;
|
||||
DN_Str8 padder = DN_Str8Subset(padding_line, 0, remaining);
|
||||
test_prefix = DN_Str8AppendF(&scratch.arena, test_prefix, "%.*s", DN_Str8PrintFmt(padder));
|
||||
}
|
||||
|
||||
// NOTE: Construct the test line
|
||||
DN_Str8 outcome_str8 = entry->failed ? DN_Str8Lit("FAILED") : DN_Str8Lit("OK");
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour) {
|
||||
if (entry->failed)
|
||||
outcome_str8 = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, bad_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(outcome_str8));
|
||||
else
|
||||
outcome_str8 = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, good_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(outcome_str8));
|
||||
}
|
||||
|
||||
DN_F64 elapsed_ms = DN_OS_PerfCounterMs(entry->ts_begin, entry->ts_end);
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s %.*s (%.3fms)\n", DN_Str8PrintFmt(test_prefix), DN_Str8PrintFmt(outcome_str8), elapsed_ms);
|
||||
|
||||
// NOTE: Output the test diagnostics, populated on failure
|
||||
if (entry->failed) {
|
||||
for (DN_ForItSize(row_it, DN_TestDiagnosticRow, entry->diagnostics, entry->diagnostics_count)) {
|
||||
DN_USize row_count = 1;
|
||||
DN_Str8TableFlags table_flags = DN_Str8TableFlags_None;
|
||||
if (row_it.index == 0) {
|
||||
row_count++; // Header
|
||||
table_flags |= DN_Str8TableFlags_HasHeader;
|
||||
}
|
||||
|
||||
DN_USize col_count = 3; // Expression, Eval, Call site
|
||||
DN_USize row_index = 0;
|
||||
DN_Str8 *rows_str8 = DN_ArenaNewArrayZ(&scratch.arena, DN_Str8, row_count * col_count);
|
||||
if (row_it.index == 0) {
|
||||
rows_str8[row_index++] = DN_Str8Lit("Expr.");
|
||||
rows_str8[row_index++] = DN_Str8Lit("Eval.");
|
||||
rows_str8[row_index++] = DN_Str8Lit("Location");
|
||||
}
|
||||
|
||||
DN_TestDiagnosticRow *row = row_it.data;
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(row->call_site.file);
|
||||
rows_str8[row_index++] = row->expr;
|
||||
rows_str8[row_index++] = row->invariant;
|
||||
rows_str8[row_index++] = DN_Str8FromFmtArena(&scratch.arena, "%.*s:%u", DN_Str8PrintFmt(file_name), row->call_site.line);
|
||||
|
||||
DN_Str8 table = DN_Str8Table(rows_str8, row_count, col_count, table_flags, &scratch.arena);
|
||||
table = DN_Str8PadNewLinesArena(table, DN_Str8Lit(" "), &scratch.arena);
|
||||
DN_Str8BuilderAppendF(&builder, " %.*s\n", DN_Str8PrintFmt(table));
|
||||
if (row->message.count) {
|
||||
DN_Str8 line_break = DN_Str8LineBreakArena(row->message, 100, DN_Str8Lit("\n "), DN_Str8LineBreakMode_AtWord, &scratch.arena);
|
||||
DN_Str8BuilderAppendF(&builder, " User Message: %.*s\n", DN_Str8PrintFmt(line_break));
|
||||
}
|
||||
}
|
||||
DN_Str8BuilderAppendF(&builder, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
DN_F64 elapsed_ms = DN_OS_PerfCounterMs(group->ts_begin, group->ts_end);
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6067) // _Param_(3) in call to 'DN_Str8BuilderAppendF' must be the address of a string. Actual type: 'const unsigned __int64'.
|
||||
DN_MSVC_WARNING_DISABLE(6271) // Extra argument passed to 'DN_Str8BuilderAppendF'.
|
||||
DN_Str8 group_prefix = DN_Str8FromFmtArena(&scratch.arena, "%'zu/%'zu test%s", group_successes, group->entries_count, group_successes > 1 ? "s" :"");
|
||||
DN_MSVC_WARNING_POP
|
||||
if (flags & DN_Str8FromTestCoreFlags_Colour) {
|
||||
if (group_failures == 0)
|
||||
group_prefix = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, good_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(group_prefix));
|
||||
else
|
||||
group_prefix = DN_Str8FromFmtANSIColourV3F32RGB255Arena(DN_ANSIColourMode_Fg, bad_colour, &scratch.arena, "%.*s", DN_Str8PrintFmt(group_prefix));
|
||||
}
|
||||
DN_Str8BuilderAppendF(&builder, "\n %.*s passed in [%.*s] %.3fms (%zu failed)\n", DN_Str8PrintFmt(group_prefix), DN_Str8PrintFmt(group->name), elapsed_ms, group_failures);
|
||||
}
|
||||
|
||||
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if DN_WITH_TESTS
|
||||
#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
|
||||
// NOTE: Taken from MSDN __cpuid example implementation
|
||||
@@ -9999,261 +10068,261 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: BytesHex
|
||||
// NOTE: Hex/Bytes
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena_, 1);
|
||||
DN_DEFER { DN_TCScratchEnd(&scratch); };
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 0x123")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 0x123")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x123"));
|
||||
DN_TestVerifyExprF(&result, val == 0x123, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 0xFFFF")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 0xFFFF")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xFFFF"));
|
||||
DN_TestVerifyExprF(&result, val == 0xFFFF, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert FFFF")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert FFFF")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("FFFF"));
|
||||
DN_TestVerifyExprF(&result, val == 0xFFFF, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert abCD")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert abCD")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("abCD"));
|
||||
DN_TestVerifyExprF(&result, val == 0xabCD, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 0xabCD")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 0xabCD")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xabCD"));
|
||||
DN_TestVerifyExprF(&result, val == 0xabCD, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 0x")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 0x")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x"));
|
||||
DN_TestVerifyExprF(&result, val == 0x0, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 0X")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 0X")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0X"));
|
||||
DN_TestVerifyExprF(&result, val == 0x0, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert 3")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert 3")) {
|
||||
uint64_t val = DN_U64FromHexStr8Unsafe(DN_Str8Lit("3"));
|
||||
DN_TestVerifyExprF(&result, val == 3, "val: %" PRIu64, val);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert f")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert f")) {
|
||||
DN_U64FromResult res = DN_U64FromHexStr8(DN_Str8Lit("f"));
|
||||
DN_TestVerifyExpr(&result, res.success);
|
||||
DN_TestVerifyExpr(&result, res.value == 0xf);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert g")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert g")) {
|
||||
DN_U64FromResult res = DN_U64FromHexStr8(DN_Str8Lit("g"));
|
||||
DN_TestVerifyExpr(&result, !res.success);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert -0x3")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert -0x3")) {
|
||||
DN_U64FromResult res = DN_U64FromHexStr8(DN_Str8Lit("-0x3"));
|
||||
DN_TestVerifyExpr(&result, !res.success);
|
||||
}
|
||||
|
||||
DN_U32 number = 0xd095f6;
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_HexFromPtrBytesArena(&number, sizeof(number), &scratch.arena, DN_TrimLeadingZero_No);
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_Str8HexFromPtrBytesArena(&number, sizeof(number), &scratch.arena, DN_TrimLeadingZero_No);
|
||||
DN_TestVerifyStr8EqF(&result, number_hex, DN_Str8Lit("f695d000"), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
number = 0xf6ed00;
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_HexFromPtrBytesArena(&number, sizeof(number), &scratch.arena, DN_TrimLeadingZero_No);
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_Str8HexFromPtrBytesArena(&number, sizeof(number), &scratch.arena, DN_TrimLeadingZero_No);
|
||||
DN_TestVerifyStr8EqF(&result, number_hex, DN_Str8Lit("00edf600"), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
DN_Str8 hex = DN_Str8Lit("0xf6ed00");
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert %.*s to bytes", DN_Str8PrintFmt(hex))) {
|
||||
DN_Str8 bytes = DN_BytesFromHexArena(hex, &scratch.arena);
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert %.*s to bytes", DN_Str8PrintFmt(hex))) {
|
||||
DN_Str8 bytes = DN_Str8BytesFromStr8HexArena(hex, &scratch.arena);
|
||||
DN_TestVerifyStr8EqF(&result,
|
||||
bytes,
|
||||
DN_Str8Lit("\xf6\xed\x00"),
|
||||
"number_hex=%.*s",
|
||||
DN_Str8PrintFmt(DN_HexFromPtrBytesArena(bytes.data, bytes.count, &scratch.arena, DN_TrimLeadingZero_No)));
|
||||
DN_Str8PrintFmt(DN_Str8HexFromPtrBytesArena(bytes.data, bytes.count, &scratch.arena, DN_TrimLeadingZero_No)));
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BytesHex] Convert empty bytes to string")) {
|
||||
for (DN_TestScopeF(&result, "[Hex/Bytes] Convert empty bytes to string")) {
|
||||
DN_Str8 bytes = DN_Str8Lit("");
|
||||
DN_Str8 as_hex = DN_HexFromPtrBytesArena(bytes.data, bytes.count, &scratch.arena, DN_TrimLeadingZero_No);
|
||||
DN_Str8 as_hex = DN_Str8HexFromPtrBytesArena(bytes.data, bytes.count, &scratch.arena, DN_TrimLeadingZero_No);
|
||||
DN_TestVerifyStr8EqF(&result, as_hex, DN_Str8Lit(""), "as_hex=%.*s", DN_Str8PrintFmt(as_hex));
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: BinarySearch
|
||||
// NOTE: BSearch
|
||||
{
|
||||
for (DN_TestScopeF(&result, "[BinarySearch] Search array of 1 item")) {
|
||||
DN_U32 array[] = {1};
|
||||
DN_BinarySearchResult search = {};
|
||||
for (DN_TestScopeF(&result, "[BSearch] Search array of 1 item")) {
|
||||
DN_U32 array[] = {1};
|
||||
DN_BSearchResult search = {};
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BinarySearch] Search array of 3 items")) {
|
||||
for (DN_TestScopeF(&result, "[BSearch] Search array of 3 items")) {
|
||||
DN_U32 array[] = {1, 2, 3};
|
||||
DN_BinarySearchResult search = {};
|
||||
DN_BSearchResult search = {};
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 4U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 3);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 4U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 3);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 1);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 3);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 4U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 3);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[BinarySearch] Search array with duplicate items")) {
|
||||
for (DN_TestScopeF(&result, "[BSearch] Search array with duplicate items")) {
|
||||
DN_U32 array[] = {1, 1, 2, 2, 3};
|
||||
DN_BinarySearchResult search = {};
|
||||
DN_BSearchResult search = {};
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 4);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U, DN_BinarySearchType_Match);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 4U, DN_BSearchType_Match);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 5);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 4);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U, DN_BinarySearchType_LowerBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 4U, DN_BSearchType_LowerBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 5);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 0U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 0);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 1U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 2);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 2U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 4);
|
||||
|
||||
search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U, DN_BinarySearchType_UpperBound);
|
||||
search = DN_BSearchU32(array, DN_ArrayCountU(array), 3U, DN_BSearchType_UpperBound);
|
||||
DN_TestVerifyExpr(&result, !search.found);
|
||||
DN_TestVerifyUSizeEq(&result, search.index, 5);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user