Add container insert

This commit is contained in:
doylet 2025-07-16 19:34:28 +10:00
parent 93e54a6e32
commit 6f67864d10
5 changed files with 187 additions and 110 deletions

View File

@ -1,4 +1,4 @@
// Generated by the DN single header generator 2025-07-14 23:14:47 // Generated by the DN single header generator 2025-07-16 19:34:17
#define DN_BASE_INC_CPP #define DN_BASE_INC_CPP
@ -743,6 +743,70 @@ DN_API void DN_ASAN_UnpoisonMemoryRegion(void const volatile *ptr, DN_USize size
// DN: Single header generator commented out this header => #include "../dn_base_inc.h" // DN: Single header generator commented out this header => #include "../dn_base_inc.h"
DN_API void *DN_CArray2_InsertArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize index, void const *items, DN_USize count)
{
void *result = nullptr;
if (!data || !size || !items || count <= 0 || ((*size + count) > max))
return result;
DN_USize clamped_index = DN_Min(index, *size);
if (clamped_index != *size) {
char const *src = DN_CAST(char *)data + (clamped_index * elem_size);
char const *dest = DN_CAST(char *)data + ((clamped_index + count) * elem_size);
char const *end = DN_CAST(char *)data + (size[0] * elem_size);
DN_USize bytes_to_move = end - src;
DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move);
}
result = DN_CAST(char *)data + (clamped_index * elem_size);
DN_Memcpy(result, items, elem_size * count);
*size += count;
return result;
}
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
{
DN_ArrayEraseResult result = {};
if (!data || !size || *size == 0 || count == 0)
return result;
// Compute the range to erase
DN_USize start = 0, end = 0;
if (count < 0) {
DN_USize abs_count = DN_Abs(count);
start = begin_index >= abs_count ? begin_index - abs_count + 1 : 0;
end = begin_index >= abs_count ? begin_index + 1 : 0;
} else {
start = begin_index;
end = begin_index + count;
}
// Clamp indices to valid bounds
start = DN_Min(start, *size);
end = DN_Min(end, *size);
// Erase the range [start, end)
DN_USize erase_count = end > start ? end - start : 0;
if (erase_count) {
char *dest = (char *)data + (elem_size * start);
char *array_end = (char *)data + (elem_size * *size);
char *src = dest + (elem_size * erase_count);
if (erase == DN_ArrayErase_Stable) {
DN_USize move_size = array_end - src;
DN_Memmove(dest, src, move_size);
} else {
char *unstable_src = array_end - (elem_size * erase_count);
DN_USize move_size = array_end - unstable_src;
DN_Memcpy(dest, unstable_src, move_size);
}
*size -= erase_count;
}
result.items_erased = erase_count;
result.it_index = start;
return result;
}
DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem) DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem)
{ {
void *result = nullptr; void *result = nullptr;
@ -794,49 +858,6 @@ DN_API bool DN_CArray2_GrowIfNeededFromPool(void **data, DN_USize size, DN_USize
return result; return result;
} }
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
{
DN_ArrayEraseResult result = {};
if (!data || !size || *size == 0 || count == 0)
return result;
// Compute the range to erase
DN_USize start = 0, end = 0;
if (count < 0) {
DN_USize abs_count = DN_Abs(count);
start = begin_index >= abs_count ? begin_index - abs_count + 1 : 0;
end = begin_index >= abs_count ? begin_index + 1 : 0;
} else {
start = begin_index;
end = begin_index + count;
}
// Clamp indices to valid bounds
start = DN_Min(start, *size);
end = DN_Min(end, *size);
// Erase the range [start, end)
DN_USize erase_count = end > start ? end - start : 0;
if (erase_count) {
char *dest = (char *)data + (elem_size * start);
char *array_end = (char *)data + (elem_size * *size);
char *src = dest + (elem_size * erase_count);
if (erase == DN_ArrayErase_Stable) {
DN_USize move_size = array_end - src;
DN_Memmove(dest, src, move_size);
} else {
char *unstable_src = array_end - (elem_size * erase_count);
DN_USize move_size = array_end - unstable_src;
DN_Memcpy(dest, unstable_src, move_size);
}
*size -= erase_count;
}
result.items_erased = erase_count;
result.it_index = start;
return result;
}
DN_API void *DN_CSLList_Detach(void **link, void **next) DN_API void *DN_CSLList_Detach(void **link, void **next)
{ {
void *result = *link; void *result = *link;
@ -4928,9 +4949,9 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
{ {
#if defined(DN_PLATFORM_EMSCRIPTEN) #if defined(DN_PLATFORM_EMSCRIPTEN)
os->arena = DN_Arena_InitFromOSVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack);
#else
os->arena = DN_Arena_InitFromOSHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack); os->arena = DN_Arena_InitFromOSHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack);
#else
os->arena = DN_Arena_InitFromOSVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack);
#endif #endif
#if defined(DN_PLATFORM_WIN32) #if defined(DN_PLATFORM_WIN32)
@ -4956,9 +4977,7 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
else else
DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status); DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status);
#else #else
DN_POSIXCore *posix = DN_CAST(DN_POSIXCore *) os->platform_context; DN_Posix_Init(DN_CAST(DN_POSIXCore *)os->platform_context);
int mutex_init = pthread_mutex_init(&posix->sync_primitive_free_list_mutex, nullptr);
DN_Assert(mutex_init == 0);
#endif #endif
} }
@ -6568,19 +6587,27 @@ DN_API void DN_OS_SleepMs(DN_UInt milliseconds)
; ;
} }
DN_API uint64_t DN_OS_PerfCounterFrequency() DN_API DN_U64 DN_OS_PerfCounterFrequency()
{ {
// NOTE: On Linux we use clock_gettime(CLOCK_MONOTONIC_RAW) which // NOTE: On Linux we use clock_gettime(CLOCK_MONOTONIC_RAW) (or CLOCK_MONOTONIC) which
// increments at nanosecond granularity. // increments at nanosecond granularity.
uint64_t result = 1'000'000'000; DN_U64 result = 1'000'000'000;
return result; return result;
} }
DN_API uint64_t DN_OS_PerfCounterNow() static DN_POSIXCore *DN_OS_GetPOSIXCore_()
{ {
DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context);
DN_POSIXCore *result = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context;
return result;
}
DN_API DN_U64 DN_OS_PerfCounterNow()
{
DN_POSIXCore *posix = DN_OS_GetPOSIXCore_();
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts); clock_gettime(posix->clock_monotonic_raw ? CLOCK_MONOTONIC_RAW : CLOCK_MONOTONIC, &ts);
uint64_t result = DN_CAST(uint64_t) ts.tv_sec * 1'000'000'000 + DN_CAST(uint64_t) ts.tv_nsec; DN_U64 result = DN_CAST(DN_U64) ts.tv_sec * 1'000'000'000 + DN_CAST(DN_U64) ts.tv_nsec;
return result; return result;
} }
@ -7284,13 +7311,6 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
return result; return result;
} }
static DN_POSIXCore *DN_OS_GetPOSIXCore_()
{
DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context);
DN_POSIXCore *result = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context;
return result;
}
static DN_POSIXSyncPrimitive *DN_OS_U64ToPOSIXSyncPrimitive_(DN_U64 u64) static DN_POSIXSyncPrimitive *DN_OS_U64ToPOSIXSyncPrimitive_(DN_U64 u64)
{ {
DN_POSIXSyncPrimitive *result = nullptr; DN_POSIXSyncPrimitive *result = nullptr;
@ -7577,6 +7597,19 @@ DN_API DN_U32 DN_OS_ThreadID()
return DN_CAST(DN_U32) result; return DN_CAST(DN_U32) result;
} }
DN_API void DN_Posix_Init(DN_POSIXCore *posix)
{
int mutex_init = pthread_mutex_init(&posix->sync_primitive_free_list_mutex, nullptr);
DN_Assert(mutex_init == 0);
struct timespec ts;
posix->clock_monotonic_raw = clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != -1;
if (!posix->clock_monotonic_raw) {
int get_result = clock_gettime(CLOCK_MONOTONIC, &ts);
DN_AssertF(get_result != -1, "CLOCK_MONOTONIC_RAW and CLOCK_MONOTONIC are not supported by this platform");
}
}
DN_API void DN_Posix_ThreadSetName(DN_Str8 name) DN_API void DN_Posix_ThreadSetName(DN_Str8 name)
{ {
#if defined(DN_PLATFORM_EMSCRIPTEN) #if defined(DN_PLATFORM_EMSCRIPTEN)
@ -9680,10 +9713,14 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init)
if (on_init & DN_CoreOnInit_LogLibFeatures) { if (on_init & DN_CoreOnInit_LogLibFeatures) {
DN_Str8Builder_AppendRef(&builder, DN_STR8("DN initialised:\n")); DN_Str8Builder_AppendRef(&builder, DN_STR8("DN initialised:\n"));
DN_F64 page_size_kib = g_dn_os_core_->page_size / 1024.0; DN_F32 page_size_kib = g_dn_os_core_->page_size / 1024.0f;
DN_F64 alloc_granularity_kib = g_dn_os_core_->alloc_granularity / 1024.0; DN_F32 alloc_granularity_kib = g_dn_os_core_->alloc_granularity / 1024.0f;
DN_Str8Builder_AppendF( DN_Str8Builder_AppendF(&builder,
&builder, " OS Page Size/Alloc Granularity: %.1f/%.1fKiB\n", page_size_kib, alloc_granularity_kib); " OS Page Size/Alloc Granularity: %.1f/%.1fKiB\n"
" Logical Processor Count: %u\n",
page_size_kib,
alloc_granularity_kib,
g_dn_os_core_->logical_processor_count);
#if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) #if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
if (DN_ASAN_POISON) { if (DN_ASAN_POISON) {
@ -9700,6 +9737,11 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init)
#if !defined(DN_NO_PROFILER) #if !defined(DN_NO_PROFILER)
DN_Str8Builder_AppendRef(&builder, DN_STR8(" TSC profiler available\n")); DN_Str8Builder_AppendRef(&builder, DN_STR8(" TSC profiler available\n"));
#endif #endif
#if defined(DN_PLATFORM_EMSCRIPTEN) || defined(DN_PLATFORM_POSIX)
DN_POSIXCore *posix = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context;
DN_Str8Builder_AppendF(&builder, " Clock GetTime: %S\n", posix->clock_monotonic_raw ? DN_STR8("CLOCK_MONOTONIC_RAW") : DN_STR8("CLOCK_MONOTONIC"));
#endif
// TODO(doyle): Add stacktrace feature log // TODO(doyle): Add stacktrace feature log
} }

View File

@ -1,4 +1,4 @@
// Generated by the DN single header generator 2025-07-14 23:14:47 // Generated by the DN single header generator 2025-07-16 19:34:17
#if !defined(DN_BASE_INC_H) #if !defined(DN_BASE_INC_H)
#define DN_BASE_INC_H #define DN_BASE_INC_H
@ -3970,6 +3970,8 @@ template <typename T> struct DN_List
#define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend) #define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend)
#define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase) #define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase)
#define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase) #define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase)
#define DN_LArray_InsertArray(c_array, size, max, index, items, count) (decltype(&(c_array)[0])) DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, items, count)
#define DN_LArray_Insert(c_array, size, max, index, item) (decltype(&(c_array)[0])) DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, &item, 1)
#define DN_IArray_Front(array) (array)->data #define DN_IArray_Front(array) (array)->data
#define DN_IArray_GrowIfNeededFromPool(array, pool) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool) #define DN_IArray_GrowIfNeededFromPool(array, pool) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool)
@ -3985,6 +3987,8 @@ template <typename T> struct DN_List
#define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend) #define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend)
#define DN_IArray_EraseRange(array, size, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase) #define DN_IArray_EraseRange(array, size, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase)
#define DN_IArray_Erase(array, size, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase) #define DN_IArray_Erase(array, size, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase)
#define DN_IArray_InsertArray(array, index, items, count) (decltype(&((array)->data)[0])) DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, items, count)
#define DN_IArray_Insert(array, index, item, count) (decltype(&((array)->data)[0])) DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, &item, 1)
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem); DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem);
@ -4195,12 +4199,14 @@ DN_API DN_CVTU64HexStr8 DN_CVT_U64ToHexStr8 (DN_U64 n
DN_API bool DN_CVT_BytesToHexPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size); DN_API bool DN_CVT_BytesToHexPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size);
DN_API DN_Str8 DN_CVT_BytesToHex (DN_Arena *arena, void const *src, DN_USize size); DN_API DN_Str8 DN_CVT_BytesToHex (DN_Arena *arena, void const *src, DN_USize size);
#define DN_CVT_BytesToHexFromTLS(...) DN_CVT_BytesToHex(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_BytesToHexFromTLS(...) DN_CVT_BytesToHex(DN_OS_TLSTopArena(), __VA_ARGS__)
#define DN_CVT_BytesToHexFromFrame(...) DN_CVT_BytesToHex(DN_OS_TLSFrameArena(), __VA_ARGS__)
DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size); DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size); DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex); DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex);
#define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex); DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex);
#define DN_CVT_HexToBytesFromFrame(...) DN_CVT_HexToBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
#define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
#endif // defined(DN_BASE_CONVERT_H) #endif // defined(DN_BASE_CONVERT_H)
@ -5693,8 +5699,10 @@ struct DN_POSIXCore
{ {
DN_POSIXSyncPrimitive *sync_primitive_free_list; DN_POSIXSyncPrimitive *sync_primitive_free_list;
pthread_mutex_t sync_primitive_free_list_mutex; pthread_mutex_t sync_primitive_free_list_mutex;
bool clock_monotonic_raw;
}; };
DN_API void DN_Posix_Init(DN_POSIXCore *posix);
DN_API void DN_Posix_ThreadSetName(DN_Str8 name); DN_API void DN_Posix_ThreadSetName(DN_Str8 name);
DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus(); DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus();
#else #else

