Do massive overhaul and simplification of DN
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#define DN_ASYNC_CPP
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
#define DN_H_WITH_OS 1
|
||||
#include "../dn.h"
|
||||
#include "dn_async.h"
|
||||
#endif
|
||||
|
||||
@@ -18,8 +18,8 @@ static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
DN_ASYNCTask task = {};
|
||||
for (DN_OS_MutexScope(&async->ring_mutex)) {
|
||||
if (DN_Ring_HasData(ring, sizeof(task)))
|
||||
DN_Ring_Read(ring, &task, sizeof(task));
|
||||
if (DN_RingHasData(ring, sizeof(task)))
|
||||
DN_RingRead(ring, &task, sizeof(task));
|
||||
}
|
||||
|
||||
if (task.work.func) {
|
||||
@@ -72,8 +72,8 @@ static bool DN_ASYNC_QueueTask_(DN_ASYNCCore *async, DN_ASYNCTask const *task, D
|
||||
bool result = false;
|
||||
for (DN_OS_MutexScope(&async->ring_mutex)) {
|
||||
for (;;) {
|
||||
if (DN_Ring_HasSpace(&async->ring, sizeof(*task))) {
|
||||
DN_Ring_WriteStruct(&async->ring, task);
|
||||
if (DN_RingHasSpace(&async->ring, sizeof(*task))) {
|
||||
DN_RingWriteStruct(&async->ring, task);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define DN_ASYNC_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
#define DN_H_WITH_OS 1
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
enum DN_ASYNCPriority
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
#define DN_BIN_PACK_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#endif
|
||||
|
||||
#if !defined(DN_BASE_INC_H)
|
||||
#error dn_base_inc.h must be included before this
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
enum DN_BinPackMode
|
||||
|
||||
+53
-35
@@ -63,7 +63,7 @@ DN_CGenTableHeaderType const DN_CGEN_TABLE_CODE_GEN_BUILTIN_TYPES_HEADER_LIST[]
|
||||
DN_CGenTableHeaderType_Name,
|
||||
};
|
||||
|
||||
static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err)
|
||||
static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_ErrSink *err)
|
||||
{
|
||||
bool result = false;
|
||||
if (!cgen || !cgen->file_list || !cgen->arena)
|
||||
@@ -283,7 +283,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CGen DN_CGen_FromFilesArgV(int argc, char const **argv, DN_OSErrSink *err)
|
||||
DN_API DN_CGen DN_CGen_FromFilesArgV(int argc, char const **argv, DN_ErrSink *err)
|
||||
{
|
||||
DN_CGen result = {};
|
||||
result.arena = MD_ArenaAlloc();
|
||||
@@ -341,7 +341,7 @@ DN_API DN_CGenMapNodeToEnum DN_CGen_MapNodeToEnumOrExit(MD_Node const *node, DN_
|
||||
|
||||
if (result.enum_val == 0) {
|
||||
MD_CodeLoc loc = MD_CodeLocFromNode(DN_Cast(MD_Node *) node);
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 user_msg = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
@@ -357,6 +357,7 @@ DN_API DN_CGenMapNodeToEnum DN_CGen_MapNodeToEnumOrExit(MD_Node const *node, DN_
|
||||
}
|
||||
|
||||
DN_Str8 error_msg = DN_Str8BuilderBuild(&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);
|
||||
}
|
||||
@@ -371,13 +372,14 @@ DN_API DN_USize DN_CGen_NodeChildrenCount(MD_Node const *node)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_OSErrSink *err, char const *fmt, ...)
|
||||
DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_ErrSink *err, char const *fmt, ...)
|
||||
{
|
||||
if (!err)
|
||||
return;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8Builder builder = {};
|
||||
builder.arena = tmem.arena;
|
||||
|
||||
MD_String8 kind_string = MD_StringFromMessageKind(kind);
|
||||
MD_CodeLoc loc = MD_CodeLocFromNode(node);
|
||||
@@ -388,14 +390,15 @@ DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_OSErrSink *err,
|
||||
DN_Str8BuilderAppendFV(&builder, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
DN_Str8 msg = DN_Str8BuilderBuild(&builder, tmem.arena);
|
||||
DN_Str8 msg = DN_Str8BuilderBuild(&builder, err->arena);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_OS_ErrSinkAppendF(err, DN_Cast(uint32_t) - 1, "%.*s", DN_Str8PrintFmt(msg));
|
||||
}
|
||||
|
||||
DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *headers, DN_USize header_count, DN_OSErrSink *err)
|
||||
DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *headers, DN_USize header_count, DN_ErrSink *err)
|
||||
{
|
||||
bool result = true;
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8Builder builder = {};
|
||||
builder.arena = tmem.arena;
|
||||
|
||||
@@ -419,6 +422,7 @@ DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *he
|
||||
DN_Str8PrintFmt(missing_headers));
|
||||
}
|
||||
|
||||
DN_TCScratchEnd(&tmem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -515,13 +519,14 @@ static void DN_CGen_EmitRowWhitespace_(DN_CGenTableRow const *row, DN_CppFile *c
|
||||
if (tag->comment.size <= 0)
|
||||
break;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 prefix = DN_Str8FromFmtArena(tmem.arena, "// NOTE: %.*s ", MD_S8VArg(tag->comment));
|
||||
int line_padding = DN_Max(100 - (DN_Cast(int) prefix.size + (DN_CppSpacePerIndent(cpp) * cpp->indent)), 0);
|
||||
DN_CppPrint(cpp, "%.*s", DN_Str8PrintFmt(prefix));
|
||||
for (int index = 0; index < line_padding; index++)
|
||||
DN_CppAppend(cpp, "/");
|
||||
DN_CppAppend(cpp, "\n");
|
||||
DN_TCScratchEnd(&tmem);
|
||||
} break;
|
||||
|
||||
case DN_CGenTableRowTagType_EmptyLine: {
|
||||
@@ -533,17 +538,18 @@ static void DN_CGen_EmitRowWhitespace_(DN_CGenTableRow const *row, DN_CppFile *c
|
||||
|
||||
DN_Str8 DN_CGen_ConvertTemplatesToEmittableLiterals_(DN_Arena *arena, DN_Str8 type)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(&arena, 1);
|
||||
DN_Str8 result = DN_Str8TrimWhitespaceAround(type);
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("<"), /*replace*/ DN_Str8Lit("_"), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive);
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit(">"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive);
|
||||
result = DN_Str8TrimWhitespaceAround(result);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_Str8 DN_CGen_StripQualifiersOnCppType_(DN_Arena *arena, DN_Str8 type)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(&arena, 1);
|
||||
DN_Str8 result = DN_Str8TrimWhitespaceAround(type);
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("*"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive);
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("constexpr"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive);
|
||||
@@ -551,6 +557,7 @@ DN_Str8 DN_CGen_StripQualifiersOnCppType_(DN_Arena *arena, DN_Str8 type)
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("static"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive);
|
||||
result = DN_Str8Replace(result, /*find*/ DN_Str8Lit(" "), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive);
|
||||
result = DN_Str8TrimWhitespaceAround(result);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -563,9 +570,10 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
DN_CppLine(cpp, "%.*sType_Nil,", DN_Str8PrintFmt(emit_prefix));
|
||||
for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next)
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 enum_name = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, it.cgen_table_column[DN_CGenTableHeaderType_Name].string);
|
||||
DN_CppLine(cpp, "%.*sType_%.*s,", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(enum_name));
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
DN_CppLine(cpp, "%.*sType_Count,", DN_Str8PrintFmt(emit_prefix));
|
||||
}
|
||||
@@ -582,9 +590,9 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
case DN_CGenTableType_CodeGenStruct: {
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
// TODO(doyle): Verify the codegen table has the headers from the table it references
|
||||
int longest_type_name = 0;
|
||||
int longest_type_name = 0;
|
||||
for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_CGenTableRow const *row = it.table->rows + row_index;
|
||||
DN_CGenLookupColumnAtHeader cpp_type = DN_CGen_LookupColumnAtHeader(it.table, it.cgen_table_column[DN_CGenTableHeaderType_CppType].string, row);
|
||||
|
||||
@@ -594,6 +602,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
length += emit_prefix.size;
|
||||
|
||||
longest_type_name = DN_Max(longest_type_name, DN_Cast(int) length);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
|
||||
DN_CppStructBlock(cpp, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string))
|
||||
@@ -606,8 +615,8 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
if (cpp_name.column.string.size <= 0 || cpp_type.column.string.size <= 0)
|
||||
continue;
|
||||
|
||||
// NOTE: Generate cpp array size ///////////////////////////////////
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
// NOTE: Generate cpp array size
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 array_size = {};
|
||||
if (cpp_array_size.column.string.size)
|
||||
array_size = DN_Str8FromFmtArena(tmem.arena, "[%.*s]", DN_Str8PrintFmt(cpp_array_size.column.string));
|
||||
@@ -620,6 +629,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
if (DN_CGen_WillCodeGenTypeName(cgen, find_name))
|
||||
emit_cpp_type = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(cpp_type.column.string));
|
||||
}
|
||||
DN_TCScratchEnd(&tmem);
|
||||
|
||||
int name_to_type_padding = 1 + longest_type_name - DN_Cast(int) emit_cpp_type.size;
|
||||
|
||||
@@ -803,7 +813,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
// for types that are declared in the same mdesk file. We will also
|
||||
// calculate the longest type name that we will generate for whitespace
|
||||
// padding purposes.
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_USize longest_cpp_type_name = 0;
|
||||
auto cpp_type_list = DN_SArray_Init<DN_Str8>(tmem.arena, it.table->row_count, DN_ZMem_Yes);
|
||||
|
||||
@@ -814,7 +824,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
// NOTE: CHeck the length of the string after turning it into emittable code
|
||||
DN_Str8 cpp_type_name = DN_CGen_StripQualifiersOnCppType_(tmem.arena, cpp_type.column.string);
|
||||
if (DN_CGen_WillCodeGenTypeName(cgen, cpp_type_name))
|
||||
cpp_type_name = DN_Str8FromTLSF("%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(cpp_type_name));
|
||||
cpp_type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(cpp_type_name));
|
||||
|
||||
DN_Str8 cpp_type_name_no_templates = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, cpp_type_name);
|
||||
longest_cpp_type_name = DN_Max(longest_cpp_type_name, cpp_type_name_no_templates.size);
|
||||
@@ -849,7 +859,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
index_the_field_references = sub_row_index;
|
||||
}
|
||||
cpp_array_size_field_str8 =
|
||||
DN_Str8FromTLSF("&g_%.*s%.*s_type_fields[%zu]",
|
||||
DN_Str8FromFmtArena(tmem.arena, "&g_%.*s%.*s_type_fields[%zu]",
|
||||
DN_Str8PrintFmt(emit_prefix),
|
||||
DN_Str8PrintFmt(struct_name.string),
|
||||
index_the_field_references);
|
||||
@@ -862,7 +872,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
DN_USize cpp_name_padding = 1 + it.table->headers[cpp_name.index].longest_string - cpp_name.column.string.size;
|
||||
DN_USize cpp_type_padding = 1 + longest_cpp_type_name - cpp_type_name.size;
|
||||
|
||||
DN_Str8 cpp_type_enum = DN_Str8FromTLSF("%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(orig_cpp_type_no_templates));
|
||||
DN_Str8 cpp_type_enum = DN_Str8FromFmtArena(tmem.arena, "%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(orig_cpp_type_no_templates));
|
||||
DN_USize cpp_type_enum_padding = cpp_type_padding + (orig_cpp_type.size - cpp_type_name.size);
|
||||
|
||||
DN_Str8 cpp_label_str8 = cpp_name.column.string;
|
||||
@@ -960,10 +970,10 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
if (cpp_name.column.string.size <= 0)
|
||||
continue;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_USize cpp_name_padding = 1 + it.table->headers[cpp_name.index].longest_string - cpp_name.column.string.size;
|
||||
DN_Str8 cpp_value_str8 = cpp_value.column.string.size ? cpp_value.column.string : DN_Str8FromTLSF("%zu", row_index);
|
||||
DN_Str8 cpp_type_enum = DN_Str8FromTLSF("%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_or_enum_name));
|
||||
DN_Str8 cpp_value_str8 = cpp_value.column.string.size ? cpp_value.column.string : DN_Str8FromFmtArena(tmem.arena, "%zu", row_index);
|
||||
DN_Str8 cpp_type_enum = DN_Str8FromFmtArena(tmem.arena, "%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_or_enum_name));
|
||||
|
||||
DN_Str8 cpp_label_str8 = cpp_name.column.string;
|
||||
DN_USize cpp_label_str8_padding = cpp_name_padding;
|
||||
@@ -972,7 +982,8 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
cpp_label_str8_padding = 1 + it.table->headers[cpp_label.index].longest_string - cpp_label.column.string.size;
|
||||
}
|
||||
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
DN_Str8Builder builder = {};
|
||||
builder.arena = tmem.arena;
|
||||
// NOTE: row
|
||||
DN_Str8BuilderAppendF(&builder, "{%2d, ", row_index);
|
||||
|
||||
@@ -1015,23 +1026,26 @@ 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_Str8BuilderBuildFromTLS(&builder);
|
||||
DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line));
|
||||
}
|
||||
}
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int longest_name_across_all_tables = 0;
|
||||
int longest_name_across_all_tables = 0;
|
||||
for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string;
|
||||
if (DN_CGen_WillCodeGenTypeName(cgen, type_name))
|
||||
type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name));
|
||||
|
||||
longest_name_across_all_tables = DN_Max(longest_name_across_all_tables, DN_Cast(int) type_name.size);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,20 +1056,21 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
DN_USize longest_type_name = 0;
|
||||
for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string;
|
||||
if (DN_CGen_WillCodeGenTypeName(cgen, type_name))
|
||||
type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name));
|
||||
longest_type_name = DN_Max(longest_type_name, type_name.size);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
}
|
||||
|
||||
for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string;
|
||||
if (DN_CGen_WillCodeGenTypeName(cgen, type_name))
|
||||
type_name = DN_Str8FromTLSF("%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name));
|
||||
type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name));
|
||||
|
||||
int name_padding = 1 + longest_name_across_all_tables - DN_Cast(int) type_name.size;
|
||||
DN_Str8 type_info_kind = {};
|
||||
@@ -1080,9 +1095,10 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
|
||||
DN_Str8 fields_count = DN_Str8Lit("0");
|
||||
if (!DN_Str8Eq(fields, DN_Str8Lit("NULL")))
|
||||
fields_count = DN_Str8FromTLSF("sizeof(%.*s)/sizeof(%.*s[0])", DN_Str8PrintFmt(fields), DN_Str8PrintFmt(fields));
|
||||
fields_count = DN_Str8FromFmtArena(tmem.arena, "sizeof(%.*s)/sizeof(%.*s[0])", DN_Str8PrintFmt(fields), DN_Str8PrintFmt(fields));
|
||||
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
DN_Str8Builder builder = {};
|
||||
builder.arena = tmem.arena;
|
||||
// NOTE: name
|
||||
DN_Str8BuilderAppendF(&builder, "{DN_Str8Lit(\"%.*s\"),%*s", DN_Str8PrintFmt(type_name), name_padding, "");
|
||||
|
||||
@@ -1101,7 +1117,8 @@ 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_Str8BuilderBuildFromTLS(&builder);
|
||||
DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line));
|
||||
}
|
||||
}
|
||||
@@ -1115,7 +1132,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
{
|
||||
DN_CppLine(cpp, "case %.*sType_Nil: break;", DN_Str8PrintFmt(emit_prefix));
|
||||
DN_CppLine(cpp, "case %.*sType_Count: break;", DN_Str8PrintFmt(emit_prefix));
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) {
|
||||
for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) {
|
||||
DN_Str8 enum_name = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, it.cgen_table_column[DN_CGenTableHeaderType_Name].string);
|
||||
@@ -1129,6 +1146,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil
|
||||
DN_CppLine(cpp, "case %.*s: result = g_%.*stypes + %.*s; break;", DN_Str8PrintFmt(full_enum_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(full_enum_name));
|
||||
}
|
||||
}
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
DN_CppLine(cpp, "return result;");
|
||||
}
|
||||
|
||||
+5
-26
@@ -2,8 +2,8 @@
|
||||
#define DN_CGEN_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
#define DN_H_WITH_OS 1
|
||||
#include "../dn.h"
|
||||
#include "../Standalone/dn_cpp_file.h"
|
||||
#endif
|
||||
|
||||
@@ -38,27 +38,6 @@
|
||||
#error Metadesk 'md.h' must be included before 'dn_cgen.h'
|
||||
#endif
|
||||
|
||||
#if !defined(DN_BASE_INC_H)
|
||||
#error dn_base_inc.h must be included before this
|
||||
#endif
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$$$$$\ $$$$$$\ $$$$$$$$\ $$\ $$\
|
||||
// $$ __$$\ $$ __$$\ $$ _____|$$$\ $$ |
|
||||
// $$ / \__|$$ / \__|$$ | $$$$\ $$ |
|
||||
// $$ | $$ |$$$$\ $$$$$\ $$ $$\$$ |
|
||||
// $$ | $$ |\_$$ |$$ __| $$ \$$$$ |
|
||||
// $$ | $$\ $$ | $$ |$$ | $$ |\$$$ |
|
||||
// \$$$$$$ |\$$$$$$ |$$$$$$$$\ $$ | \$$ |
|
||||
// \______/ \______/ \________|\__| \__|
|
||||
//
|
||||
// dn_cgen.h -- C/C++ code generation from table data in Metadesk files
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
enum DN_CGenTableKeyType
|
||||
{
|
||||
DN_CGenTableKeyType_Nil,
|
||||
@@ -194,12 +173,12 @@ enum DN_CGenEmit
|
||||
(str8).size \
|
||||
}
|
||||
|
||||
DN_API DN_CGen DN_CGen_InitFilesArgV(int argc, char const **argv, DN_OSErrSink *err);
|
||||
DN_API DN_CGen DN_CGen_InitFilesArgV(int argc, char const **argv, DN_ErrSink *err);
|
||||
DN_API DN_Str8 DN_CGen_TableHeaderTypeToDeclStr8(DN_CGenTableHeaderType type);
|
||||
DN_API DN_CGenMapNodeToEnum DN_CGen_MapNodeToEnumOrExit(MD_Node const *node, DN_CGenMapNodeToEnum const *valid_keys, DN_USize valid_keys_size, char const *fmt, ...);
|
||||
DN_API DN_USize DN_CGen_NodeChildrenCount(MD_Node const *node);
|
||||
DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_OSErrSink *err, char const *fmt, ...);
|
||||
DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *headers, DN_USize header_count, DN_OSErrSink *err);
|
||||
DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_ErrSink *err, char const *fmt, ...);
|
||||
DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *headers, DN_USize header_count, DN_ErrSink *err);
|
||||
DN_API DN_CGenLookupColumnAtHeader DN_CGen_LookupColumnAtHeader(DN_CGenTable *table, DN_Str8 header, DN_CGenTableRow const *row);
|
||||
DN_API bool DN_CGen_LookupNextTableInCodeGenTable(DN_CGen *cgen, DN_CGenTable *cgen_table, DN_CGenLookupTableIterator *it);
|
||||
DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFile *cpp, DN_Str8 emit_prefix);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define DN_CSV_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
enum DN_CSVSerialise
|
||||
|
||||
+97
-94
@@ -1,6 +1,5 @@
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
@@ -31,10 +30,11 @@ void DN_Demo()
|
||||
|
||||
// NOTE: DN_HexFromBytes
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
unsigned char bytes[2] = {0xFA, 0xCE};
|
||||
DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), tmem.arena);
|
||||
DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), scratch.arena);
|
||||
DN_Assert(DN_Str8Eq(hex, DN_Str8Lit("face"))); // NOTE: Guaranteed to be null-terminated
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_BytesFromHex
|
||||
@@ -119,8 +119,8 @@ void DN_Demo()
|
||||
// buffer, this buffer must be valid throughout the lifetime of the hash
|
||||
// table!
|
||||
{
|
||||
// NOTE: DN_DSMap_Init
|
||||
// NOTE: DN_DSMap_Deinit
|
||||
// NOTE: DN_DSMapInit
|
||||
// NOTE: DN_DSMapDeinit
|
||||
//
|
||||
// Initialise a hash table where the table size *must* be a
|
||||
// power-of-two, otherwise an assert will be triggered. If
|
||||
@@ -139,15 +139,15 @@ void DN_Demo()
|
||||
// A 'Deinit' of the map will similarly deallocate the passed in arena (as
|
||||
// the map takes ownership of the arena).
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_DSMap<int> map = DN_DSMap_Init<int>(&arena, /*size*/ 1024, DN_DSMapFlags_Nil); // Size must be PoT!
|
||||
DN_Assert(DN_DSMap_IsValid(&map)); // Valid if no initialisation failure (e.g. mem alloc failure)
|
||||
DN_DSMap<int> map = DN_DSMapInit<int>(&arena, /*size*/ 1024, DN_DSMapFlags_Nil); // Size must be PoT!
|
||||
DN_Assert(DN_DSMapIsValid(&map)); // Valid if no initialisation failure (e.g. mem alloc failure)
|
||||
|
||||
// NOTE: DN_DSMap_KeyCStringLit
|
||||
// NOTE: DN_DSMap_KeyU64
|
||||
// NOTE: DN_DSMap_KeyU64NoHash
|
||||
// NOTE: DN_DSMap_KeyBuffer
|
||||
// NOTE: DN_DSMap_KeyStr8
|
||||
// NOTE: DN_DSMap_KeyStr8Copy
|
||||
// NOTE: DN_DSMapKeyCStringLit
|
||||
// NOTE: DN_DSMapKeyU64
|
||||
// NOTE: DN_DSMapKeyU64NoHash
|
||||
// NOTE: DN_DSMapKeyBuffer
|
||||
// NOTE: DN_DSMapKeyStr8
|
||||
// NOTE: DN_DSMapKeyStr8Copy
|
||||
// Create a hash-table key where:
|
||||
//
|
||||
// KeyCStringLit: Uses a Hash(cstring literal)
|
||||
@@ -168,11 +168,11 @@ void DN_Demo()
|
||||
// already sufficiently uniformly distributed already (e.g. using 8
|
||||
// bytes taken from a SHA256 hash as the key) and the first 4 bytes
|
||||
// will be used verbatim.
|
||||
DN_DSMapKey key = DN_DSMap_KeyStr8(&map, DN_Str8Lit("Sample Key"));
|
||||
DN_DSMapKey key = DN_DSMapKeyStr8(&map, DN_Str8Lit("Sample Key"));
|
||||
|
||||
// NOTE: DN_DSMap_Find
|
||||
// NOTE: DN_DSMap_Make
|
||||
// NOTE: DN_DSMap_Set
|
||||
// NOTE: DN_DSMapFind
|
||||
// NOTE: DN_DSMapMake
|
||||
// NOTE: DN_DSMapSet
|
||||
//
|
||||
// Query or commit key-value pair to the table, where:
|
||||
//
|
||||
@@ -190,7 +190,7 @@ void DN_Demo()
|
||||
// the table will be grown to 2x the current the size before insertion
|
||||
// completes.
|
||||
{
|
||||
DN_DSMapResult<int> set_result = DN_DSMap_Set(&map, key, 0xCAFE);
|
||||
DN_DSMapResult<int> set_result = DN_DSMapSet(&map, key, 0xCAFE);
|
||||
DN_Assert(!set_result.found); // First time we are setting the key-value pair, it wasn't previously in the table
|
||||
DN_Assert(map.occupied == 2); // Sentinel + new element == 2
|
||||
}
|
||||
@@ -206,38 +206,38 @@ void DN_Demo()
|
||||
DN_Assert(DN_Str8Eq(DN_Str8FromPtr(it_key.buffer_data, it_key.buffer_size), DN_Str8Lit("Sample Key")));
|
||||
}
|
||||
|
||||
// NOTE: DN_DSMap_Erase
|
||||
// NOTE: DN_DSMapErase
|
||||
//
|
||||
// Remove the key-value pair from the table. If by erasing the key-value
|
||||
// pair from the table puts the table under 25% load, the table will be
|
||||
// shrunk by 1/2 the current size after erasing. The table will not shrink
|
||||
// below the initial size that the table was initialised as.
|
||||
{
|
||||
bool erased = DN_DSMap_Erase(&map, key);
|
||||
bool erased = DN_DSMapErase(&map, key);
|
||||
DN_Assert(erased);
|
||||
DN_Assert(map.occupied == 1); // Sentinel element
|
||||
}
|
||||
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes); // Deallocates the 'arena' for us!
|
||||
DN_DSMapDeinit(&map, DN_ZMem_Yes); // Deallocates the 'arena' for us!
|
||||
}
|
||||
|
||||
// NOTE: DN_DSMap_Hash
|
||||
// NOTE: DN_DSMapHash
|
||||
//
|
||||
// Hash the input key using the custom hash function if it's set on the map,
|
||||
// otherwise uses the default hashing function (32bit Murmur3).
|
||||
|
||||
// NOTE: DN_DSMap_HashToSlotIndex
|
||||
// NOTE: DN_DSMapHashToSlotIndex
|
||||
//
|
||||
// Calculate the index into the map's 'slots' array from the given hash.
|
||||
|
||||
// NOTE: DN_DSMap_Resize
|
||||
// NOTE: DN_DSMapResize
|
||||
//
|
||||
// Resize the table and move all elements to the new map, note that the new
|
||||
// size must be a power of two. This function wil fail on memory allocation
|
||||
// failure, or the requested size is smaller than the current number of
|
||||
// elements in the map to resize.
|
||||
|
||||
// NOTE: DN_OSErrSink
|
||||
// NOTE: DN_ErrSink
|
||||
//
|
||||
// Error sinks are a way of accumulating errors from API calls related or
|
||||
// unrelated into 1 unified error handling pattern. The implemenation of a
|
||||
@@ -273,11 +273,11 @@ void DN_Demo()
|
||||
// (B) Error handling using pipelining and and error proof APIs. APIs that
|
||||
// produce errors take in the error sink as a parameter.
|
||||
if (0) {
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_ErrSink *error = DN_TCErrSinkBegin(DN_ErrSinkMode_Nil);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error);
|
||||
DN_OS_FileClose(&file);
|
||||
if (DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to file")) {
|
||||
if (DN_ErrSinkEndLogErrorF(error, "Failed to write to file")) {
|
||||
// Do error handling!
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ void DN_Demo()
|
||||
// be populated by the first error encountered in that scope.
|
||||
|
||||
if (0) {
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_ErrSink *error = DN_TCErrSinkBegin(DN_ErrSinkMode_Nil);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error);
|
||||
DN_OS_FileClose(&file);
|
||||
@@ -305,12 +305,12 @@ void DN_Demo()
|
||||
{
|
||||
// NOTE: My error sinks are thread-local, so the returned 'error' is
|
||||
// the same as the 'error' value above.
|
||||
DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_TCErrSinkBegin(DN_ErrSinkMode_Nil);
|
||||
DN_OS_FileWriteAll(DN_Str8Lit("/path/to/another/file"), DN_Str8Lit("123"), error);
|
||||
DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to another file");
|
||||
DN_ErrSinkEndLogErrorF(error, "Failed to write to another file");
|
||||
}
|
||||
|
||||
if (DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to file")) {
|
||||
if (DN_ErrSinkEndLogErrorF(error, "Failed to write to file")) {
|
||||
// Do error handling!
|
||||
}
|
||||
}
|
||||
@@ -357,16 +357,6 @@ void DN_Demo()
|
||||
//
|
||||
// And the non-named version emit just the 'value' portion
|
||||
|
||||
// NOTE: DN_List_Iterate
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_List<int> list = DN_List_Init<int>(/*chunk_size*/ 128);
|
||||
for (DN_ListIterator<int> it = {}; DN_List_Iterate(&list, &it, 0);) {
|
||||
int *item = it.data;
|
||||
(void)item;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_LOGProc
|
||||
//
|
||||
// Function prototype of the logging interface exposed by this library. Logs
|
||||
@@ -438,10 +428,11 @@ void DN_Demo()
|
||||
// If 'tmp_path' is written to successfuly, the file will be copied over into
|
||||
// 'path'.
|
||||
if (0) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(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_OS_ErrSinkEndAndLogErrorF(error, "");
|
||||
DN_ErrSinkEndLogErrorF(error, "");
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_OS_EstimateTSCPerSecond
|
||||
@@ -630,7 +621,7 @@ void DN_Demo()
|
||||
// Int -> U32: 0 or UINT32_MAX
|
||||
// Int -> U64: 0 or UINT64_MAX
|
||||
|
||||
// NOTE: DN_StackTrace
|
||||
// NOTE: DN_OS_StackTrace
|
||||
// Emit stack traces at the calling site that these functions are invoked
|
||||
// from.
|
||||
//
|
||||
@@ -647,15 +638,15 @@ void DN_Demo()
|
||||
// the debug APIs are aware of how to resolve the new addresses imported
|
||||
// into the address space.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
|
||||
// NOTE: DN_StackTraceWalk
|
||||
// NOTE: DN_OS_StackTraceWalk
|
||||
//
|
||||
// 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(tmem.arena, /*depth limit*/ 128);
|
||||
DN_StackTraceWalkResult walk = DN_StackTraceWalk(scratch.arena, /*depth limit*/ 128);
|
||||
|
||||
// Loop over the addresses produced in the stack trace
|
||||
for (DN_StackTraceWalkResultIterator it = {}; DN_StackTraceWalkResultIterate(&it, &walk);) {
|
||||
@@ -663,7 +654,7 @@ void DN_Demo()
|
||||
//
|
||||
// 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(tmem.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)
|
||||
@@ -675,13 +666,15 @@ void DN_Demo()
|
||||
// to resolve the new addresses.
|
||||
DN_StackTraceReloadSymbols();
|
||||
|
||||
// NOTE: DN_StackTraceGetFrames
|
||||
// NOTE: DN_OS_StackTraceGetFrames
|
||||
//
|
||||
// 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_Slice<DN_StackTraceFrame> frames = DN_StackTraceGetFrames(tmem.arena, /*depth limit*/ 128);
|
||||
DN_StackTraceFrameSlice frames = DN_StackTraceGetFrames(scratch.arena, /*depth limit*/ 128);
|
||||
(void)frames;
|
||||
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8FromArena
|
||||
@@ -693,10 +686,11 @@ void DN_Demo()
|
||||
// The returned string's 'size' member variable does *not* include this
|
||||
// additional null-terminating byte.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8FromArena(tmem.arena, /*size*/ 1, DN_ZMem_Yes);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8FromArena(scratch.arena, /*size*/ 1, DN_ZMem_Yes);
|
||||
DN_Assert(string.size == 1);
|
||||
DN_Assert(string.data[string.size] == 0); // It is null-terminated!
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8BSplit
|
||||
@@ -773,14 +767,15 @@ void DN_Demo()
|
||||
// always be a newly allocated copy, irrespective of if any replacements
|
||||
// were done or not.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
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*/ tmem.arena,
|
||||
/*arena*/ scratch.arena,
|
||||
/*eq_case*/ DN_Str8EqCase_Sensitive);
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Foo Moo Bar")));
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8Segment
|
||||
@@ -791,18 +786,19 @@ void DN_Demo()
|
||||
// Reverse segment delimits the string counting 'segment_size' from the back
|
||||
// of the string.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8Segment(tmem.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ',');
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(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);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8Split
|
||||
{
|
||||
// Splits the string at each delimiter into substrings occuring prior and
|
||||
// after until the next delimiter.
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
{
|
||||
DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ tmem.arena,
|
||||
DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena,
|
||||
/*string*/ DN_Str8Lit("192.168.8.1"),
|
||||
/*delimiter*/ DN_Str8Lit("."),
|
||||
/*mode*/ DN_Str8SplitIncludeEmptyStrings_No);
|
||||
@@ -816,7 +812,7 @@ 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*/ tmem.arena,
|
||||
DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ scratch.arena,
|
||||
/*string*/ DN_Str8Lit("a--b"),
|
||||
/*delimiter*/ DN_Str8Lit("-"),
|
||||
/*mode*/ DN_Str8SplitIncludeEmptyStrings_Yes);
|
||||
@@ -825,6 +821,8 @@ void DN_Demo()
|
||||
DN_Str8Eq(splits.data[1], DN_Str8Lit("")) &&
|
||||
DN_Str8Eq(splits.data[2], DN_Str8Lit("b")));
|
||||
}
|
||||
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: DN_I64FromStr8, DN_U64FromStr8
|
||||
@@ -931,7 +929,7 @@ void DN_Demo()
|
||||
|
||||
// NOTE: DN_ThreadContext
|
||||
//
|
||||
// Each thread is assigned in their thread-local storage (TLS) tmem and
|
||||
// Each thread is assigned in their thread-local storage (TLS) scratch and
|
||||
// permanent arena allocators. These can be used for allocations with a
|
||||
// lifetime scoped to the lexical scope or for storing data permanently
|
||||
// using the arena paradigm.
|
||||
@@ -939,40 +937,43 @@ void DN_Demo()
|
||||
// TLS in this implementation is implemented using the `thread_local` C/C++
|
||||
// keyword.
|
||||
//
|
||||
// 99% of the time you will want DN_OS_TLSTMem(...) which returns you a
|
||||
// 99% of the time you will want DN_OS_TLSTMem...) which returns you a
|
||||
// temporary arena for function lifetime allocations. On scope exit, the
|
||||
// arena is cleared out.
|
||||
//
|
||||
// This library's paradigm revolves heavily around arenas including tmem
|
||||
// This library's paradigm revolves heavily around arenas including scratch
|
||||
// arenas into child functions for temporary calculations. If an arena is
|
||||
// passed into a function, this poses a problem sometimes known as
|
||||
// 'arena aliasing'.
|
||||
//
|
||||
// If an arena aliases another arena (e.g. the arena passed in) is the same
|
||||
// as the tmem arena requested in the function, we risk the tmem arena
|
||||
// as the scratch arena requested in the function, we risk the scratch arena
|
||||
// on scope exit deallocating memory belonging to the caller.
|
||||
//
|
||||
// To avoid this we the 'DN_OS_TLSTMem(...)' API takes in a list of arenas
|
||||
// to ensure that we provide a tmem arena that *won't* alias with the
|
||||
// To avoid this we the 'DN_OS_TLSTMem...)' API takes in a list of arenas
|
||||
// to ensure that we provide a scratch arena that *won't* alias with the
|
||||
// caller's arena. If arena aliasing occurs, with ASAN on, generally
|
||||
// the library will trap and report use-after-poison once violated.
|
||||
{
|
||||
DN_OSTLSTMem tmem_a = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch_a = DN_TCScratchBegin(nullptr, 0);
|
||||
|
||||
// Now imagine we call a function where we pass tmem_a.arena down
|
||||
// into it .. If we call tmem again, we need to pass in the arena
|
||||
// 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_OSTLSTMem tmem_b = DN_OS_TLSTMem(tmem_a.arena);
|
||||
DN_Assert(tmem_a.arena != tmem_b.arena);
|
||||
DN_TCScratch scratch_b = DN_TCScratchBegin(&scratch_a.arena, 1);
|
||||
DN_Assert(scratch_a.arena != scratch_b.arena);
|
||||
|
||||
DN_TCScratchEnd(&scratch_b);
|
||||
DN_TCScratchEnd(&scratch_a);
|
||||
}
|
||||
|
||||
// @proc DN_Thread_GetTMem
|
||||
// @proc DN_Thread_Getscratch
|
||||
// @desc Retrieve the per-thread temporary arena allocator that is reset on scope
|
||||
// exit.
|
||||
|
||||
// The tmem arena must be deconflicted with any existing arenas in the
|
||||
// The scratch arena must be deconflicted with any existing arenas in the
|
||||
// function to avoid trampling over each other's memory. Consider the situation
|
||||
// where the tmem arena is passed into the function. Inside the function, if
|
||||
// where the scratch arena is passed into the function. Inside the function, if
|
||||
// the same arena is reused then, if both arenas allocate, when the inner arena
|
||||
// is reset, this will undo the passed in arena's allocations in the function.
|
||||
|
||||
@@ -988,9 +989,10 @@ void DN_Demo()
|
||||
|
||||
// NOTE: DN_CVT_AgeFromU64
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(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);
|
||||
}
|
||||
|
||||
// NOTE: DN_VArray
|
||||
@@ -1017,21 +1019,21 @@ void DN_Demo()
|
||||
// In addition to no realloc on expansion or shrinking.
|
||||
//
|
||||
{
|
||||
// NOTE: DN_VArray_Init
|
||||
// NOTE: DN_VArray_InitByteSize
|
||||
// NOTE: DN_OS_VArrayInit
|
||||
// NOTE: DN_OS_VArrayInitByteSize
|
||||
//
|
||||
// Initialise an array with the requested byte size or item capacity
|
||||
// respectively. The returned array may have a higher capacity than the
|
||||
// requested amount since requested memory from the OS may have a certain
|
||||
// alignment requirement (e.g. on Windows reserve/commit are 64k/4k
|
||||
// aligned).
|
||||
DN_VArray<int> array = DN_VArray_Init<int>(1024);
|
||||
DN_VArray<int> array = DN_OS_VArrayInit<int>(1024);
|
||||
DN_Assert(array.size == 0 && array.max >= 1024);
|
||||
|
||||
// NOTE: DN_VArray_Make
|
||||
// NOTE: DN_VArray_Add
|
||||
// NOTE: DN_VArray_MakeArray
|
||||
// NOTE: DN_VArray_AddArray
|
||||
// NOTE: DN_OS_VArrayMake
|
||||
// NOTE: DN_OS_VArrayAdd
|
||||
// NOTE: DN_OS_VArrayMakeArray
|
||||
// NOTE: DN_OS_VArrayAddArray
|
||||
//
|
||||
// Allocate items from the array where:
|
||||
//
|
||||
@@ -1040,11 +1042,11 @@ void DN_Demo()
|
||||
//
|
||||
// If the array has run out of capacity or was never initialised, a null
|
||||
// pointer is returned.
|
||||
int *item = DN_VArray_Add(&array, 0xCAFE);
|
||||
int *item = DN_OS_VArrayAdd(&array, 0xCAFE);
|
||||
DN_Assert(*item == 0xCAFE && array.size == 1);
|
||||
|
||||
// NOTE: DN_VArray_AddCArray
|
||||
DN_VArray_AddCArray(&array, {1, 2, 3});
|
||||
// NOTE: DN_OS_VArrayAddCArray
|
||||
DN_OS_VArrayAddCArray(&array, {1, 2, 3});
|
||||
DN_Assert(array.size == 4);
|
||||
|
||||
// TODO(doyle): There's a bug here with the negative erase!
|
||||
@@ -1054,7 +1056,7 @@ void DN_Demo()
|
||||
if (index != 1)
|
||||
continue;
|
||||
|
||||
// NOTE: DN_VArray_EraseRange
|
||||
// NOTE: DN_OS_VArrayEraseRange
|
||||
//
|
||||
// Erase the next 'count' items at 'begin_index' in the array.
|
||||
// 'count' can be positive or negative which dictates the if we
|
||||
@@ -1072,7 +1074,7 @@ void DN_Demo()
|
||||
|
||||
// TODO(doyle): There's a bug here! This doesn't work.
|
||||
// Erase index 0 with the negative count!
|
||||
DN_ArrayEraseResult erase_result = DN_VArray_EraseRange(&array,
|
||||
DN_ArrayEraseResult erase_result = DN_OS_VArrayEraseRange(&array,
|
||||
/*begin_index*/ index,
|
||||
/*count*/ -1,
|
||||
/*erase*/ DN_ArrayErase_Stable);
|
||||
@@ -1089,7 +1091,7 @@ void DN_Demo()
|
||||
array.data[2] == 3);
|
||||
#endif
|
||||
|
||||
// NOTE: DN_VArray_Reserve
|
||||
// NOTE: DN_OS_VArrayReserve
|
||||
//
|
||||
// Ensure that the requested number of items are backed by physical pages
|
||||
// from the OS. Calling this pre-emptively will minimise syscalls into the
|
||||
@@ -1097,9 +1099,9 @@ void DN_Demo()
|
||||
// in bytes to the allocation granularity of OS allocation APIs hence the
|
||||
// reserved space may be greater than the requested amount (e.g. this is 4k
|
||||
// on Windows).
|
||||
DN_VArray_Reserve(&array, /*count*/ 8);
|
||||
DN_OS_VArrayReserve(&array, /*count*/ 8);
|
||||
|
||||
DN_VArray_Deinit(&array);
|
||||
DN_OS_VArrayDeinit(&array);
|
||||
}
|
||||
|
||||
// NOTE: DN_W32_LastError
|
||||
@@ -1108,13 +1110,14 @@ void DN_Demo()
|
||||
if (0) {
|
||||
// Generate the error string for the last Win32 API called that return
|
||||
// an error value.
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_W32Error get_last_error = DN_W32_LastError(tmem.arena);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(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_W32Error error_msg_for_code = DN_W32_ErrorCodeToMsg(tmem.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);
|
||||
}
|
||||
|
||||
// NOTE: DN_W32_MakeProcessDPIAware
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
#define DN_HASH_CPP
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "dn_hash.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$\ $$\ $$$$$$\ $$$$$$\ $$\ $$\
|
||||
// $$ | $$ |$$ __$$\ $$ __$$\ $$ | $$ |
|
||||
// $$ | $$ |$$ / $$ |$$ / \__|$$ | $$ |
|
||||
// $$$$$$$$ |$$$$$$$$ |\$$$$$$\ $$$$$$$$ |
|
||||
// $$ __$$ |$$ __$$ | \____$$\ $$ __$$ |
|
||||
// $$ | $$ |$$ | $$ |$$\ $$ |$$ | $$ |
|
||||
// $$ | $$ |$$ | $$ |\$$$$$$ |$$ | $$ |
|
||||
// \__| \__|\__| \__| \______/ \__| \__|
|
||||
//
|
||||
// dn_hash.cpp
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: DN_FNV1A
|
||||
// Default values recommended by: http://isthe.com/chongo/tech/comp/fnv/
|
||||
DN_API DN_U32 DN_FNV1A32_Iterate(void const *bytes, DN_USize size, DN_U32 hash)
|
||||
{
|
||||
auto buffer = DN_Cast(DN_U8 const *)bytes;
|
||||
for (DN_USize i = 0; i < size; i++)
|
||||
hash = (buffer[i] ^ hash) * 16777619 /*FNV Prime*/;
|
||||
return hash;
|
||||
}
|
||||
|
||||
DN_API DN_U32 DN_FNV1A32_Hash(void const *bytes, DN_USize size)
|
||||
{
|
||||
DN_U32 result = DN_FNV1A32_Iterate(bytes, size, DN_FNV1A32_SEED);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_FNV1A64_Iterate(void const *bytes, DN_USize size, DN_U64 hash)
|
||||
{
|
||||
auto buffer = DN_Cast(DN_U8 const *)bytes;
|
||||
for (DN_USize i = 0; i < size; i++)
|
||||
hash = (buffer[i] ^ hash) * 1099511628211 /*FNV Prime*/;
|
||||
return hash;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_FNV1A64_Hash(void const *bytes, DN_USize size)
|
||||
{
|
||||
DN_U64 result = DN_FNV1A64_Iterate(bytes, size, DN_FNV1A64_SEED);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_MurmurHash3 ////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL)
|
||||
#define DN_MMH3_ROTL32(x, y) _rotl(x, y)
|
||||
#define DN_MMH3_ROTL64(x, y) _rotl64(x, y)
|
||||
#else
|
||||
#define DN_MMH3_ROTL32(x, y) ((x) << (y)) | ((x) >> (32 - (y)))
|
||||
#define DN_MMH3_ROTL64(x, y) ((x) << (y)) | ((x) >> (64 - (y)))
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Block read - if your platform needs to do endian-swapping or can only
|
||||
// handle aligned reads, do the conversion here
|
||||
|
||||
DN_FORCE_INLINE DN_U32 DN_MurmurHash3_GetBlock32(DN_U32 const *p, int i)
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
DN_FORCE_INLINE DN_U64 DN_MurmurHash3_GetBlock64(DN_U64 const *p, int i)
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finalization mix - force all bits of a hash block to avalanche
|
||||
|
||||
DN_FORCE_INLINE DN_U32 DN_MurmurHash3_FMix32(DN_U32 h)
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
return h;
|
||||
}
|
||||
|
||||
DN_FORCE_INLINE DN_U64 DN_MurmurHash3_FMix64(DN_U64 k)
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= 0xff51afd7ed558ccd;
|
||||
k ^= k >> 33;
|
||||
k *= 0xc4ceb9fe1a85ec53;
|
||||
k ^= k >> 33;
|
||||
return k;
|
||||
}
|
||||
|
||||
DN_API DN_U32 DN_MurmurHash3_x86U32(void const *key, int len, DN_U32 seed)
|
||||
{
|
||||
const DN_U8 *data = (const DN_U8 *)key;
|
||||
const int nblocks = len / 4;
|
||||
|
||||
DN_U32 h1 = seed;
|
||||
|
||||
const DN_U32 c1 = 0xcc9e2d51;
|
||||
const DN_U32 c2 = 0x1b873593;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const DN_U32 *blocks = (const DN_U32 *)(data + nblocks * 4);
|
||||
|
||||
for (int i = -nblocks; i; i++)
|
||||
{
|
||||
DN_U32 k1 = DN_MurmurHash3_GetBlock32(blocks, i);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = DN_MMH3_ROTL32(k1, 15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = DN_MMH3_ROTL32(h1, 13);
|
||||
h1 = h1 * 5 + 0xe6546b64;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const DN_U8 *tail = (const DN_U8 *)(data + nblocks * 4);
|
||||
|
||||
DN_U32 k1 = 0;
|
||||
|
||||
switch (len & 3)
|
||||
{
|
||||
case 3:
|
||||
k1 ^= tail[2] << 16;
|
||||
case 2:
|
||||
k1 ^= tail[1] << 8;
|
||||
case 1:
|
||||
k1 ^= tail[0];
|
||||
k1 *= c1;
|
||||
k1 = DN_MMH3_ROTL32(k1, 15);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h1 = DN_MurmurHash3_FMix32(h1);
|
||||
|
||||
return h1;
|
||||
}
|
||||
|
||||
DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128(void const *key, int len, DN_U32 seed)
|
||||
{
|
||||
const DN_U8 *data = (const DN_U8 *)key;
|
||||
const int nblocks = len / 16;
|
||||
|
||||
DN_U64 h1 = seed;
|
||||
DN_U64 h2 = seed;
|
||||
|
||||
const DN_U64 c1 = 0x87c37b91114253d5;
|
||||
const DN_U64 c2 = 0x4cf5ad432745937f;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const DN_U64 *blocks = (const DN_U64 *)(data);
|
||||
|
||||
for (int i = 0; i < nblocks; i++)
|
||||
{
|
||||
DN_U64 k1 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 0);
|
||||
DN_U64 k2 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 1);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = DN_MMH3_ROTL64(k1, 31);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
|
||||
h1 = DN_MMH3_ROTL64(h1, 27);
|
||||
h1 += h2;
|
||||
h1 = h1 * 5 + 0x52dce729;
|
||||
|
||||
k2 *= c2;
|
||||
k2 = DN_MMH3_ROTL64(k2, 33);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
|
||||
h2 = DN_MMH3_ROTL64(h2, 31);
|
||||
h2 += h1;
|
||||
h2 = h2 * 5 + 0x38495ab5;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const DN_U8 *tail = (const DN_U8 *)(data + nblocks * 16);
|
||||
|
||||
DN_U64 k1 = 0;
|
||||
DN_U64 k2 = 0;
|
||||
|
||||
switch (len & 15)
|
||||
{
|
||||
case 15:
|
||||
k2 ^= ((DN_U64)tail[14]) << 48;
|
||||
case 14:
|
||||
k2 ^= ((DN_U64)tail[13]) << 40;
|
||||
case 13:
|
||||
k2 ^= ((DN_U64)tail[12]) << 32;
|
||||
case 12:
|
||||
k2 ^= ((DN_U64)tail[11]) << 24;
|
||||
case 11:
|
||||
k2 ^= ((DN_U64)tail[10]) << 16;
|
||||
case 10:
|
||||
k2 ^= ((DN_U64)tail[9]) << 8;
|
||||
case 9:
|
||||
k2 ^= ((DN_U64)tail[8]) << 0;
|
||||
k2 *= c2;
|
||||
k2 = DN_MMH3_ROTL64(k2, 33);
|
||||
k2 *= c1;
|
||||
h2 ^= k2;
|
||||
|
||||
case 8:
|
||||
k1 ^= ((DN_U64)tail[7]) << 56;
|
||||
case 7:
|
||||
k1 ^= ((DN_U64)tail[6]) << 48;
|
||||
case 6:
|
||||
k1 ^= ((DN_U64)tail[5]) << 40;
|
||||
case 5:
|
||||
k1 ^= ((DN_U64)tail[4]) << 32;
|
||||
case 4:
|
||||
k1 ^= ((DN_U64)tail[3]) << 24;
|
||||
case 3:
|
||||
k1 ^= ((DN_U64)tail[2]) << 16;
|
||||
case 2:
|
||||
k1 ^= ((DN_U64)tail[1]) << 8;
|
||||
case 1:
|
||||
k1 ^= ((DN_U64)tail[0]) << 0;
|
||||
k1 *= c1;
|
||||
k1 = DN_MMH3_ROTL64(k1, 31);
|
||||
k1 *= c2;
|
||||
h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
h2 ^= len;
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
h1 = DN_MurmurHash3_FMix64(h1);
|
||||
h2 = DN_MurmurHash3_FMix64(h2);
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
DN_MurmurHash3 result = {};
|
||||
result.e[0] = h1;
|
||||
result.e[1] = h2;
|
||||
return result;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#if !defined(DN_HASH_H)
|
||||
#define DN_HASH_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$\ $$\ $$$$$$\ $$$$$$\ $$\ $$\
|
||||
// $$ | $$ |$$ __$$\ $$ __$$\ $$ | $$ |
|
||||
// $$ | $$ |$$ / $$ |$$ / \__|$$ | $$ |
|
||||
// $$$$$$$$ |$$$$$$$$ |\$$$$$$\ $$$$$$$$ |
|
||||
// $$ __$$ |$$ __$$ | \____$$\ $$ __$$ |
|
||||
// $$ | $$ |$$ | $$ |$$\ $$ |$$ | $$ |
|
||||
// $$ | $$ |$$ | $$ |\$$$$$$ |$$ | $$ |
|
||||
// \__| \__|\__| \__| \______/ \__| \__|
|
||||
//
|
||||
// dn_hash.h -- Hashing functions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: DN_FNV1A //////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(DN_FNV1A32_SEED)
|
||||
#define DN_FNV1A32_SEED 2166136261U
|
||||
#endif
|
||||
|
||||
#if !defined(DN_FNV1A64_SEED)
|
||||
#define DN_FNV1A64_SEED 14695981039346656037ULL
|
||||
#endif
|
||||
|
||||
// NOTE: DN_MurmurHash3 ////////////////////////////////////////////////////////////////////////////
|
||||
struct DN_MurmurHash3 { uint64_t e[2]; };
|
||||
|
||||
// NOTE: DN_FNV1A //////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API uint32_t DN_FNV1A32_Hash (void const *bytes, DN_USize size);
|
||||
DN_API uint64_t DN_FNV1A64_Hash (void const *bytes, DN_USize size);
|
||||
DN_API uint32_t DN_FNV1A32_Iterate (void const *bytes, DN_USize size, uint32_t hash);
|
||||
DN_API uint64_t DN_FNV1A64_Iterate (void const *bytes, DN_USize size, uint64_t hash);
|
||||
|
||||
// NOTE: DN_MurmurHash3 ////////////////////////////////////////////////////////////////////////////
|
||||
DN_API uint32_t DN_MurmurHash3_x86U32 (void const *key, int len, uint32_t seed);
|
||||
DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128 (void const *key, int len, uint32_t seed);
|
||||
#define DN_MurmurHash3_x64U128AsU64(key, len, seed) (DN_MurmurHash3_x64U128(key, len, seed).e[0])
|
||||
#define DN_MurmurHash3_x64U128AsU32(key, len, seed) (DN_Cast(uint32_t)DN_MurmurHash3_x64U128(key, len, seed).e[0])
|
||||
|
||||
#endif // !defined(DN_HASH_H)
|
||||
@@ -4,102 +4,6 @@
|
||||
#include "dn_helpers.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$\ $$\ $$$$$$$$\ $$\ $$$$$$$\ $$$$$$$$\ $$$$$$$\ $$$$$$\
|
||||
// $$ | $$ |$$ _____|$$ | $$ __$$\ $$ _____|$$ __$$\ $$ __$$\
|
||||
// $$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ | $$ |$$ / \__|
|
||||
// $$$$$$$$ |$$$$$\ $$ | $$$$$$$ |$$$$$\ $$$$$$$ |\$$$$$$\
|
||||
// $$ __$$ |$$ __| $$ | $$ ____/ $$ __| $$ __$$< \____$$\
|
||||
// $$ | $$ |$$ | $$ | $$ | $$ | $$ | $$ |$$\ $$ |
|
||||
// $$ | $$ |$$$$$$$$\ $$$$$$$$\ $$ | $$$$$$$$\ $$ | $$ |\$$$$$$ |
|
||||
// \__| \__|\________|\________|\__| \________|\__| \__| \______/
|
||||
//
|
||||
// dn_helpers.cpp
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: DN_PCG32 //////////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL
|
||||
#define DN_PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL
|
||||
|
||||
DN_API DN_PCG32 DN_PCG32_Init(uint64_t seed)
|
||||
{
|
||||
DN_PCG32 result = {};
|
||||
DN_PCG32_Next(&result);
|
||||
result.state += seed;
|
||||
DN_PCG32_Next(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API uint32_t DN_PCG32_Next(DN_PCG32 *rng)
|
||||
{
|
||||
uint64_t state = rng->state;
|
||||
rng->state = state * DN_PCG_DEFAULT_MULTIPLIER_64 + DN_PCG_DEFAULT_INCREMENT_64;
|
||||
|
||||
// XSH-RR
|
||||
uint32_t value = (uint32_t)((state ^ (state >> 18)) >> 27);
|
||||
int rot = state >> 59;
|
||||
return rot ? (value >> rot) | (value << (32 - rot)) : value;
|
||||
}
|
||||
|
||||
DN_API uint64_t DN_PCG32_Next64(DN_PCG32 *rng)
|
||||
{
|
||||
uint64_t value = DN_PCG32_Next(rng);
|
||||
value <<= 32;
|
||||
value |= DN_PCG32_Next(rng);
|
||||
return value;
|
||||
}
|
||||
|
||||
DN_API uint32_t DN_PCG32_Range(DN_PCG32 *rng, uint32_t low, uint32_t high)
|
||||
{
|
||||
uint32_t bound = high - low;
|
||||
uint32_t threshold = -(int32_t)bound % bound;
|
||||
|
||||
for (;;) {
|
||||
uint32_t r = DN_PCG32_Next(rng);
|
||||
if (r >= threshold)
|
||||
return low + (r % bound);
|
||||
}
|
||||
}
|
||||
|
||||
DN_API float DN_PCG32_NextF32(DN_PCG32 *rng)
|
||||
{
|
||||
uint32_t x = DN_PCG32_Next(rng);
|
||||
return (float)(int32_t)(x >> 8) * 0x1.0p-24f;
|
||||
}
|
||||
|
||||
DN_API double DN_PCG32_NextF64(DN_PCG32 *rng)
|
||||
{
|
||||
uint64_t x = DN_PCG32_Next64(rng);
|
||||
return (double)(int64_t)(x >> 11) * 0x1.0p-53;
|
||||
}
|
||||
|
||||
DN_API void DN_PCG32_Advance(DN_PCG32 *rng, uint64_t delta)
|
||||
{
|
||||
uint64_t cur_mult = DN_PCG_DEFAULT_MULTIPLIER_64;
|
||||
uint64_t cur_plus = DN_PCG_DEFAULT_INCREMENT_64;
|
||||
|
||||
uint64_t acc_mult = 1;
|
||||
uint64_t acc_plus = 0;
|
||||
|
||||
while (delta != 0) {
|
||||
if (delta & 1) {
|
||||
acc_mult *= cur_mult;
|
||||
acc_plus = acc_plus * cur_mult + cur_plus;
|
||||
}
|
||||
cur_plus = (cur_mult + 1) * cur_plus;
|
||||
cur_mult *= cur_mult;
|
||||
delta >>= 1;
|
||||
}
|
||||
|
||||
rng->state = acc_mult * rng->state + acc_plus;
|
||||
}
|
||||
|
||||
#if !defined(DN_NO_JSON_BUILDER)
|
||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_JSONBuilder DN_JSONBuilder_Init(DN_Arena *arena, int spaces_per_indent)
|
||||
{
|
||||
DN_JSONBuilder result = {};
|
||||
@@ -167,9 +71,10 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
|
||||
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(builder->string_builder.arena);
|
||||
DN_Str8 value = DN_Str8FromFmtVArena(tmem.arena, value_fmt, args);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(&builder->string_builder.arena, 1);
|
||||
DN_Str8 value = DN_Str8FromFmtVArena(scratch.arena, value_fmt, args);
|
||||
DN_JSONBuilder_KeyValue(builder, key, value);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_KeyValueF(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, ...)
|
||||
@@ -246,4 +151,3 @@ DN_API void DN_JSONBuilder_BoolNamed(DN_JSONBuilder *builder, DN_Str8 key, bool
|
||||
DN_Str8 value_string = value ? DN_Str8Lit("true") : DN_Str8Lit("false");
|
||||
DN_JSONBuilder_KeyValueF(builder, key, "%.*s", value_string.size, value_string.data);
|
||||
}
|
||||
#endif // !defined(DN_NO_JSON_BUILDER)
|
||||
|
||||
@@ -2,16 +2,7 @@
|
||||
#define DN_HELPERS_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "dn_math.h"
|
||||
#endif
|
||||
|
||||
#if !defined(DN_BASE_H)
|
||||
#error dn_base_inc.h must be included before this
|
||||
#endif
|
||||
|
||||
#if !defined(DN_MATH_H)
|
||||
#error dn_math.h must be included before this
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -31,11 +22,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// NOTE: DN_PCG32 //////////////////////////////////////////////////////////////////////////////////
|
||||
struct DN_PCG32 { uint64_t state; };
|
||||
|
||||
#if !defined(DN_NO_JSON_BUILDER)
|
||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
||||
enum DN_JSONBuilderItem
|
||||
{
|
||||
DN_JSONBuilderItem_Empty,
|
||||
@@ -100,15 +87,6 @@ struct DN_BinarySearchResult
|
||||
template <typename T>
|
||||
using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context);
|
||||
|
||||
// NOTE: DN_PCG32 //////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_PCG32 DN_PCG32_Init (uint64_t seed);
|
||||
DN_API uint32_t DN_PCG32_Next (DN_PCG32 *rng);
|
||||
DN_API uint64_t DN_PCG32_Next64 (DN_PCG32 *rng);
|
||||
DN_API uint32_t DN_PCG32_Range (DN_PCG32 *rng, uint32_t low, uint32_t high);
|
||||
DN_API DN_F32 DN_PCG32_NextF32 (DN_PCG32 *rng);
|
||||
DN_API DN_F64 DN_PCG32_NextF64 (DN_PCG32 *rng);
|
||||
DN_API void DN_PCG32_Advance (DN_PCG32 *rng, uint64_t delta);
|
||||
|
||||
#if !defined(DN_NO_JSON_BUILDER)
|
||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_JSONBuilder_Object(builder) \
|
||||
|
||||
@@ -407,7 +407,7 @@ void DN_JSON_ItErrorUnknownKeyValue_(DN_JSONIt *it, DN_CallSite call_site)
|
||||
json_string_s const *key = curr->name;
|
||||
if (it->flags & json_parse_flags_allow_location_information) {
|
||||
json_string_ex_s const *info = DN_Cast(json_string_ex_s const *)key;
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning),
|
||||
DN_LogEmitFromType(DN_LogMakeU32LogTypeParam(DN_LogType_Warning),
|
||||
call_site,
|
||||
"Unknown key-value pair in object [loc=%zu:%zu, key=%.*s, value=%.*s]",
|
||||
info->line_no,
|
||||
@@ -417,7 +417,7 @@ void DN_JSON_ItErrorUnknownKeyValue_(DN_JSONIt *it, DN_CallSite call_site)
|
||||
DN_Cast(int) value_type_size,
|
||||
value_type);
|
||||
} else {
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning),
|
||||
DN_LogEmitFromType(DN_LogMakeU32LogTypeParam(DN_LogType_Warning),
|
||||
call_site,
|
||||
"Unknown key-value pair in object [key=%.*s, value=%.*s]",
|
||||
DN_Cast(int) key->string_size,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define DN_JSON_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn.h"
|
||||
#include "../External/json.h"
|
||||
#endif
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#error Sheredom json.h (github.com/sheredom/json.h) must be included before this file
|
||||
#endif
|
||||
|
||||
// NOTE: DN_JSON //////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON
|
||||
|
||||
void *DN_JSON_ArenaAllocFunc (void *user_data, size_t count);
|
||||
char const *DN_JSON_TypeEnumCString(json_type_e type, size_t *size);
|
||||
bool DN_JSON_String8Cmp (json_string_s const *lhs, DN_Str8 rhs);
|
||||
|
||||
// NOTE: DN_JSON_It /////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_It
|
||||
enum DN_JSONItEntryType
|
||||
{
|
||||
DN_JSON_ItEntryTypeObjElement,
|
||||
@@ -42,7 +42,7 @@ struct DN_JSONIt
|
||||
|
||||
DN_JSONIt DN_JSON_LoadFileToIt(DN_Arena *arena, DN_Str8 json);
|
||||
|
||||
// NOTE: DN_JSON_ItPush/Pop /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_ItPush/Pop
|
||||
bool DN_JSON_ItPushObjElement (DN_JSONIt *it, json_object_element_s *element);
|
||||
bool DN_JSON_ItPushObj (DN_JSONIt *it, json_object_s *obj);
|
||||
bool DN_JSON_ItPushArrayElement(DN_JSONIt *it, json_array_element_s *element);
|
||||
@@ -50,7 +50,7 @@ bool DN_JSON_ItPushArray (DN_JSONIt *it, json_value_s *value);
|
||||
bool DN_JSON_ItPushValue (DN_JSONIt *it, json_value_s *value);
|
||||
void DN_JSON_ItPop (DN_JSONIt *it);
|
||||
|
||||
// NOTE: DN_JSON_It tree navigation /////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_It tree navigation
|
||||
json_value_s *DN_JSON_ItPushCurrValue(DN_JSONIt *it);
|
||||
bool DN_JSON_ItNext(DN_JSONIt *it);
|
||||
|
||||
@@ -58,12 +58,12 @@ bool DN_JSON_ItNext(DN_JSONIt *it);
|
||||
for(void *DN_UniqueName(ptr) = DN_JSON_ItPushCurrValue(it); DN_UniqueName(ptr); DN_JSON_ItPop(it), DN_UniqueName(ptr) = nullptr) \
|
||||
while (DN_JSON_ItNext(it))
|
||||
|
||||
// NOTE: DN_JSON_ItCurr /////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_ItCurr
|
||||
DN_JSONItEntry *DN_JSON_ItCurr(DN_JSONIt *it);
|
||||
json_value_s *DN_JSON_ItCurrValue(DN_JSONIt *it);
|
||||
json_object_element_s *DN_JSON_ItCurrObjElement(DN_JSONIt *it);
|
||||
|
||||
// NOTE: DN_JSON_ItValueIs //////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_ItValueIs
|
||||
json_value_s *DN_JSON_ItValueIs(DN_JSONIt *it, json_type_e type);
|
||||
json_object_s *DN_JSON_ItValueIsObj(DN_JSONIt *it);
|
||||
json_array_s *DN_JSON_ItValueIsArray(DN_JSONIt *it);
|
||||
@@ -74,7 +74,7 @@ json_value_s *DN_JSON_ItValueIsNull(DN_JSONIt *it);
|
||||
|
||||
size_t DN_JSON_ItValueArraySize(DN_JSONIt *it);
|
||||
|
||||
// NOTE: DN_JSON_ItKeyValueIs ///////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_ItKeyValueIs
|
||||
DN_Str8 DN_JSON_ItKey(DN_JSONIt *it);
|
||||
bool DN_JSON_ItKeyIs(DN_JSONIt *it, DN_Str8 key);
|
||||
json_object_s *DN_JSON_ItKeyValueIsObj(DN_JSONIt *it, DN_Str8 key);
|
||||
@@ -84,7 +84,7 @@ json_number_s *DN_JSON_ItKeyValueIsNumber(DN_JSONIt *it, DN_Str8 key);
|
||||
json_value_s *DN_JSON_ItKeyValueIsBool(DN_JSONIt *it, DN_Str8 key);
|
||||
json_value_s *DN_JSON_ItKeyValueIsNull(DN_JSONIt *it, DN_Str8 key);
|
||||
|
||||
// NOTE: DN_JSON_ItValueTo //////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSON_ItValueTo
|
||||
DN_Str8 DN_JSON_ItValueToString(DN_JSONIt *it);
|
||||
int64_t DN_JSON_ItValueToI64(DN_JSONIt *it);
|
||||
uint64_t DN_JSON_ItValueToU64(DN_JSONIt *it);
|
||||
|
||||
+10
-10
@@ -1255,18 +1255,18 @@ DN_API DN_M2x3 DN_M2x3_Translate(DN_V2F32 offset)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_V2F32 DN_M2x3_ScaleGet(DN_M2x3 m2x3)
|
||||
{
|
||||
DN_V2F32 result = DN_V2F32_From2N(m2x3.row[0][0], m2x3.row[1][1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_M2x3 DN_M2x3_Scale(DN_V2F32 scale)
|
||||
{
|
||||
DN_M2x3 result = {
|
||||
{
|
||||
scale.x,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
scale.y,
|
||||
0,
|
||||
}
|
||||
};
|
||||
DN_M2x3 result = {{
|
||||
scale.x, 0, 0,
|
||||
0, scale.y, 0,
|
||||
}};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+17
-10
@@ -2,7 +2,7 @@
|
||||
#define DN_MATH_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
@@ -34,25 +34,25 @@ union DN_V2F32
|
||||
struct { DN_F32 w, h; };
|
||||
DN_F32 data[2];
|
||||
};
|
||||
DN_DArrayStructDecl(DN_V2F32);
|
||||
|
||||
union DN_V3F32
|
||||
{
|
||||
struct { DN_F32 x, y, z; };
|
||||
struct { DN_F32 r, g, b; };
|
||||
DN_F32 data[3];
|
||||
DN_V2F32 xy;
|
||||
DN_F32 data[3];
|
||||
};
|
||||
|
||||
|
||||
union DN_V4F32
|
||||
{
|
||||
struct { DN_F32 x, y, z, w; };
|
||||
struct { DN_F32 r, g, b, a; };
|
||||
#if !defined(DN_NO_V3)
|
||||
DN_V3F32 rgb;
|
||||
DN_V3F32 xyz;
|
||||
#endif
|
||||
DN_F32 data[4];
|
||||
DN_F32 data[4];
|
||||
};
|
||||
DN_DArrayStructDecl(DN_V4F32);
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
struct DN_M4
|
||||
@@ -137,10 +137,10 @@ DN_API DN_V2I32 DN_V2I32_Min (DN_V2I32 a, DN
|
||||
DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b);
|
||||
DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a);
|
||||
|
||||
#define DN_V2U16_Zero DN_Literal(DN_V2U16){{(uint16_t)(0), (uint16_t)(0)}}
|
||||
#define DN_V2U16_One DN_Literal(DN_V2U16){{(uint16_t)(1), (uint16_t)(1)}}
|
||||
#define DN_V2U16_From1N(x) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(x)}}
|
||||
#define DN_V2U16_From2N(x, y) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(y)}}
|
||||
#define DN_V2U16_Zero DN_Literal(DN_V2U16){{(DN_U16)(0), (DN_U16)(0)}}
|
||||
#define DN_V2U16_One DN_Literal(DN_V2U16){{(DN_U16)(1), (DN_U16)(1)}}
|
||||
#define DN_V2U16_From1N(x) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(x)}}
|
||||
#define DN_V2U16_From2N(x, y) DN_Literal(DN_V2U16){{(DN_U16)(x), (DN_U16)(y)}}
|
||||
|
||||
DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs);
|
||||
DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs);
|
||||
@@ -165,6 +165,11 @@ DN_API DN_V2U16 & operator/= (DN_V2U16& lhs,
|
||||
DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs);
|
||||
DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs);
|
||||
|
||||
#define DN_V2U32_Zero DN_Literal(DN_V2U32){{(DN_U32)(0), (DN_U32)(0)}}
|
||||
#define DN_V2U32_One DN_Literal(DN_V2U32){{(DN_U32)(1), (DN_U32)(1)}}
|
||||
#define DN_V2U32_From1N(x) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(x)}}
|
||||
#define DN_V2U32_From2N(x, y) DN_Literal(DN_V2U32){{(DN_U32)(x), (DN_U32)(y)}}
|
||||
|
||||
#define DN_V2F32_Zero DN_Literal(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}}
|
||||
#define DN_V2F32_One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}}
|
||||
#define DN_V2F32_From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}}
|
||||
@@ -315,6 +320,7 @@ DN_API bool operator== (DN_M2x3 const
|
||||
DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs);
|
||||
DN_API DN_M2x3 DN_M2x3_Identity ();
|
||||
DN_API DN_M2x3 DN_M2x3_Translate (DN_V2F32 offset);
|
||||
DN_API DN_V2F32 DN_M2x3_ScaleGet (DN_M2x3 m2x3);
|
||||
DN_API DN_M2x3 DN_M2x3_Scale (DN_V2F32 scale);
|
||||
DN_API DN_M2x3 DN_M2x3_Rotate (DN_F32 radians);
|
||||
DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2);
|
||||
@@ -323,6 +329,7 @@ DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN
|
||||
|
||||
#define DN_Rect_From2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)}
|
||||
#define DN_Rect_From4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}}
|
||||
#define DN_Rect_Zero DN_Rect_From4N(0, 0, 0, 0)
|
||||
|
||||
DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs);
|
||||
DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect);
|
||||
|
||||
@@ -91,14 +91,14 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_OS_ThreadSetName(DN_Str8FromPtr(curl->thread.name.data, curl->thread.name.size));
|
||||
|
||||
while (!curl->kill_thread) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
|
||||
// NOTE: Handle events sitting in the ring queue
|
||||
for (bool dequeue_ring = true; dequeue_ring;) {
|
||||
DN_NETCurlRingEvent event = {};
|
||||
for (DN_OS_MutexScope(&curl->ring_mutex)) {
|
||||
if (DN_Ring_HasData(&curl->ring, sizeof(event)))
|
||||
DN_Ring_Read(&curl->ring, &event, sizeof(event));
|
||||
if (DN_RingHasData(&curl->ring, sizeof(event)))
|
||||
DN_RingRead(&curl->ring, &event, sizeof(event));
|
||||
}
|
||||
|
||||
DN_NETRequest *req = DN_NET_RequestFromHandle(event.request);
|
||||
@@ -126,9 +126,9 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
case DN_NETCurlRingEventType_SendWS: {
|
||||
DN_Str8 payload = {};
|
||||
for (DN_OS_MutexScope(&curl->ring_mutex)) {
|
||||
DN_Assert(DN_Ring_HasData(&curl->ring, event.ws_send_size));
|
||||
DN_Assert(DN_RingHasData(&curl->ring, event.ws_send_size));
|
||||
payload = DN_Str8FromArena(tmem.arena, event.ws_send_size, DN_ZMem_No);
|
||||
DN_Ring_Read(&curl->ring, payload.data, payload.size);
|
||||
DN_RingRead(&curl->ring, payload.data, payload.size);
|
||||
}
|
||||
|
||||
DN_U32 curlws_flag = 0;
|
||||
@@ -370,6 +370,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
DN_I32 sleep_time_ms = ws_count > 0 ? 16 : INT32_MAX;
|
||||
curl_multi_poll(curl->thread_curlm, nullptr, 0, sleep_time_ms, nullptr);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -526,7 +527,7 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
||||
event.type = DN_NETCurlRingEventType_DoRequest;
|
||||
event.request = result;
|
||||
for (DN_OS_MutexScope(&curl_core->ring_mutex))
|
||||
DN_Ring_WriteStruct(&curl_core->ring, &event);
|
||||
DN_RingWriteStruct(&curl_core->ring, &event);
|
||||
|
||||
curl_multi_wakeup(curl_core->thread_curlm);
|
||||
}
|
||||
@@ -569,9 +570,9 @@ void DN_NET_CurlDoWSSend(DN_NETRequestHandle handle, DN_Str8 payload, DN_NETWSSe
|
||||
event.ws_send = send;
|
||||
|
||||
for (DN_OS_MutexScope(&curl->ring_mutex)) {
|
||||
DN_Assert(DN_Ring_HasSpace(&curl->ring, payload.size));
|
||||
DN_Ring_WriteStruct(&curl->ring, &event);
|
||||
DN_Ring_Write(&curl->ring, payload.data, payload.size);
|
||||
DN_Assert(DN_RingHasSpace(&curl->ring, payload.size));
|
||||
DN_RingWriteStruct(&curl->ring, &event);
|
||||
DN_RingWrite(&curl->ring, payload.data, payload.size);
|
||||
}
|
||||
curl_multi_wakeup(curl->thread_curlm);
|
||||
}
|
||||
@@ -627,7 +628,7 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
||||
}
|
||||
|
||||
for (DN_OS_MutexScope(&curl->ring_mutex))
|
||||
DN_Ring_WriteStruct(&curl->ring, &event);
|
||||
DN_RingWriteStruct(&curl->ring, &event);
|
||||
curl_multi_wakeup(curl->thread_curlm);
|
||||
|
||||
return result;
|
||||
|
||||
+108
-145
@@ -1,6 +1,6 @@
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
#define DN_H_WITH_OS 1
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
#if !defined(DN_UT_H)
|
||||
@@ -440,7 +440,7 @@ static DN_UTCore DN_Tests_Arena()
|
||||
|
||||
static DN_UTCore DN_Tests_Bin()
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_UTCore test = DN_UT_Init();
|
||||
DN_UT_LogF(&test, "DN_Bin\n");
|
||||
{
|
||||
@@ -502,25 +502,26 @@ static DN_UTCore DN_Tests_Bin()
|
||||
|
||||
uint32_t number = 0xd095f6;
|
||||
for (DN_UT_Test(&test, "Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena);
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), scratch.arena);
|
||||
DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("f695d000")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
number = 0xf6ed00;
|
||||
for (DN_UT_Test(&test, "Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena);
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), scratch.arena);
|
||||
DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("00edf600")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
DN_Str8 hex = DN_Str8Lit("0xf6ed00");
|
||||
for (DN_UT_Test(&test, "Convert %.*s to bytes", DN_Str8PrintFmt(hex))) {
|
||||
DN_Str8 bytes = DN_BytesFromHexStr8Arena(hex, tmem.arena);
|
||||
DN_Str8 bytes = DN_BytesFromHexStr8Arena(hex, scratch.arena);
|
||||
DN_UT_AssertF(&test,
|
||||
DN_Str8Eq(bytes, DN_Str8Lit("\xf6\xed\x00")),
|
||||
"number_hex=%.*s",
|
||||
DN_Str8PrintFmt(DN_HexFromBytesPtrArena(bytes.data, bytes.size, tmem.arena)));
|
||||
DN_Str8PrintFmt(DN_HexFromBytesPtrArena(bytes.data, bytes.size, scratch.arena)));
|
||||
}
|
||||
}
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return test;
|
||||
}
|
||||
|
||||
@@ -838,40 +839,40 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
DN_UT_LogF(&result, "DN_DSMap\n");
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
{
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
uint32_t const MAP_SIZE = 64;
|
||||
DN_DSMap<uint64_t> map = DN_DSMap_Init<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes);
|
||||
DN_DSMapDeinit(&map, DN_ZMem_Yes);
|
||||
};
|
||||
|
||||
for (DN_UT_Test(&result, "Find non-existent value")) {
|
||||
DN_DSMapResult<uint64_t> find = DN_DSMap_FindKeyStr8(&map, DN_Str8Lit("Foo"));
|
||||
DN_DSMapResult<uint64_t> find = DN_DSMapFindKeyStr8(&map, DN_Str8Lit("Foo"));
|
||||
DN_UT_Assert(&result, !find.found);
|
||||
DN_UT_Assert(&result, map.size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.occupied == 1 /*Sentinel*/);
|
||||
}
|
||||
|
||||
DN_DSMapKey key = DN_DSMap_KeyCStr8(&map, "Bar");
|
||||
DN_DSMapKey key = DN_DSMapKeyCStr8(&map, "Bar");
|
||||
for (DN_UT_Test(&result, "Insert value and lookup")) {
|
||||
uint64_t desired_value = 0xF00BAA;
|
||||
uint64_t *slot_value = DN_DSMap_Set(&map, key, desired_value).value;
|
||||
uint64_t *slot_value = DN_DSMapSet(&map, key, desired_value).value;
|
||||
DN_UT_Assert(&result, slot_value);
|
||||
DN_UT_Assert(&result, map.size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.occupied == 2);
|
||||
|
||||
uint64_t *value = DN_DSMap_Find(&map, key).value;
|
||||
uint64_t *value = DN_DSMapFind(&map, key).value;
|
||||
DN_UT_Assert(&result, value);
|
||||
DN_UT_Assert(&result, *value == desired_value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Remove key")) {
|
||||
DN_DSMap_Erase(&map, key);
|
||||
DN_DSMapErase(&map, key);
|
||||
DN_UT_Assert(&result, map.size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.occupied == 1 /*Sentinel*/);
|
||||
@@ -892,13 +893,13 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
case DSMapTestType_MakeSlot: prefix = DN_Str8Lit("Make slot"); break;
|
||||
}
|
||||
|
||||
DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(tmem.arena);
|
||||
DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(scratch.arena);
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
uint32_t const MAP_SIZE = 64;
|
||||
DN_DSMap<uint64_t> map = DN_DSMap_Init<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes);
|
||||
DN_DSMapDeinit(&map, DN_ZMem_Yes);
|
||||
};
|
||||
|
||||
for (DN_UT_Test(&result, "%.*s: Test growing", DN_Str8PrintFmt(prefix))) {
|
||||
@@ -906,27 +907,27 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
uint64_t value = 0;
|
||||
uint64_t grow_threshold = map_start_size * 3 / 4;
|
||||
for (; map.occupied != grow_threshold; value++) {
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value);
|
||||
DN_UT_Assert(&result, !DN_DSMap_Find<uint64_t>(&map, key).found);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value);
|
||||
DN_UT_Assert(&result, !DN_DSMapFind<uint64_t>(&map, key).found);
|
||||
DN_DSMapResult<uint64_t> make_result = {};
|
||||
if (result_type == DSMapTestType_Set)
|
||||
make_result = DN_DSMap_Set(&map, key, value);
|
||||
make_result = DN_DSMapSet(&map, key, value);
|
||||
else
|
||||
make_result = DN_DSMap_Make(&map, key);
|
||||
make_result = DN_DSMapMake(&map, key);
|
||||
DN_UT_Assert(&result, !make_result.found);
|
||||
DN_UT_Assert(&result, DN_DSMap_Find<uint64_t>(&map, key).value);
|
||||
DN_UT_Assert(&result, DN_DSMapFind<uint64_t>(&map, key).value);
|
||||
}
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.size == map_start_size);
|
||||
DN_UT_Assert(&result, map.occupied == 1 /*Sentinel*/ + value);
|
||||
|
||||
{ // NOTE: One more item should cause the table to grow by 2x
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value);
|
||||
DN_DSMapResult<uint64_t> make_result = {};
|
||||
if (result_type == DSMapTestType_Set)
|
||||
make_result = DN_DSMap_Set(&map, key, value);
|
||||
make_result = DN_DSMapSet(&map, key, value);
|
||||
else
|
||||
make_result = DN_DSMap_Make(&map, key);
|
||||
make_result = DN_DSMapMake(&map, key);
|
||||
|
||||
value++;
|
||||
DN_UT_Assert(&result, !make_result.found);
|
||||
@@ -948,16 +949,16 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
// NOTE: Validate each slot value
|
||||
uint64_t value_result = index - 1;
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value_result);
|
||||
DN_UT_Assert(&result, DN_DSMap_KeyEquals(slot->key, key));
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value_result);
|
||||
DN_UT_Assert(&result, DN_DSMapKeyEquals(slot->key, key));
|
||||
if (result_type == DSMapTestType_Set)
|
||||
DN_UT_Assert(&result, slot->value == value_result);
|
||||
else
|
||||
DN_UT_Assert(&result, slot->value == 0); // NOTE: Make slot does not set the key so should be 0
|
||||
DN_UT_Assert(&result, slot->key.hash == DN_DSMap_Hash(&map, slot->key));
|
||||
DN_UT_Assert(&result, slot->key.hash == DN_DSMapHash(&map, slot->key));
|
||||
|
||||
// NOTE: Check the reverse lookup is correct
|
||||
DN_DSMapResult<uint64_t> check = DN_DSMap_Find(&map, slot->key);
|
||||
DN_DSMapResult<uint64_t> check = DN_DSMapFind(&map, slot->key);
|
||||
DN_UT_Assert(&result, slot->value == *check.value);
|
||||
}
|
||||
}
|
||||
@@ -968,17 +969,17 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
uint64_t value = 0;
|
||||
uint64_t shrink_threshold = map.size * 1 / 4;
|
||||
for (; map.occupied != shrink_threshold; value++) {
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value);
|
||||
DN_UT_Assert(&result, DN_DSMap_Find<uint64_t>(&map, key).found);
|
||||
DN_DSMap_Erase(&map, key);
|
||||
DN_UT_Assert(&result, !DN_DSMap_Find<uint64_t>(&map, key).found);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value);
|
||||
DN_UT_Assert(&result, DN_DSMapFind<uint64_t>(&map, key).found);
|
||||
DN_DSMapErase(&map, key);
|
||||
DN_UT_Assert(&result, !DN_DSMapFind<uint64_t>(&map, key).found);
|
||||
}
|
||||
DN_UT_Assert(&result, map.size == start_map_size);
|
||||
DN_UT_Assert(&result, map.occupied == start_map_occupied - value);
|
||||
|
||||
{ // NOTE: One more item should cause the table to shrink by 2x
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value);
|
||||
DN_DSMap_Erase(&map, key);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value);
|
||||
DN_DSMapErase(&map, key);
|
||||
value++;
|
||||
|
||||
DN_UT_Assert(&result, map.size == start_map_size / 2);
|
||||
@@ -995,34 +996,35 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (uint64_t index = 1 /*Sentinel*/; index < map.occupied; index++) {
|
||||
// NOTE: Generate the key
|
||||
uint64_t value_result = value + (index - 1);
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value_result);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value_result);
|
||||
|
||||
// NOTE: Validate each slot value
|
||||
DN_DSMapResult<uint64_t> find_result = DN_DSMap_Find(&map, key);
|
||||
DN_DSMapResult<uint64_t> find_result = DN_DSMapFind(&map, key);
|
||||
DN_UT_Assert(&result, find_result.value);
|
||||
DN_UT_Assert(&result, find_result.slot->key == key);
|
||||
if (result_type == DSMapTestType_Set)
|
||||
DN_UT_Assert(&result, *find_result.value == value_result);
|
||||
else
|
||||
DN_UT_Assert(&result, *find_result.value == 0); // NOTE: Make slot does not set the key so should be 0
|
||||
DN_UT_Assert(&result, find_result.slot->key.hash == DN_DSMap_Hash(&map, find_result.slot->key));
|
||||
DN_UT_Assert(&result, find_result.slot->key.hash == DN_DSMapHash(&map, find_result.slot->key));
|
||||
|
||||
// NOTE: Check the reverse lookup is correct
|
||||
DN_DSMapResult<uint64_t> check = DN_DSMap_Find(&map, find_result.slot->key);
|
||||
DN_DSMapResult<uint64_t> check = DN_DSMapFind(&map, find_result.slot->key);
|
||||
DN_UT_Assert(&result, *find_result.value == *check.value);
|
||||
}
|
||||
|
||||
for (; map.occupied != 1; value++) { // NOTE: Remove all items from the table
|
||||
DN_DSMapKey key = DN_DSMap_KeyU64(&map, value);
|
||||
DN_UT_Assert(&result, DN_DSMap_Find<uint64_t>(&map, key).found);
|
||||
DN_DSMap_Erase(&map, key);
|
||||
DN_UT_Assert(&result, !DN_DSMap_Find<uint64_t>(&map, key).found);
|
||||
DN_DSMapKey key = DN_DSMapKeyU64(&map, value);
|
||||
DN_UT_Assert(&result, DN_DSMapFind<uint64_t>(&map, key).found);
|
||||
DN_DSMapErase(&map, key);
|
||||
DN_UT_Assert(&result, !DN_DSMapFind<uint64_t>(&map, key).found);
|
||||
}
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.size == map.initial_size);
|
||||
DN_UT_Assert(&result, map.occupied == 1 /*Sentinel*/);
|
||||
}
|
||||
}
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
DN_UT_LogF(&result, "DN_IArray\n");
|
||||
@@ -1040,7 +1042,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
array.max = DN_ArrayCountU(array_buffer);
|
||||
|
||||
for (DN_UT_Test(&result, "Make item")) {
|
||||
int *item = DN_IArray_Make(&array, DN_ZMem_Yes);
|
||||
int *item = DN_IArrayMake(&array, DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, item && array.size == 1);
|
||||
}
|
||||
}
|
||||
@@ -1050,7 +1052,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Positive count, middle of array, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
@@ -1061,7 +1063,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Negative count, middle of array, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
@@ -1072,7 +1074,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "count = -1, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||
DN_UT_Assert(&result, erase.it_index == 5);
|
||||
@@ -1083,7 +1085,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Positive count, unstable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
@@ -1094,7 +1096,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Negative count, unstable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
||||
int expected[] = {0, 1, 2, 7, 8, 9, 6};
|
||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
@@ -1105,18 +1107,18 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Edge case - begin_index at start, negative count")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 0, -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_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
DN_UT_Assert(&result, size == 10);
|
||||
DN_UT_Assert(&result, size == 9);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Edge case - begin_index at end, positive count")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||
DN_UT_Assert(&result, erase.it_index == 9);
|
||||
@@ -1127,7 +1129,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Invalid input - count = 0")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
@@ -1137,7 +1139,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
for (DN_UT_Test(&result, "Invalid input - null data")) {
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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, size == 10);
|
||||
@@ -1145,7 +1147,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
for (DN_UT_Test(&result, "Invalid input - null size")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
}
|
||||
@@ -1153,7 +1155,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Invalid input - empty array")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 0;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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, size == 0);
|
||||
@@ -1162,7 +1164,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Out-of-bounds begin_index")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArray2_EraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(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);
|
||||
@@ -1171,77 +1173,31 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
}
|
||||
}
|
||||
|
||||
DN_UT_LogF(&result, "DN_FArray\n");
|
||||
{
|
||||
for (DN_UT_Test(&result, "Initialise from raw array")) {
|
||||
int raw_array[] = {1, 2};
|
||||
auto array = DN_FArray_Init<int, 4>(raw_array, DN_ArrayCountU(raw_array));
|
||||
DN_UT_Assert(&result, array.size == 2);
|
||||
DN_UT_Assert(&result, array.data[0] == 1);
|
||||
DN_UT_Assert(&result, array.data[1] == 2);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Erase stable 1 element from array")) {
|
||||
int raw_array[] = {1, 2, 3};
|
||||
auto array = DN_FArray_Init<int, 4>(raw_array, DN_ArrayCountU(raw_array));
|
||||
DN_FArray_EraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable);
|
||||
DN_UT_Assert(&result, array.size == 2);
|
||||
DN_UT_Assert(&result, array.data[0] == 1);
|
||||
DN_UT_Assert(&result, array.data[1] == 3);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Erase unstable 1 element from array")) {
|
||||
int raw_array[] = {1, 2, 3};
|
||||
auto array = DN_FArray_Init<int, 4>(raw_array, DN_ArrayCountU(raw_array));
|
||||
DN_FArray_EraseRange(&array, 0 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable);
|
||||
DN_UT_Assert(&result, array.size == 2);
|
||||
DN_UT_Assert(&result, array.data[0] == 3);
|
||||
DN_UT_Assert(&result, array.data[1] == 2);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Add 1 element to array")) {
|
||||
int const ITEM = 2;
|
||||
int raw_array[] = {1};
|
||||
auto array = DN_FArray_Init<int, 4>(raw_array, DN_ArrayCountU(raw_array));
|
||||
DN_FArray_Add(&array, ITEM);
|
||||
DN_UT_Assert(&result, array.size == 2);
|
||||
DN_UT_Assert(&result, array.data[0] == 1);
|
||||
DN_UT_Assert(&result, array.data[1] == ITEM);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Clear array")) {
|
||||
int raw_array[] = {1};
|
||||
auto array = DN_FArray_Init<int, 4>(raw_array, DN_ArrayCountU(raw_array));
|
||||
DN_FArray_Clear(&array);
|
||||
DN_UT_Assert(&result, array.size == 0);
|
||||
}
|
||||
}
|
||||
|
||||
DN_UT_LogF(&result, "DN_VArray\n");
|
||||
{
|
||||
{
|
||||
DN_VArray<uint32_t> array = DN_VArray_InitByteSize<uint32_t>(DN_Kilobytes(64));
|
||||
DN_VArray<uint32_t> array = DN_OS_VArrayInitByteSize<uint32_t>(DN_Kilobytes(64));
|
||||
DN_DEFER
|
||||
{
|
||||
DN_VArray_Deinit(&array);
|
||||
DN_OS_VArrayDeinit(&array);
|
||||
};
|
||||
|
||||
for (DN_UT_Test(&result, "Test adding an array of items to the array")) {
|
||||
uint32_t array_literal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
DN_VArray_AddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal));
|
||||
DN_OS_VArrayAddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal));
|
||||
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, 1 item, the '2' value from the array")) {
|
||||
DN_VArray_EraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable);
|
||||
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable);
|
||||
DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable);
|
||||
uint32_t 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);
|
||||
@@ -1251,49 +1207,49 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (DN_UT_Test(&result, "Test un/stable erase, OOB")) {
|
||||
for (DN_ArrayErase erase : erase_enums) {
|
||||
uint32_t array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
|
||||
DN_VArray_EraseRange(&array, DN_ArrayCountU(array_literal) /*begin_index*/, DN_ArrayCountU(array_literal) + 100 /*count*/, erase);
|
||||
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_VArray_EraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable);
|
||||
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable);
|
||||
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable);
|
||||
DN_OS_VArrayEraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable);
|
||||
DN_OS_VArrayEraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable);
|
||||
DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable);
|
||||
uint32_t 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_VArray_EraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable);
|
||||
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable);
|
||||
uint32_t 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);
|
||||
@@ -1301,7 +1257,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
for (DN_UT_Test(&result, "Test adding an array of items after erase")) {
|
||||
uint32_t array_literal[] = {0, 1, 2, 3};
|
||||
DN_VArray_AddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal));
|
||||
DN_OS_VArrayAddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal));
|
||||
|
||||
uint32_t expected_literal[] = {14, 6, 0, 1, 2, 3};
|
||||
DN_UT_Assert(&result, array.size == DN_ArrayCountU(expected_literal));
|
||||
@@ -1331,16 +1287,16 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
DN_VArray<UnalignedObject> array = DN_VArray_InitByteSize<UnalignedObject>(DN_Kilobytes(64));
|
||||
DN_VArray<UnalignedObject> array = DN_OS_VArrayInitByteSize<UnalignedObject>(DN_Kilobytes(64));
|
||||
DN_DEFER
|
||||
{
|
||||
DN_VArray_Deinit(&array);
|
||||
DN_OS_VArrayDeinit(&array);
|
||||
};
|
||||
|
||||
// NOTE: Verify that the items returned from the data array are
|
||||
// contiguous in memory.
|
||||
UnalignedObject *make_item_a = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes);
|
||||
UnalignedObject *make_item_b = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes);
|
||||
UnalignedObject *make_item_a = DN_OS_VArrayMakeArray(&array, 1, DN_ZMem_Yes);
|
||||
UnalignedObject *make_item_b = DN_OS_VArrayMakeArray(&array, 1, DN_ZMem_Yes);
|
||||
DN_Memset(make_item_a->data, 'a', sizeof(make_item_a->data));
|
||||
DN_Memset(make_item_b->data, 'b', sizeof(make_item_b->data));
|
||||
DN_UT_Assert(&result, (uintptr_t)make_item_b == (uintptr_t)(make_item_a + 1));
|
||||
@@ -1642,8 +1598,8 @@ DN_Str8 const DN_UT_HASH_STRING_[] =
|
||||
|
||||
void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 input_hex = DN_HexFromBytesPtrArena(input.data, input.size, tmem.arena);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 input_hex = DN_HexFromBytesPtrArena(input.data, input.size, scratch.arena);
|
||||
|
||||
switch (hash_type) {
|
||||
case Hash_SHA3_224: {
|
||||
@@ -1754,10 +1710,11 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data));
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data));
|
||||
} break;
|
||||
}
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
#endif // defined(DN_UNIT_TESTS_WITH_KECCAK)
|
||||
|
||||
@@ -1845,10 +1802,11 @@ static DN_UTCore DN_Tests_OS()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Query executable directory")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 os_result = DN_OS_EXEDir(tmem.arena);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 os_result = DN_OS_EXEDir(scratch.arena);
|
||||
DN_UT_Assert(&result, os_result.size);
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result));
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "DN_OS_PerfCounterNow")) {
|
||||
@@ -1895,8 +1853,8 @@ static DN_UTCore DN_Tests_OS()
|
||||
DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
|
||||
|
||||
// NOTE: Read step
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 read_file = DN_OS_FileReadAllArena(tmem.arena, SRC_FILE, nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 read_file = DN_OS_FileReadAllArena(scratch.arena, SRC_FILE, nullptr);
|
||||
DN_UT_AssertF(&result, read_file.size, "Failed to load file");
|
||||
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(read_file, DN_Str8Lit("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_Str8PrintFmt(read_file));
|
||||
@@ -1925,6 +1883,7 @@ static DN_UTCore DN_Tests_OS()
|
||||
DN_B32 delete_non_existent_moved_file = DN_OS_PathDelete(MOVE_FILE);
|
||||
DN_UT_Assert(&result, delete_non_existent_moved_file == false);
|
||||
DN_UT_Assert(&result, delete_non_existent_src_file == false);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2147,22 +2106,24 @@ static DN_UTCore DN_Tests_Str8()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Initialise with format string")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8FromFmtArena(tmem.arena, "%s", "AB");
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8FromFmtArena(scratch.arena, "%s", "AB");
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
||||
DN_UT_AssertF(&result, string.data[1] == 'B', "string[1]: %c", string.data[1]);
|
||||
DN_UT_AssertF(&result, string.data[2] == 0, "string[2]: %c", string.data[2]);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Copy string")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8Lit("AB");
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, string);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(scratch.arena, string);
|
||||
DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size);
|
||||
DN_UT_AssertF(&result, copy.data[0] == 'A', "copy[0]: %c", copy.data[0]);
|
||||
DN_UT_AssertF(&result, copy.data[1] == 'B', "copy[1]: %c", copy.data[1]);
|
||||
DN_UT_AssertF(&result, copy.data[2] == 0, "copy[2]: %c", copy.data[2]);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Trim whitespace around string")) {
|
||||
@@ -2171,9 +2132,10 @@ static DN_UTCore DN_Tests_Str8()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Allocate string from arena")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8FromArena(tmem.arena, 2, DN_ZMem_No);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8FromArena(scratch.arena, 2, DN_ZMem_No);
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
|
||||
// NOTE: TrimPrefix/Suffix /////////////////////////////////////////////////////////////////////
|
||||
@@ -2448,28 +2410,28 @@ static DN_UTCore DN_Tests_Win()
|
||||
#if defined(DN_PLATFORM_WIN32)
|
||||
DN_UT_LogF(&result, "OS Win32\n");
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 input8 = DN_Str8Lit("String");
|
||||
DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1};
|
||||
|
||||
for (DN_UT_Test(&result, "Str8 to Str16")) {
|
||||
DN_Str16 str_result = DN_W32_Str8ToStr16(tmem.arena, input8);
|
||||
DN_Str16 str_result = DN_OS_W32Str8ToStr16(scratch.arena, input8);
|
||||
DN_UT_Assert(&result, DN_Str16Eq(str_result, input16));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Str16 to Str8")) {
|
||||
DN_Str8 str_result = DN_W32_Str16ToStr8(tmem.arena, input16);
|
||||
DN_Str8 str_result = DN_OS_W32Str16ToStr8(scratch.arena, input16);
|
||||
DN_UT_Assert(&result, DN_Str8Eq(str_result, input8));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Str16 to Str8: Null terminates string")) {
|
||||
int size_required = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
char *string = DN_ArenaNewArray(tmem.arena, char, size_required + 1, DN_ZMem_No);
|
||||
int size_required = DN_OS_W32Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
char *string = DN_ArenaNewArray(scratch.arena, char, size_required + 1, DN_ZMem_No);
|
||||
|
||||
// Fill the string with error sentinels
|
||||
DN_Memset(string, 'Z', size_required + 1);
|
||||
|
||||
int size_returned = DN_W32_Str16ToStr8Buffer(input16, string, size_required + 1);
|
||||
int size_returned = DN_OS_W32Str16ToStr8Buffer(input16, string, size_required + 1);
|
||||
char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
|
||||
|
||||
DN_UT_AssertF(&result, size_required == size_returned, "string_size: %d, result: %d", size_required, size_returned);
|
||||
@@ -2478,14 +2440,15 @@ static DN_UTCore DN_Tests_Win()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Str16 to Str8: Arena null terminates string")) {
|
||||
DN_Str8 string8 = DN_W32_Str16ToStr8(tmem.arena, input16);
|
||||
int size_returned = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
DN_Str8 string8 = DN_OS_W32Str16ToStr8(scratch.arena, input16);
|
||||
int size_returned = DN_OS_W32Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
|
||||
|
||||
DN_UT_AssertF(&result, DN_Cast(int) string8.size == size_returned, "string_size: %d, result: %d", DN_Cast(int) string8.size, size_returned);
|
||||
DN_UT_AssertF(&result, DN_Cast(int) string8.size == DN_ArrayCountU(EXPECTED) - 1, "string_size: %d, expected: %zu", DN_Cast(int) string8.size, DN_ArrayCountU(EXPECTED) - 1);
|
||||
DN_UT_Assert(&result, DN_Memcmp(EXPECTED, string8.data, sizeof(EXPECTED)) == 0);
|
||||
}
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
#endif // DN_PLATFORM_WIN32
|
||||
return result;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define DN_TYPE_INFO_H
|
||||
|
||||
#if defined(_CLANGD)
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user