View File

@ -2,6 +2,70 @@
#include "../dn_base_inc.h" #include "../dn_base_inc.h"
DN_API void *DN_CArray2_InsertArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize index, void const *items, DN_USize count)
{
void *result = nullptr;
if (!data || !size || !items || count <= 0 || ((*size + count) > max))
return result;
DN_USize clamped_index = DN_Min(index, *size);
if (clamped_index != *size) {
char const *src = DN_CAST(char *)data + (clamped_index * elem_size);
char const *dest = DN_CAST(char *)data + ((clamped_index + count) * elem_size);
char const *end = DN_CAST(char *)data + (size[0] * elem_size);
DN_USize bytes_to_move = end - src;
DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move);
}
result = DN_CAST(char *)data + (clamped_index * elem_size);
DN_Memcpy(result, items, elem_size * count);
*size += count;
return result;
}
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
{
DN_ArrayEraseResult result = {};
if (!data || !size || *size == 0 || count == 0)
return result;
// Compute the range to erase
DN_USize start = 0, end = 0;
if (count < 0) {
DN_USize abs_count = DN_Abs(count);
start = begin_index >= abs_count ? begin_index - abs_count + 1 : 0;
end = begin_index >= abs_count ? begin_index + 1 : 0;
} else {
start = begin_index;
end = begin_index + count;
}
// Clamp indices to valid bounds
start = DN_Min(start, *size);
end = DN_Min(end, *size);
// Erase the range [start, end)
DN_USize erase_count = end > start ? end - start : 0;
if (erase_count) {
char *dest = (char *)data + (elem_size * start);
char *array_end = (char *)data + (elem_size * *size);
char *src = dest + (elem_size * erase_count);
if (erase == DN_ArrayErase_Stable) {
DN_USize move_size = array_end - src;
DN_Memmove(dest, src, move_size);
} else {
char *unstable_src = array_end - (elem_size * erase_count);
DN_USize move_size = array_end - unstable_src;
DN_Memcpy(dest, unstable_src, move_size);
}
*size -= erase_count;
}
result.items_erased = erase_count;
result.it_index = start;
return result;
}
DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem) DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem)
{ {
void *result = nullptr; void *result = nullptr;
@ -53,49 +117,6 @@ DN_API bool DN_CArray2_GrowIfNeededFromPool(void **data, DN_USize size, DN_USize
return result; return result;
} }
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
{
DN_ArrayEraseResult result = {};
if (!data || !size || *size == 0 || count == 0)
return result;
// Compute the range to erase
DN_USize start = 0, end = 0;
if (count < 0) {
DN_USize abs_count = DN_Abs(count);
start = begin_index >= abs_count ? begin_index - abs_count + 1 : 0;
end = begin_index >= abs_count ? begin_index + 1 : 0;
} else {
start = begin_index;
end = begin_index + count;
}
// Clamp indices to valid bounds
start = DN_Min(start, *size);
end = DN_Min(end, *size);
// Erase the range [start, end)
DN_USize erase_count = end > start ? end - start : 0;
if (erase_count) {
char *dest = (char *)data + (elem_size * start);
char *array_end = (char *)data + (elem_size * *size);
char *src = dest + (elem_size * erase_count);
if (erase == DN_ArrayErase_Stable) {
DN_USize move_size = array_end - src;
DN_Memmove(dest, src, move_size);
} else {
char *unstable_src = array_end - (elem_size * erase_count);
DN_USize move_size = array_end - unstable_src;
DN_Memcpy(dest, unstable_src, move_size);
}
*size -= erase_count;
}
result.items_erased = erase_count;
result.it_index = start;
return result;
}
DN_API void *DN_CSLList_Detach(void **link, void **next) DN_API void *DN_CSLList_Detach(void **link, void **next)
{ {
void *result = *link; void *result = *link;

View File

@ -217,6 +217,8 @@ template <typename T> struct DN_List
#define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend) #define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend)
#define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase) #define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase)
#define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase) #define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase)
#define DN_LArray_InsertArray(c_array, size, max, index, items, count) (decltype(&(c_array)[0])) DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, items, count)
#define DN_LArray_Insert(c_array, size, max, index, item) (decltype(&(c_array)[0])) DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, &item, 1)
#define DN_IArray_Front(array) (array)->data #define DN_IArray_Front(array) (array)->data
#define DN_IArray_GrowIfNeededFromPool(array, pool) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool) #define DN_IArray_GrowIfNeededFromPool(array, pool) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool)
@ -232,6 +234,8 @@ template <typename T> struct DN_List
#define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend) #define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend)
#define DN_IArray_EraseRange(array, size, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase) #define DN_IArray_EraseRange(array, size, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase)
#define DN_IArray_Erase(array, size, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase) #define DN_IArray_Erase(array, size, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase)
#define DN_IArray_InsertArray(array, index, items, count) (decltype(&((array)->data)[0])) DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, items, count)
#define DN_IArray_Insert(array, index, item, count) (decltype(&((array)->data)[0])) DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, &item, 1)
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem); DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem);

View File

@ -67,11 +67,13 @@ DN_API DN_CVTU64HexStr8 DN_CVT_U64ToHexStr8 (DN_U64 n
DN_API bool DN_CVT_BytesToHexPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size); DN_API bool DN_CVT_BytesToHexPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size);
DN_API DN_Str8 DN_CVT_BytesToHex (DN_Arena *arena, void const *src, DN_USize size); DN_API DN_Str8 DN_CVT_BytesToHex (DN_Arena *arena, void const *src, DN_USize size);
#define DN_CVT_BytesToHexFromTLS(...) DN_CVT_BytesToHex(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_BytesToHexFromTLS(...) DN_CVT_BytesToHex(DN_OS_TLSTopArena(), __VA_ARGS__)
#define DN_CVT_BytesToHexFromFrame(...) DN_CVT_BytesToHex(DN_OS_TLSFrameArena(), __VA_ARGS__)
DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size); DN_API DN_USize DN_CVT_HexToBytesPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size); DN_API DN_USize DN_CVT_HexToBytesPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex); DN_API DN_Str8 DN_CVT_HexToBytesUnchecked (DN_Arena *arena, DN_Str8 hex);
#define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_HexToBytesUncheckedFromTLS(...) DN_CVT_HexToBytesUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex); DN_API DN_Str8 DN_CVT_HexToBytes (DN_Arena *arena, DN_Str8 hex);
#define DN_CVT_HexToBytesFromFrame(...) DN_CVT_HexToBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
#define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__) #define DN_CVT_HexToBytesFromTLS(...) DN_CVT_HexToBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
#endif // defined(DN_BASE_CONVERT_H) #endif // defined(DN_BASE_CONVERT_H)