Cleanup base layer
This commit is contained in:
+2156
-79
File diff suppressed because it is too large
Load Diff
+654
-92
@@ -22,6 +22,7 @@
|
||||
#define DN_ForIndexI(index, size) DN_ISize index = 0; index < size; index++
|
||||
#define DN_ForItSize(it, T, array, size) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < (size); it.index++, it.data = (array) + it.index
|
||||
#define DN_ForIt(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)->data[0]}; it.index < (array)->size; it.index++, it.data = ((array)->data) + it.index
|
||||
#define DN_ForLinkedListIt(it, T, list) struct { DN_USize index; T *data; } it = {0, list}; it.data; it.index++, it.data = ((it).data->next)
|
||||
#define DN_ForItCArray(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < DN_ArrayCountU(array); it.index++, it.data = (array) + it.index
|
||||
|
||||
#define DN_AlignUpPowerOfTwo(value, pot) (((uintptr_t)(value) + ((uintptr_t)(pot) - 1)) & ~((uintptr_t)(pot) - 1))
|
||||
@@ -83,7 +84,7 @@
|
||||
} while (0)
|
||||
|
||||
// NOTE: Size
|
||||
#define DN_SizeOfI(val) DN_CAST(ptrdiff_t)sizeof(val)
|
||||
#define DN_SizeOfI(val) DN_Cast(ptrdiff_t)sizeof(val)
|
||||
#define DN_ArrayCountU(array) (sizeof(array)/(sizeof((array)[0])))
|
||||
#define DN_ArrayCountI(array) (DN_ISize)DN_ArrayCountU(array)
|
||||
#define DN_CharCountU(string) (sizeof(string) - 1)
|
||||
@@ -95,12 +96,12 @@
|
||||
#define DN_Gigabytes(val) ((DN_U64)1024 * DN_Megabytes(val))
|
||||
|
||||
// NOTE: Time
|
||||
#define DN_SecondsToMs(val) ((val) * 1000)
|
||||
#define DN_MinutesToSec(val) ((val) * 60ULL)
|
||||
#define DN_HoursToSec(val) (DN_MinutesToSec(val) * 60ULL)
|
||||
#define DN_DaysToSec(val) (DN_HoursToSec(val) * 24ULL)
|
||||
#define DN_WeeksToSec(val) (DN_DaysToSec(val) * 7ULL)
|
||||
#define DN_YearsToSec(val) (DN_WeeksToSec(val) * 52ULL)
|
||||
#define DN_MsFromSec(val) ((val) * 1000ULL)
|
||||
#define DN_SecFromMins(val) ((val) * 60ULL)
|
||||
#define DN_SecFromHours(val) (DN_SecFromMins(val) * 60ULL)
|
||||
#define DN_SecFromDays(val) (DN_SecFromHours(val) * 24ULL)
|
||||
#define DN_SecFromWeeks(val) (DN_SecFromDays(val) * 7ULL)
|
||||
#define DN_SecFromYears(val) (DN_SecFromWeeks(val) * 52ULL)
|
||||
|
||||
// NOTE: Debug Break
|
||||
#if !defined(DN_DebugBreak)
|
||||
@@ -161,10 +162,10 @@ typedef DN_I32 DN_B32;
|
||||
#define DN_ISIZE_MAX INTPTR_MAX
|
||||
#define DN_ISIZE_MIN INTPTR_MIN
|
||||
|
||||
enum DN_ZeroMem
|
||||
enum DN_ZMem
|
||||
{
|
||||
DN_ZeroMem_No, // Memory can be handed out without zero-ing it out
|
||||
DN_ZeroMem_Yes, // Memory should be zero-ed out before giving to the callee
|
||||
DN_ZMem_No, // Memory can be handed out without zero-ing it out
|
||||
DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee
|
||||
};
|
||||
|
||||
struct DN_Str8
|
||||
@@ -173,21 +174,36 @@ struct DN_Str8
|
||||
DN_USize size; // The number of bytes in the string
|
||||
};
|
||||
|
||||
struct DN_Str8x32 { char data[32]; DN_USize size; };
|
||||
struct DN_Str8x64 { char data[64]; DN_USize size; };
|
||||
struct DN_Str8x128 { char data[128]; DN_USize size; };
|
||||
struct DN_Str8x256 { char data[256]; DN_USize size; };
|
||||
|
||||
struct DN_Hex32 { char data[32]; };
|
||||
struct DN_Hex64 { char data[64]; };
|
||||
struct DN_Hex128 { char data[128]; };
|
||||
|
||||
struct DN_HexU64Str8
|
||||
{
|
||||
char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/];
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
enum DN_HexFromU64Type
|
||||
{
|
||||
DN_HexFromU64Type_Nil,
|
||||
DN_HexFromU64Type_Uppercase,
|
||||
};
|
||||
|
||||
struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes.
|
||||
{
|
||||
wchar_t *data; // The UTF16 bytes of the string
|
||||
DN_USize size; // The number of characters in the string
|
||||
};
|
||||
|
||||
struct DN_U8x32
|
||||
{
|
||||
DN_U8 data[32];
|
||||
};
|
||||
|
||||
struct DN_U8x64
|
||||
{
|
||||
DN_U8 data[64];
|
||||
};
|
||||
struct DN_U8x16 { DN_U8 data[16]; };
|
||||
struct DN_U8x32 { DN_U8 data[32]; };
|
||||
struct DN_U8x64 { DN_U8 data[64]; };
|
||||
|
||||
template <typename T>
|
||||
struct DN_Slice // A pointer and length container of data
|
||||
@@ -208,7 +224,7 @@ struct DN_CallSite
|
||||
DN_U32 line;
|
||||
};
|
||||
|
||||
#define DN_CALL_SITE DN_CallSite { DN_STR8(__FILE__), DN_STR8(__func__), __LINE__ }
|
||||
#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ }
|
||||
|
||||
// NOTE: Defer Macro
|
||||
#if defined(__cplusplus)
|
||||
@@ -247,7 +263,7 @@ struct DN_DeferHelper
|
||||
#define DN_AtomicLoadU32(target) *(target)
|
||||
#define DN_AtomicAddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value)
|
||||
#define DN_AtomicAddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value)
|
||||
#define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_CAST(long volatile *) target, (long)-value)
|
||||
#define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_Cast(long volatile *) target, (long)-value)
|
||||
#define DN_AtomicSubU64(target, value) DN_AtomicAddU64(target, (DN_U64) - value)
|
||||
|
||||
#define DN_CountLeadingZerosU64(value) __lzcnt64(value)
|
||||
@@ -404,92 +420,638 @@ struct DN_TicketMutex
|
||||
unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned
|
||||
};
|
||||
|
||||
DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
struct DN_U64FromResult
|
||||
{
|
||||
bool success;
|
||||
DN_U64 value;
|
||||
};
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPUGetReport ();
|
||||
struct DN_I64FromResult
|
||||
{
|
||||
bool success;
|
||||
DN_I64 value;
|
||||
};
|
||||
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
enum DN_MemCommit
|
||||
{
|
||||
DN_MemCommit_No,
|
||||
DN_MemCommit_Yes,
|
||||
};
|
||||
|
||||
DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_BitClearNextLSB(value) (value) & ((value) - 1)
|
||||
typedef DN_U32 DN_MemPage;
|
||||
enum DN_MemPage_
|
||||
{
|
||||
// Exception on read/write with a page. This flag overrides the read/write
|
||||
// access.
|
||||
DN_MemPage_NoAccess = 1 << 0,
|
||||
|
||||
DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b);
|
||||
DN_MemPage_Read = 1 << 1, // Only read permitted on the page.
|
||||
|
||||
DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b);
|
||||
// Only write permitted on the page. On Windows this is not supported and
|
||||
// will be promoted to read+write permissions.
|
||||
DN_MemPage_Write = 1 << 2,
|
||||
|
||||
DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b);
|
||||
DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write,
|
||||
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
// Modifier used in conjunction with previous flags. Raises exception on
|
||||
// first access to the page, then, the underlying protection flags are
|
||||
// active. This is supported on Windows, on other OS's using this flag will
|
||||
// set the OS equivalent of DN_MemPage_NoAccess.
|
||||
// This flag must only be used in DN_Mem_Protect
|
||||
DN_MemPage_Guard = 1 << 3,
|
||||
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
// If leak tracing is enabled, this flag will allow the allocation recorded
|
||||
// from the reserve call to be leaked, e.g. not printed when leaks are
|
||||
// dumped to the console.
|
||||
DN_MemPage_AllocRecordLeakPermitted = 1 << 4,
|
||||
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
// If leak tracing is enabled this flag will prevent any allocation record
|
||||
// from being created in the allocation table at all. If this flag is
|
||||
// enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the
|
||||
// record will never be created.
|
||||
DN_MemPage_NoAllocRecordEntry = 1 << 5,
|
||||
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
// [INTERNAL] Do not use. All flags together do not constitute a correct
|
||||
// configuration of pages.
|
||||
DN_MemPage_All = DN_MemPage_NoAccess |
|
||||
DN_MemPage_ReadWrite |
|
||||
DN_MemPage_Guard |
|
||||
DN_MemPage_AllocRecordLeakPermitted |
|
||||
DN_MemPage_NoAllocRecordEntry,
|
||||
};
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
#if !defined(DN_ARENA_RESERVE_SIZE)
|
||||
#define DN_ARENA_RESERVE_SIZE DN_Megabytes(64)
|
||||
#endif
|
||||
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
#if !defined(DN_ARENA_COMMIT_SIZE)
|
||||
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
|
||||
#endif
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
enum DN_Allocator
|
||||
{
|
||||
DN_Allocator_Arena,
|
||||
DN_Allocator_Pool,
|
||||
};
|
||||
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
struct DN_ArenaBlock
|
||||
{
|
||||
DN_ArenaBlock *prev;
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 reserve_sum;
|
||||
};
|
||||
|
||||
DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_USize size);
|
||||
typedef DN_U32 DN_ArenaFlags;
|
||||
enum DN_ArenaFlags_
|
||||
{
|
||||
DN_ArenaFlags_Nil = 0,
|
||||
DN_ArenaFlags_NoGrow = 1 << 0,
|
||||
DN_ArenaFlags_NoPoison = 1 << 1,
|
||||
DN_ArenaFlags_NoAllocTrack = 1 << 2,
|
||||
DN_ArenaFlags_AllocCanLeak = 1 << 3,
|
||||
|
||||
DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon);
|
||||
// NOTE: Internal flags. Do not use
|
||||
DN_ArenaFlags_UserBuffer = 1 << 4,
|
||||
DN_ArenaFlags_MemFuncs = 1 << 5,
|
||||
};
|
||||
|
||||
struct DN_ArenaInfo
|
||||
{
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 blocks;
|
||||
};
|
||||
|
||||
struct DN_ArenaStats
|
||||
{
|
||||
DN_ArenaInfo info;
|
||||
DN_ArenaInfo hwm;
|
||||
};
|
||||
|
||||
enum DN_ArenaMemFuncType
|
||||
{
|
||||
DN_ArenaMemFuncType_Nil,
|
||||
DN_ArenaMemFuncType_Basic,
|
||||
DN_ArenaMemFuncType_VMem,
|
||||
};
|
||||
|
||||
typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size);
|
||||
typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr);
|
||||
typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
|
||||
typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size);
|
||||
struct DN_ArenaMemFuncs
|
||||
{
|
||||
DN_ArenaMemFuncType type;
|
||||
DN_ArenaMemBasicAllocFunc *basic_alloc;
|
||||
DN_ArenaMemBasicDeallocFunc *basic_dealloc;
|
||||
|
||||
DN_U32 vmem_page_size;
|
||||
DN_ArenaMemVMemReserveFunc *vmem_reserve;
|
||||
DN_ArenaMemVMemCommitFunc *vmem_commit;
|
||||
DN_ArenaMemVMemReleaseFunc *vmem_release;
|
||||
};
|
||||
|
||||
struct DN_Arena
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs;
|
||||
DN_ArenaBlock *curr;
|
||||
DN_ArenaStats stats;
|
||||
DN_ArenaFlags flags;
|
||||
DN_Str8 label;
|
||||
DN_Arena *prev, *next;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMem
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_U64 used_sum;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMemScope
|
||||
{
|
||||
DN_ArenaTempMemScope(DN_Arena *arena);
|
||||
~DN_ArenaTempMemScope();
|
||||
DN_ArenaTempMem mem;
|
||||
};
|
||||
|
||||
DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64);
|
||||
|
||||
#if !defined(DN_POOL_DEFAULT_ALIGN)
|
||||
#define DN_POOL_DEFAULT_ALIGN 16
|
||||
#endif
|
||||
|
||||
struct DN_PoolSlot
|
||||
{
|
||||
void *data;
|
||||
DN_PoolSlot *next;
|
||||
};
|
||||
|
||||
enum DN_PoolSlotSize
|
||||
{
|
||||
DN_PoolSlotSize_32B,
|
||||
DN_PoolSlotSize_64B,
|
||||
DN_PoolSlotSize_128B,
|
||||
DN_PoolSlotSize_256B,
|
||||
DN_PoolSlotSize_512B,
|
||||
DN_PoolSlotSize_1KiB,
|
||||
DN_PoolSlotSize_2KiB,
|
||||
DN_PoolSlotSize_4KiB,
|
||||
DN_PoolSlotSize_8KiB,
|
||||
DN_PoolSlotSize_16KiB,
|
||||
DN_PoolSlotSize_32KiB,
|
||||
DN_PoolSlotSize_64KiB,
|
||||
DN_PoolSlotSize_128KiB,
|
||||
DN_PoolSlotSize_256KiB,
|
||||
DN_PoolSlotSize_512KiB,
|
||||
DN_PoolSlotSize_1MiB,
|
||||
DN_PoolSlotSize_2MiB,
|
||||
DN_PoolSlotSize_4MiB,
|
||||
DN_PoolSlotSize_8MiB,
|
||||
DN_PoolSlotSize_16MiB,
|
||||
DN_PoolSlotSize_32MiB,
|
||||
DN_PoolSlotSize_64MiB,
|
||||
DN_PoolSlotSize_128MiB,
|
||||
DN_PoolSlotSize_256MiB,
|
||||
DN_PoolSlotSize_512MiB,
|
||||
DN_PoolSlotSize_1GiB,
|
||||
DN_PoolSlotSize_2GiB,
|
||||
DN_PoolSlotSize_4GiB,
|
||||
DN_PoolSlotSize_8GiB,
|
||||
DN_PoolSlotSize_16GiB,
|
||||
DN_PoolSlotSize_32GiB,
|
||||
DN_PoolSlotSize_Count,
|
||||
};
|
||||
|
||||
struct DN_Pool
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_PoolSlot *slots[DN_PoolSlotSize_Count];
|
||||
DN_U8 align;
|
||||
};
|
||||
|
||||
struct DN_NibbleFromU8Result
|
||||
{
|
||||
char nibble0;
|
||||
char nibble1;
|
||||
};
|
||||
|
||||
enum DN_Str8EqCase
|
||||
{
|
||||
DN_Str8EqCase_Sensitive,
|
||||
DN_Str8EqCase_Insensitive,
|
||||
};
|
||||
|
||||
enum DN_Str8IsAllType
|
||||
{
|
||||
DN_Str8IsAllType_Digits,
|
||||
DN_Str8IsAllType_Hex,
|
||||
};
|
||||
|
||||
struct DN_Str8BSplitResult
|
||||
{
|
||||
DN_Str8 lhs;
|
||||
DN_Str8 rhs;
|
||||
};
|
||||
|
||||
struct DN_Str8FindResult
|
||||
{
|
||||
bool found; // True if string was found. If false, the subsequent fields below are not set.
|
||||
DN_USize index; // Index in the buffer where the found string starts
|
||||
DN_Str8 match; // Matching string in the buffer that was searched
|
||||
DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer
|
||||
DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer
|
||||
DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it
|
||||
};
|
||||
|
||||
enum DN_Str8FindFlag
|
||||
{
|
||||
DN_Str8FindFlag_Digit = 1 << 0, // 0-9
|
||||
DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
|
||||
DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
|
||||
DN_Str8FindFlag_Plus = 1 << 3, // +
|
||||
DN_Str8FindFlag_Minus = 1 << 4, // -
|
||||
DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit,
|
||||
};
|
||||
|
||||
enum DN_Str8SplitIncludeEmptyStrings
|
||||
{
|
||||
DN_Str8SplitIncludeEmptyStrings_No,
|
||||
DN_Str8SplitIncludeEmptyStrings_Yes,
|
||||
};
|
||||
|
||||
struct DN_Str8TruncateResult
|
||||
{
|
||||
bool truncated;
|
||||
DN_Str8 str8;
|
||||
};
|
||||
|
||||
struct DN_Str8SplitResult
|
||||
{
|
||||
DN_Str8 *data;
|
||||
DN_USize count;
|
||||
};
|
||||
|
||||
struct DN_Str8Link
|
||||
{
|
||||
DN_Str8 string; // The string
|
||||
DN_Str8Link *next; // The next string in the linked list
|
||||
DN_Str8Link *prev; // The prev string in the linked list
|
||||
};
|
||||
|
||||
struct DN_Str8Builder
|
||||
{
|
||||
DN_Arena *arena; // Allocator to use to back the string list
|
||||
DN_Str8Link *head; // First string in the linked list of strings
|
||||
DN_Str8Link *tail; // Last string in the linked list of strings
|
||||
DN_USize string_size; // The size in bytes necessary to construct the current string
|
||||
DN_USize count; // The number of links in the linked list of strings
|
||||
};
|
||||
|
||||
enum DN_Str8BuilderAdd
|
||||
{
|
||||
DN_Str8BuilderAdd_Append,
|
||||
DN_Str8BuilderAdd_Prepend,
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_AgeUnit;
|
||||
enum DN_AgeUnit_
|
||||
{
|
||||
DN_AgeUnit_Ms = 1 << 0,
|
||||
DN_AgeUnit_Sec = 1 << 1,
|
||||
DN_AgeUnit_Min = 1 << 2,
|
||||
DN_AgeUnit_Hr = 1 << 3,
|
||||
DN_AgeUnit_Day = 1 << 4,
|
||||
DN_AgeUnit_Week = 1 << 5,
|
||||
DN_AgeUnit_Year = 1 << 6,
|
||||
DN_AgeUnit_FractionalSec = 1 << 7,
|
||||
DN_AgeUnit_HMS = DN_AgeUnit_Sec | DN_AgeUnit_Min | DN_AgeUnit_Hr,
|
||||
DN_AgeUnit_All = DN_AgeUnit_Ms | DN_AgeUnit_HMS | DN_AgeUnit_Day | DN_AgeUnit_Week | DN_AgeUnit_Year,
|
||||
};
|
||||
|
||||
enum DN_ByteCountType
|
||||
{
|
||||
DN_ByteCountType_B,
|
||||
DN_ByteCountType_KiB,
|
||||
DN_ByteCountType_MiB,
|
||||
DN_ByteCountType_GiB,
|
||||
DN_ByteCountType_TiB,
|
||||
DN_ByteCountType_Count,
|
||||
DN_ByteCountType_Auto,
|
||||
};
|
||||
|
||||
struct DN_ByteCountResult
|
||||
{
|
||||
DN_ByteCountType type;
|
||||
DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c
|
||||
DN_F64 bytes;
|
||||
};
|
||||
|
||||
struct DN_FmtAppendResult
|
||||
{
|
||||
DN_USize size_req;
|
||||
DN_Str8 str8;
|
||||
bool truncated;
|
||||
};
|
||||
|
||||
#if !defined(DN_STB_SPRINTF_HEADER_ONLY)
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#define STB_SPRINTF_STATIC
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4505) // Unused function warning
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wunused-function)
|
||||
#include "../External/stb_sprintf.h"
|
||||
DN_GCC_WARNING_POP
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__)
|
||||
#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__)
|
||||
#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__)
|
||||
#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__)
|
||||
|
||||
DN_API bool DN_MemEq (void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size);
|
||||
|
||||
DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPUGetReport ();
|
||||
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
|
||||
DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_BitClearNextLSB(value) (value) & ((value) - 1)
|
||||
|
||||
DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b);
|
||||
|
||||
DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b);
|
||||
|
||||
DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b);
|
||||
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
|
||||
DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
|
||||
DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon);
|
||||
|
||||
DN_API DN_Arena DN_ArenaFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_ArenaFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_ArenaDeinit (DN_Arena *arena);
|
||||
DN_API bool DN_ArenaCommit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_ArenaCommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_ArenaGrow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_ArenaAlloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem);
|
||||
DN_API void * DN_ArenaAllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem);
|
||||
DN_API void * DN_ArenaCopy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_ArenaPopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_ArenaPop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_ArenaPos (DN_Arena const *arena);
|
||||
DN_API void DN_ArenaClear (DN_Arena *arena);
|
||||
DN_API bool DN_ArenaOwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_ArenaSumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_ArenaSumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_ArenaSumArenaArrayToStats(DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_ArenaTempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_ArenaTempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_ArenaNew(arena, T, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), zmem)
|
||||
#define DN_ArenaNewZ(arena, T) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewContiguous(arena, T, zmem) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), zmem)
|
||||
#define DN_ArenaNewContiguousZ(arena, T) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewArray(arena, T, count, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), zmem)
|
||||
#define DN_ArenaNewArrayZ(arena, T, count) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API DN_Pool DN_PoolFromArena (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_PoolIsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_PoolAlloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API void DN_PoolDealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_PoolCopy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
#define DN_PoolNew(pool, T) (T *)DN_PoolAlloc(pool, sizeof(T))
|
||||
#define DN_PoolNewArray(pool, T, count) (T *)DN_PoolAlloc(pool, count * sizeof(T))
|
||||
#define DN_PoolNewCopy(pool, T, src) (T *)DN_PoolCopy (pool, (src), sizeof(T), alignof(T))
|
||||
#define DN_PoolNewArrayCopy(pool, T, src, count) (T *)DN_PoolCopy (pool, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API bool DN_CharIsAlphabet (char ch);
|
||||
DN_API bool DN_CharIsDigit (char ch);
|
||||
DN_API bool DN_CharIsAlphaNum (char ch);
|
||||
DN_API bool DN_CharIsWhitespace (char ch);
|
||||
DN_API bool DN_CharIsHex (char ch);
|
||||
DN_API char DN_CharToLower (char ch);
|
||||
DN_API char DN_CharToUpper (char ch);
|
||||
|
||||
DN_API DN_U64FromResult DN_U64FromStr8 (DN_Str8 string, char separator);
|
||||
DN_API DN_U64FromResult DN_U64FromPtr (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_U64 DN_U64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_U64FromResult DN_U64FromHexPtr (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U64 DN_U64FromHexPtrUnsafe (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U64FromResult DN_U64FromHexStr8 (DN_Str8 hex);
|
||||
DN_API DN_U64 DN_U64FromHexStr8Unsafe (DN_Str8 hex);
|
||||
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator);
|
||||
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
||||
|
||||
DN_API DN_USize DN_FmtVSize (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_USize DN_FmtSize (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_FmtAppendResult DN_FmtVAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args);
|
||||
DN_API DN_FmtAppendResult DN_FmtAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...);
|
||||
DN_API DN_FmtAppendResult DN_FmtAppendTruncate (char *buf, DN_USize *buf_size, DN_USize buf_max, DN_Str8 truncator, char const *fmt, ...);
|
||||
DN_API DN_USize DN_CStr8Size (char const *src);
|
||||
DN_API DN_USize DN_CStr16Size (wchar_t const *src);
|
||||
|
||||
#define DN_Str16Lit(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1}
|
||||
#define DN_Str8Lit(c_str) DN_Literal(DN_Str8){(char *)(c_str), sizeof(c_str) - 1}
|
||||
#define DN_Str8PrintFmt(string) (int)((string).size), (string).data
|
||||
#define DN_Str8FromPtr(data, size) DN_Literal(DN_Str8){(char *)(data), (DN_USize)(size)}
|
||||
#define DN_Str8FromStruct(ptr) DN_Str8FromPtr((ptr)->data, (ptr)->size)
|
||||
DN_API DN_Str8 DN_Str8FromCStr8 (char const *src);
|
||||
DN_API DN_Str8 DN_Str8FromArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
DN_API DN_Str8 DN_Str8FromPool (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8FromStr8Arena (DN_Arena *pool, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromStr8Pool (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type);
|
||||
DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all);
|
||||
DN_API char * DN_Str8End (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Slice (DN_Str8 string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8Advance (DN_Str8 string, DN_USize amount);
|
||||
DN_API DN_Str8 DN_Str8NextLine (DN_Str8 string);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplit (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitLast (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitArena (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8FindResult DN_Str8FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, uint32_t flags);
|
||||
DN_API DN_Str8 DN_Str8Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API bool DN_Str8Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8EqInsensitive (DN_Str8 lhs, DN_Str8 rhs);
|
||||
DN_API bool DN_Str8StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8HasChar (DN_Str8 string, char ch);
|
||||
DN_API DN_Str8 DN_Str8TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8TrimHexPrefix (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8TrimAround (DN_Str8 string, DN_Str8 trim_string);
|
||||
DN_API DN_Str8 DN_Str8TrimHeadWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimTailWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimWhitespaceAround (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimByteOrderMark (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FileNameFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileNameNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FilePathNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileDirectoryFromPath(DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args);
|
||||
DN_API void DN_Str8Remove (DN_Str8 *string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddle (DN_Arena *arena, DN_Str8 str8, DN_U32 side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8 DN_Str8Lower (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Upper (DN_Arena *arena, DN_Str8 string);
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromArena (DN_Arena *arena);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromBuilder (DN_Arena *arena, DN_Str8Builder const *builder);
|
||||
DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
DN_API bool DN_Str8BuilderAppendRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8BuilderAppendCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Append, fmt, args)
|
||||
DN_API bool DN_Str8BuilderAppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8BuilderAppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8BuilderAppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8BuilderAppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
DN_API bool DN_Str8BuilderAppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
DN_API bool DN_Str8BuilderPrependRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8BuilderPrependCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args)
|
||||
DN_API bool DN_Str8BuilderPrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8BuilderErase (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8BuilderBuild (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
|
||||
DN_API int DN_EncodeUTF8Codepoint (uint8_t utf8[4], uint32_t codepoint);
|
||||
DN_API int DN_EncodeUTF16Codepoint (uint16_t utf16[2], uint32_t codepoint);
|
||||
|
||||
DN_API DN_U8 DN_U8FromHexNibble (char hex);
|
||||
DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8);
|
||||
|
||||
DN_API DN_USize DN_BytesFromHexPtr (void const *hex, DN_USize hex_count, void *dest, DN_USize dest_count);
|
||||
DN_API DN_Str8 DN_BytesFromHexPtrArena (void const *hex, DN_USize hex_count, DN_Arena *arena);
|
||||
DN_API DN_USize DN_BytesFromHexStr8 (DN_Str8 hex, void *dest, DN_USize dest_count);
|
||||
DN_API DN_Str8 DN_BytesFromHexStr8Arena (DN_Str8 hex, DN_Arena *arena);
|
||||
DN_API DN_U8x16 DN_BytesFromHex32Ptr (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U8x32 DN_BytesFromHex64Ptr (void const *hex, DN_USize hex_count);
|
||||
|
||||
DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type);
|
||||
DN_API DN_USize DN_HexFromBytesPtr (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count);
|
||||
DN_API DN_Str8 DN_HexFromBytesPtrArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena);
|
||||
DN_API DN_Hex32 DN_HexFromBytes16Ptr (void const *bytes, DN_USize bytes_count);
|
||||
DN_API DN_Hex64 DN_HexFromBytes32Ptr (void const *bytes, DN_USize bytes_count);
|
||||
DN_API DN_Hex128 DN_HexFromBytes64Ptr (void const *bytes, DN_USize bytes_count);
|
||||
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromSecU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromSecF64 (DN_F64 sec, DN_AgeUnit units);
|
||||
|
||||
DN_API DN_ByteCountResult DN_ByteCountFromType (DN_U64 bytes, DN_ByteCountType type);
|
||||
#define DN_ByteCount(bytes) DN_ByteCountFromType(bytes, DN_ByteCountType_Auto)
|
||||
DN_API DN_Str8x32 DN_ByteCountStr8x32FromType (DN_U64 bytes, DN_ByteCountType type);
|
||||
#define DN_ByteCountStr8x32(bytes) DN_ByteCountStr8x32FromType(bytes, DN_ByteCountType_Auto)
|
||||
|
||||
#endif // !defined(DN_BASE_H)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
@@ -24,7 +24,7 @@
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
@@ -37,7 +37,7 @@
|
||||
once = false; \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
#endif
|
||||
|
||||
// NOTE: Type Cast /////////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_CAST(val) (val)
|
||||
#define DN_Cast(val) (val)
|
||||
|
||||
// NOTE: Zero initialisation macro /////////////////////////////////////////////////////////////////
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -10,14 +10,14 @@ DN_API void *DN_CArray2_InsertArray(void *data, DN_USize *size, DN_USize max, DN
|
||||
|
||||
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);
|
||||
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);
|
||||
DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move);
|
||||
}
|
||||
|
||||
result = DN_CAST(char *)data + (clamped_index * elem_size);
|
||||
result = DN_Cast(char *)data + (clamped_index * elem_size);
|
||||
DN_Memcpy(result, items, elem_size * count);
|
||||
*size += count;
|
||||
return result;
|
||||
@@ -66,14 +66,14 @@ DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_
|
||||
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_ZMem z_mem)
|
||||
{
|
||||
void *result = nullptr;
|
||||
DN_USize new_size = *size + make_size;
|
||||
if (new_size <= max) {
|
||||
result = DN_CAST(char *) data + (data_size * size[0]);
|
||||
result = DN_Cast(char *) data + (data_size * size[0]);
|
||||
*size = new_size;
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result, 0, data_size * make_size);
|
||||
}
|
||||
|
||||
@@ -82,13 +82,13 @@ DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_U
|
||||
|
||||
DN_API void *DN_CArray2_AddArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add)
|
||||
{
|
||||
void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZeroMem_No);
|
||||
void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZMem_No);
|
||||
if (result) {
|
||||
if (add == DN_ArrayAdd_Append) {
|
||||
DN_Memcpy(result, elems, elems_count * data_size);
|
||||
} else {
|
||||
char *move_dest = DN_CAST(char *)data + (elems_count * data_size); // Shift elements forward
|
||||
char *move_src = DN_CAST(char *)data;
|
||||
char *move_dest = DN_Cast(char *)data + (elems_count * data_size); // Shift elements forward
|
||||
char *move_src = DN_Cast(char *)data;
|
||||
DN_Memmove(move_dest, move_src, data_size * size[0]);
|
||||
DN_Memcpy(data, elems, data_size * elems_count);
|
||||
}
|
||||
@@ -101,11 +101,11 @@ DN_API bool DN_CArray2_ResizeFromPool(void **data, DN_USize *size, DN_USize *max
|
||||
bool result = true;
|
||||
if (new_max != *max) {
|
||||
DN_USize bytes_to_alloc = data_size * new_max;
|
||||
void *buffer = DN_Pool_NewArray(pool, DN_U8, bytes_to_alloc);
|
||||
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
||||
if (buffer) {
|
||||
DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max);
|
||||
DN_Memcpy(buffer, *data, bytes_to_copy);
|
||||
DN_Pool_Dealloc(pool, *data);
|
||||
DN_PoolDealloc(pool, *data);
|
||||
*data = buffer;
|
||||
*max = new_max;
|
||||
*size = DN_Min(*size, new_max);
|
||||
@@ -243,7 +243,7 @@ DN_ArrayEraseResult DN_CArray_EraseRange(T *data, DN_USize *size, DN_USize begin
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!data || !size || count == 0)
|
||||
return nullptr;
|
||||
@@ -254,7 +254,7 @@ T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN
|
||||
// TODO: Use placement new? Why doesn't this work?
|
||||
T *result = data + *size;
|
||||
*size += count;
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result, 0, sizeof(*result) * count);
|
||||
return result;
|
||||
}
|
||||
@@ -268,11 +268,11 @@ T *DN_CArray_InsertArray(T *data, DN_USize *size, DN_USize max, DN_USize index,
|
||||
|
||||
DN_USize clamped_index = DN_Min(index, *size);
|
||||
if (clamped_index != *size) {
|
||||
char const *src = DN_CAST(char *)(data + clamped_index);
|
||||
char const *dest = DN_CAST(char *)(data + (clamped_index + count));
|
||||
char const *end = DN_CAST(char *)(data + (*size));
|
||||
char const *src = DN_Cast(char *)(data + clamped_index);
|
||||
char const *dest = DN_Cast(char *)(data + (clamped_index + count));
|
||||
char const *end = DN_Cast(char *)(data + (*size));
|
||||
DN_USize bytes_to_move = end - src;
|
||||
DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move);
|
||||
DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move);
|
||||
}
|
||||
|
||||
result = data + clamped_index;
|
||||
@@ -329,34 +329,34 @@ DN_ArrayFindResult<T> DN_CArray_Find(T *data, DN_USize size, T const &value)
|
||||
#if !defined(DN_NO_SARRAY)
|
||||
// NOTE: DN_SArray /////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
DN_SArray<T> DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_SArray<T> result = {};
|
||||
if (!arena || !size)
|
||||
return result;
|
||||
result.data = DN_Arena_NewArray(arena, T, size, zero_mem);
|
||||
result.data = DN_ArenaNewArray(arena, T, size, z_mem);
|
||||
if (result.data)
|
||||
result.max = size;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DN_SArray<T> DN_SArray_InitSlice(DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_InitSlice(DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_USize max = DN_Max(slice.size, size);
|
||||
DN_SArray<T> result = DN_SArray_Init<T>(arena, max, DN_ZeroMem_No);
|
||||
DN_SArray<T> result = DN_SArray_Init<T>(arena, max, DN_ZMem_No);
|
||||
if (DN_SArray_IsValid(&result)) {
|
||||
DN_SArray_AddArray(&result, slice.data, slice.size);
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result.data + result.size, 0, (result.max - result.size) * sizeof(T));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
DN_SArray<T> DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_SArray<T> result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_CAST(T *) array, N), size, zero_mem);
|
||||
DN_SArray<T> result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_Cast(T *) array, N), size, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -381,30 +381,30 @@ DN_Slice<T> DN_SArray_Slice(DN_SArray<T> const *array)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (array)
|
||||
result = DN_Slice_Init<T>(DN_CAST(T *) array->data, array->size);
|
||||
result = DN_Slice_Init<T>(DN_Cast(T *) array->data, array->size);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_MakeArray(DN_SArray<T> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_SArray_MakeArray(DN_SArray<T> *array, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!DN_SArray_IsValid(array))
|
||||
return nullptr;
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, zero_mem);
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_Make(DN_SArray<T> *array, DN_ZeroMem zero_mem)
|
||||
T *DN_SArray_Make(DN_SArray<T> *array, DN_ZMem z_mem)
|
||||
{
|
||||
T *result = DN_SArray_MakeArray(array, 1, zero_mem);
|
||||
T *result = DN_SArray_MakeArray(array, 1, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_AddArray(DN_SArray<T> *array, T const *items, DN_USize count)
|
||||
{
|
||||
T *result = DN_SArray_MakeArray(array, count, DN_ZeroMem_No);
|
||||
T *result = DN_SArray_MakeArray(array, count, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, count * sizeof(T));
|
||||
return result;
|
||||
@@ -517,14 +517,14 @@ DN_Slice<T> DN_FArray_Slice(DN_FArray<T, N> const *array)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (array)
|
||||
result = DN_Slice_Init<T>(DN_CAST(T *) array->data, array->size);
|
||||
result = DN_Slice_Init<T>(DN_Cast(T *) array->data, array->size);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_AddArray(DN_FArray<T, N> *array, T const *items, DN_USize count)
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, count, DN_ZeroMem_No);
|
||||
T *result = DN_FArray_MakeArray(array, count, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, count * sizeof(T));
|
||||
return result;
|
||||
@@ -533,7 +533,7 @@ T *DN_FArray_AddArray(DN_FArray<T, N> *array, T const *items, DN_USize count)
|
||||
template <typename T, DN_USize N, DN_USize K>
|
||||
T *DN_FArray_AddCArray(DN_FArray<T, N> *array, T const (&items)[K])
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, K, DN_ZeroMem_No);
|
||||
T *result = DN_FArray_MakeArray(array, K, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, K * sizeof(T));
|
||||
return result;
|
||||
@@ -547,18 +547,18 @@ T *DN_FArray_Add(DN_FArray<T, N> *array, T const &item)
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_MakeArray(DN_FArray<T, N> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_FArray_MakeArray(DN_FArray<T, N> *array, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!DN_FArray_IsValid(array))
|
||||
return nullptr;
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, zero_mem);
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_Make(DN_FArray<T, N> *array, DN_ZeroMem zero_mem)
|
||||
T *DN_FArray_Make(DN_FArray<T, N> *array, DN_ZMem z_mem)
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, 1, zero_mem);
|
||||
T *result = DN_FArray_MakeArray(array, 1, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ DN_Slice<T> DN_Slice_Init(T *const data, DN_USize size)
|
||||
template <typename T, DN_USize N>
|
||||
DN_Slice<T> DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N])
|
||||
{
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, N, DN_ZeroMem_No);
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, N, DN_ZMem_No);
|
||||
if (result.data)
|
||||
DN_Memcpy(result.data, array, sizeof(T) * N);
|
||||
return result;
|
||||
@@ -649,7 +649,7 @@ DN_Slice<T> DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N])
|
||||
template <typename T>
|
||||
DN_Slice<T> DN_Slice_CopyPtr(DN_Arena *arena, T *const data, DN_USize size)
|
||||
{
|
||||
T *copy = DN_Arena_NewArrayCopy(arena, T, data, size);
|
||||
T *copy = DN_ArenaNewArrayCopy(arena, T, data, size);
|
||||
DN_Slice<T> result = DN_Slice_Init(copy, copy ? size : 0);
|
||||
return result;
|
||||
}
|
||||
@@ -662,12 +662,12 @@ DN_Slice<T> DN_Slice_Copy(DN_Arena *arena, DN_Slice<T> slice)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DN_Slice<T> DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_Slice<T> DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (!arena || size == 0)
|
||||
return result;
|
||||
result.data = DN_Arena_NewArray(arena, T, size, zero_mem);
|
||||
result.data = DN_ArenaNewArray(arena, T, size, z_mem);
|
||||
if (result.data)
|
||||
result.size = size;
|
||||
return result;
|
||||
@@ -691,9 +691,9 @@ DN_DSMap<T> DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags)
|
||||
if (!DN_Check(arena))
|
||||
return result;
|
||||
result.arena = arena;
|
||||
result.pool = DN_Pool_FromArena(arena, DN_POOL_DEFAULT_ALIGN);
|
||||
result.hash_to_slot = DN_Arena_NewArray(result.arena, DN_U32, size, DN_ZeroMem_Yes);
|
||||
result.slots = DN_Arena_NewArray(result.arena, DN_DSMapSlot<T>, size, DN_ZeroMem_Yes);
|
||||
result.pool = DN_PoolFromArena(arena, DN_POOL_DEFAULT_ALIGN);
|
||||
result.hash_to_slot = DN_ArenaNewArray(result.arena, DN_U32, size, DN_ZMem_Yes);
|
||||
result.slots = DN_ArenaNewArray(result.arena, DN_DSMapSlot<T>, size, DN_ZMem_Yes);
|
||||
result.occupied = 1; // For sentinel
|
||||
result.size = size;
|
||||
result.initial_size = size;
|
||||
@@ -703,13 +703,13 @@ DN_DSMap<T> DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DN_DSMap_Deinit(DN_DSMap<T> *map, DN_ZeroMem zero_mem)
|
||||
void DN_DSMap_Deinit(DN_DSMap<T> *map, DN_ZMem z_mem)
|
||||
{
|
||||
if (!map)
|
||||
return;
|
||||
// TODO(doyle): Use zero_mem
|
||||
(void)zero_mem;
|
||||
DN_Arena_Deinit(map->arena);
|
||||
// TODO(doyle): Use z_mem
|
||||
(void)z_mem;
|
||||
DN_ArenaDeinit(map->arena);
|
||||
*map = {};
|
||||
}
|
||||
|
||||
@@ -733,7 +733,7 @@ DN_U32 DN_DSMap_Hash(DN_DSMap<T> const *map, DN_DSMapKey key)
|
||||
return result;
|
||||
|
||||
if (key.type == DN_DSMapKeyType_U64NoHash) {
|
||||
result = DN_CAST(DN_U32) key.u64;
|
||||
result = DN_Cast(DN_U32) key.u64;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -761,12 +761,12 @@ DN_U32 DN_DSMap_Hash(DN_DSMap<T> const *map, DN_DSMapKey key)
|
||||
case DN_DSMapKeyType_Invalid: break;
|
||||
|
||||
case DN_DSMapKeyType_Buffer:
|
||||
key_ptr = DN_CAST(char const *) key.buffer_data;
|
||||
key_ptr = DN_Cast(char const *) key.buffer_data;
|
||||
len = key.buffer_size;
|
||||
break;
|
||||
|
||||
case DN_DSMapKeyType_U64:
|
||||
key_ptr = DN_CAST(char const *) & key.u64;
|
||||
key_ptr = DN_Cast(char const *) & key.u64;
|
||||
len = sizeof(key.u64);
|
||||
break;
|
||||
}
|
||||
@@ -870,7 +870,7 @@ DN_DSMapResult<T> DN_DSMap_Make(DN_DSMap<T> *map, DN_DSMapKey key)
|
||||
if ((key.type == DN_DSMapKeyType_Buffer ||
|
||||
key.type == DN_DSMapKeyType_BufferAsU64NoHash) &&
|
||||
!key.no_copy_buffer)
|
||||
result.slot->key.buffer_data = DN_Pool_NewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size);
|
||||
result.slot->key.buffer_data = DN_PoolNewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size);
|
||||
}
|
||||
} else {
|
||||
result.slot = map->slots + map->hash_to_slot[index];
|
||||
@@ -970,7 +970,7 @@ bool DN_DSMap_Resize(DN_DSMap<T> *map, DN_U32 size)
|
||||
}
|
||||
|
||||
if ((map->flags & DN_DSMapFlags_DontFreeArenaOnResize) == 0)
|
||||
DN_DSMap_Deinit(map, DN_ZeroMem_No);
|
||||
DN_DSMap_Deinit(map, DN_ZMem_No);
|
||||
*map = new_map; // Update the map inplace
|
||||
map->arena = prev_arena; // Restore the previous arena pointer, it's been de-init-ed
|
||||
*map->arena = new_arena; // Re-init the old arena with the new data
|
||||
@@ -997,7 +997,7 @@ bool DN_DSMap_Erase(DN_DSMap<T> *map, DN_DSMapKey key)
|
||||
|
||||
DN_DSMapSlot<T> *slot = map->slots + slot_index;
|
||||
if (!slot->key.no_copy_buffer)
|
||||
DN_Pool_Dealloc(&map->pool, DN_CAST(void *) slot->key.buffer_data);
|
||||
DN_PoolDealloc(&map->pool, DN_Cast(void *) slot->key.buffer_data);
|
||||
*slot = {}; // TODO: Optional?
|
||||
|
||||
if (map->occupied > 1 /*Sentinel*/) {
|
||||
@@ -1074,7 +1074,7 @@ DN_DSMapKey DN_DSMap_KeyBuffer(DN_DSMap<T> const *map, void const *data, DN_USiz
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_Buffer;
|
||||
result.buffer_data = data;
|
||||
result.buffer_size = DN_CAST(DN_U32) size;
|
||||
result.buffer_size = DN_Cast(DN_U32) size;
|
||||
result.hash = DN_DSMap_Hash(map, result);
|
||||
return result;
|
||||
}
|
||||
@@ -1085,7 +1085,7 @@ DN_DSMapKey DN_DSMap_KeyBufferAsU64NoHash(DN_DSMap<T> const *map, void const *da
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_BufferAsU64NoHash;
|
||||
result.buffer_data = data;
|
||||
result.buffer_size = DN_CAST(DN_U32) size;
|
||||
result.buffer_size = DN_Cast(DN_U32) size;
|
||||
DN_Assert(size >= sizeof(result.hash));
|
||||
DN_Memcpy(&result.hash, data, sizeof(result.hash));
|
||||
return result;
|
||||
@@ -1158,16 +1158,16 @@ DN_API bool DN_List_AttachTail_(DN_List<T> *list, DN_ListChunk<T> *tail)
|
||||
template <typename T>
|
||||
DN_API DN_ListChunk<T> *DN_List_AllocArena_(DN_List<T> *list, DN_Arena *arena, DN_USize count)
|
||||
{
|
||||
auto *result = DN_Arena_New(arena, DN_ListChunk<T>, DN_ZeroMem_Yes);
|
||||
DN_ArenaTempMem tmem = DN_Arena_TempMemBegin(arena);
|
||||
auto *result = DN_ArenaNew(arena, DN_ListChunk<T>, DN_ZMem_Yes);
|
||||
DN_ArenaTempMem tmem = DN_ArenaTempMemBegin(arena);
|
||||
if (!result)
|
||||
return nullptr;
|
||||
|
||||
DN_USize items = DN_Max(list->chunk_size, count);
|
||||
result->data = DN_Arena_NewArray(arena, T, items, DN_ZeroMem_Yes);
|
||||
result->data = DN_ArenaNewArray(arena, T, items, DN_ZMem_Yes);
|
||||
result->size = items;
|
||||
if (!result->data) {
|
||||
DN_Arena_TempMemEnd(tmem);
|
||||
DN_ArenaTempMemEnd(tmem);
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
@@ -1178,15 +1178,15 @@ DN_API DN_ListChunk<T> *DN_List_AllocArena_(DN_List<T> *list, DN_Arena *arena, D
|
||||
template <typename T>
|
||||
DN_API DN_ListChunk<T> *DN_List_AllocPool_(DN_List<T> *list, DN_Pool *pool, DN_USize count)
|
||||
{
|
||||
auto *result = DN_Pool_New(pool, DN_ListChunk<T>);
|
||||
auto *result = DN_PoolNew(pool, DN_ListChunk<T>);
|
||||
if (!result)
|
||||
return nullptr;
|
||||
|
||||
DN_USize items = DN_Max(list->chunk_size, count);
|
||||
result->data = DN_Pool_NewArray(pool, T, items);
|
||||
result->data = DN_PoolNewArray(pool, T, items);
|
||||
result->size = items;
|
||||
if (!result->data) {
|
||||
DN_Pool_Dealloc(result);
|
||||
DN_PoolDealloc(result);
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
@@ -1349,12 +1349,12 @@ template <typename T>
|
||||
DN_Slice<T> DN_List_ToSliceCopy(DN_List<T> const *list, DN_Arena *arena)
|
||||
{
|
||||
// TODO(doyle): Chunk memcopies is much faster
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, list->count, DN_ZeroMem_No);
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, list->count, DN_ZMem_No);
|
||||
if (result.size) {
|
||||
DN_USize slice_index = 0;
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6011) // Dereferencing NULL pointer 'x'
|
||||
for (DN_ListIterator<T> it = {}; DN_List_Iterate<T>(DN_CAST(DN_List<T> *) list, &it, 0);)
|
||||
for (DN_ListIterator<T> it = {}; DN_List_Iterate<T>(DN_Cast(DN_List<T> *) list, &it, 0);)
|
||||
result.data[slice_index++] = *it.data;
|
||||
DN_MSVC_WARNING_POP
|
||||
DN_Assert(slice_index == result.size);
|
||||
@@ -1378,7 +1378,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice<DN_Str8> array, DN_
|
||||
total_size += item.size;
|
||||
}
|
||||
|
||||
result = DN_Str8_Alloc(arena, total_size, DN_ZeroMem_No);
|
||||
result = DN_Str8FromArena(arena, total_size, DN_ZMem_No);
|
||||
if (result.data) {
|
||||
DN_USize write_index = 0;
|
||||
for (DN_USize index = 0; index < array.size; index++) {
|
||||
@@ -1397,7 +1397,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice<DN_Str8> array, DN_
|
||||
|
||||
DN_API DN_Str8 DN_Slice_Str8RenderSpaceSeparated(DN_Arena *arena, DN_Slice<DN_Str8> array)
|
||||
{
|
||||
DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_STR8(" "));
|
||||
DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_Str8Lit(" "));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1415,7 +1415,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice<DN_Str16> array,
|
||||
total_size += item.size;
|
||||
}
|
||||
|
||||
result = {DN_Arena_NewArray(arena, wchar_t, total_size + 1, DN_ZeroMem_No), total_size};
|
||||
result = {DN_ArenaNewArray(arena, wchar_t, total_size + 1, DN_ZMem_No), total_size};
|
||||
if (result.data) {
|
||||
DN_USize write_index = 0;
|
||||
for (DN_USize index = 0; index < array.size; index++) {
|
||||
@@ -1435,7 +1435,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice<DN_Str16> array,
|
||||
|
||||
DN_API DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice<DN_Str16> array)
|
||||
{
|
||||
DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_STR16(L" "));
|
||||
DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_Str16Lit(L" "));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1446,7 +1446,7 @@ DN_API DN_DSMapKey DN_DSMap_KeyU64NoHash(DN_U64 u64)
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_U64NoHash;
|
||||
result.u64 = u64;
|
||||
result.hash = DN_CAST(DN_U32) u64;
|
||||
result.hash = DN_Cast(DN_U32) u64;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ template <typename T> struct DN_List
|
||||
// ```
|
||||
// MyStruct buffer[TB_ASType_Count] = {};
|
||||
// DN_USize size = 0;
|
||||
// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZeroMem_No);
|
||||
// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZMem_No);
|
||||
// ```
|
||||
//
|
||||
// IArray => Intrusive Array
|
||||
@@ -189,7 +189,7 @@ template <typename T> struct DN_List
|
||||
// DN_USize max;
|
||||
// } my_array = {};
|
||||
//
|
||||
// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZeroMem_No);
|
||||
// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZMem_No);
|
||||
// ```
|
||||
// ISLList => Intrusive Singly Linked List
|
||||
// Define a struct with the members 'next':
|
||||
@@ -210,13 +210,13 @@ template <typename T> struct DN_List
|
||||
|
||||
#define DN_DLList_InitArena(list, T, arena) \
|
||||
do { \
|
||||
(list) = DN_Arena_New(arena, T, DN_ZeroMem_Yes); \
|
||||
(list) = DN_ArenaNew(arena, T, DN_ZMem_Yes); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_InitPool(list, T, pool) \
|
||||
do { \
|
||||
(list) = DN_Pool_New(pool, T); \
|
||||
(list) = DN_PoolNew(pool, T); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
@@ -278,10 +278,10 @@ template <typename T> struct DN_List
|
||||
#define DN_LArray_ResizeFromPool(c_array, size, max, pool, new_max) DN_CArray2_ResizeFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max)
|
||||
#define DN_LArray_GrowFromPool(c_array, size, max, pool, new_max) DN_CArray2_GrowFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max)
|
||||
#define DN_LArray_GrowIfNeededFromPool(c_array, size, max, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(c_array), size, max, sizeof((c_array)[0]), pool, add_count)
|
||||
#define DN_LArray_MakeArray(c_array, size, max, count, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, zero_mem)
|
||||
#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZeroMem_Yes)
|
||||
#define DN_LArray_Make(c_array, size, max, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, zero_mem)
|
||||
#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZeroMem_Yes)
|
||||
#define DN_LArray_MakeArray(c_array, size, max, count, z_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, z_mem)
|
||||
#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZMem_Yes)
|
||||
#define DN_LArray_Make(c_array, size, max, z_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, z_mem)
|
||||
#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZMem_Yes)
|
||||
#define DN_LArray_AddArray(c_array, size, max, items, count, add) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), items, count, add)
|
||||
#define DN_LArray_Add(c_array, size, max, item, add) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, add)
|
||||
#define DN_LArray_AppendArray(c_array, size, max, items, count) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Append)
|
||||
@@ -296,10 +296,10 @@ template <typename T> struct DN_List
|
||||
#define DN_IArray_ResizeFromPool(array, pool, new_max) DN_CArray2_ResizeFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max)
|
||||
#define DN_IArray_GrowFromPool(array, pool, new_max) DN_CArray2_GrowFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max)
|
||||
#define DN_IArray_GrowIfNeededFromPool(array, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool, add_count)
|
||||
#define DN_IArray_MakeArray(array, count, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, zero_mem)
|
||||
#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZeroMem_Yes)
|
||||
#define DN_IArray_Make(array, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, zero_mem)
|
||||
#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZeroMem_Yes)
|
||||
#define DN_IArray_MakeArray(array, count, z_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, z_mem)
|
||||
#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZMem_Yes)
|
||||
#define DN_IArray_Make(array, z_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, z_mem)
|
||||
#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZMem_Yes)
|
||||
#define DN_IArray_AddArray(array, items, count, add) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, add)
|
||||
#define DN_IArray_Add(array, item, add) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, add)
|
||||
#define DN_IArray_AppendArray(array, items, count) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Append)
|
||||
@@ -312,7 +312,7 @@ template <typename T> struct DN_List
|
||||
#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 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_ZMem z_mem);
|
||||
DN_API void *DN_CArray2_AddArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add);
|
||||
DN_API bool DN_CArray2_Resize (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
||||
DN_API bool DN_CArray2_Grow (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
||||
@@ -327,7 +327,7 @@ DN_API void DN_Ring_Read (DN_Ring *ring, voi
|
||||
#define DN_Ring_ReadStruct(ring, dest) DN_Ring_Read((ring), (dest), sizeof(*(dest)))
|
||||
|
||||
template <typename T> DN_ArrayEraseResult DN_CArray_EraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
|
||||
template <typename T> T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T> T * DN_CArray_InsertArray (T *data, DN_USize *size, DN_USize max, DN_USize index, T const *items, DN_USize count);
|
||||
template <typename T> T DN_CArray_PopFront (T *data, DN_USize *size, DN_USize count);
|
||||
template <typename T> T DN_CArray_PopBack (T *data, DN_USize *size, DN_USize count);
|
||||
@@ -335,9 +335,9 @@ template <typename T> DN_ArrayFindResult<T> DN_CArray_
|
||||
|
||||
// NOTE: DN_SArray /////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(DN_NO_SARRAY)
|
||||
template <typename T> DN_SArray<T> DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitSlice (DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T, size_t N> DN_SArray<T> DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitSlice (DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZMem z_mem);
|
||||
template <typename T, size_t N> DN_SArray<T> DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitBuffer (T* buffer, DN_USize size);
|
||||
template <typename T> bool DN_SArray_IsValid (DN_SArray<T> const *array);
|
||||
template <typename T> DN_Slice<T> DN_SArray_Slice (DN_SArray<T> const *array);
|
||||
@@ -347,8 +347,8 @@ template <typename T> T * DN_SArray_
|
||||
#define DN_SArray_AddArrayAssert(...) DN_HardAssert(DN_SArray_AddArray(__VA_ARGS__))
|
||||
#define DN_SArray_AddCArrayAssert(...) DN_HardAssert(DN_SArray_AddCArray(__VA_ARGS__))
|
||||
#define DN_SArray_AddAssert(...) DN_HardAssert(DN_SArray_Add(__VA_ARGS__))
|
||||
template <typename T> T * DN_SArray_MakeArray (DN_SArray<T> *array, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_SArray_Make (DN_SArray<T> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_SArray_MakeArray (DN_SArray<T> *array, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T> T * DN_SArray_Make (DN_SArray<T> *array, DN_ZMem z_mem);
|
||||
#define DN_SArray_MakeArrayAssert(...) DN_HardAssert(DN_SArray_MakeArray(__VA_ARGS__))
|
||||
#define DN_SArray_MakeAssert(...) DN_HardAssert(DN_SArray_Make(__VA_ARGS__))
|
||||
template <typename T> T * DN_SArray_InsertArray (DN_SArray<T> *array, DN_USize index, T const *items, DN_USize count);
|
||||
@@ -378,8 +378,8 @@ template <typename T, DN_USize N> T * DN_FArray_
|
||||
#define DN_FArray_AddArrayAssert(...) DN_HardAssert(DN_FArray_AddArray(__VA_ARGS__))
|
||||
#define DN_FArray_AddCArrayAssert(...) DN_HardAssert(DN_FArray_AddCArray(__VA_ARGS__))
|
||||
#define DN_FArray_AddAssert(...) DN_HardAssert(DN_FArray_Add(__VA_ARGS__))
|
||||
template <typename T, DN_USize N> T * DN_FArray_MakeArray (DN_FArray<T, N> *array, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_Make (DN_FArray<T, N> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_MakeArray (DN_FArray<T, N> *array, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_Make (DN_FArray<T, N> *array, DN_ZMem z_mem);
|
||||
#define DN_FArray_MakeArrayAssert(...) DN_HardAssert(DN_FArray_MakeArray(__VA_ARGS__))
|
||||
#define DN_FArray_MakeAssert(...) DN_HardAssert(DN_FArray_Make(__VA_ARGS__))
|
||||
template <typename T, DN_USize N> T * DN_FArray_InsertArray (DN_FArray<T, N> *array, T const &item, DN_USize index);
|
||||
@@ -401,7 +401,7 @@ template <typename T> DN_Slice<T> DN_Slice_I
|
||||
template <typename T, DN_USize N> DN_Slice<T> DN_Slice_InitCArrayCopy (DN_Arena *arena, T const (&array)[N]);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Copy (DN_Arena *arena, DN_Slice<T> slice);
|
||||
template <typename T> DN_Slice<T> DN_Slice_CopyPtr (DN_Arena *arena, T* const data, DN_USize size);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
DN_Str8 DN_Slice_Str8Render (DN_Arena *arena, DN_Slice<DN_Str8> array, DN_Str8 separator);
|
||||
DN_Str8 DN_Slice_Str8RenderSpaceSeparated (DN_Arena *arena, DN_Slice<DN_Str8> array);
|
||||
DN_Str16 DN_Slice_Str16Render (DN_Arena *arena, DN_Slice<DN_Str16> array, DN_Str16 separator);
|
||||
@@ -410,7 +410,7 @@ template <typename T> DN_Slice<T> DN_Slice_A
|
||||
|
||||
#if !defined(DN_NO_DSMAP)
|
||||
template <typename T> DN_DSMap<T> DN_DSMap_Init (DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags);
|
||||
template <typename T> void DN_DSMap_Deinit (DN_DSMap<T> *map, DN_ZeroMem zero_mem);
|
||||
template <typename T> void DN_DSMap_Deinit (DN_DSMap<T> *map, DN_ZMem z_mem);
|
||||
template <typename T> bool DN_DSMap_IsValid (DN_DSMap<T> const *map);
|
||||
template <typename T> DN_U32 DN_DSMap_Hash (DN_DSMap<T> const *map, DN_DSMapKey key);
|
||||
template <typename T> DN_U32 DN_DSMap_HashToSlotIndex (DN_DSMap<T> const *map, DN_DSMapKey key);
|
||||
|
||||
@@ -1,389 +0,0 @@
|
||||
#define DN_CONVERT_CPP
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8(DN_U8 u8)
|
||||
{
|
||||
static char const *table = "0123456789abcdef";
|
||||
DN_U8 lhs = (u8 >> 0) & 0xF;
|
||||
DN_U8 rhs = (u8 >> 4) & 0xF;
|
||||
DN_NibbleFromU8Result result = {};
|
||||
result.nibble0 = table[rhs];
|
||||
result.nibble1 = table[lhs];
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U8 DN_CVT_U8FromHexNibble(char hex)
|
||||
{
|
||||
bool digit = hex >= '0' && hex <= '9';
|
||||
bool upper = hex >= 'A' && hex <= 'F';
|
||||
bool lower = hex >= 'a' && hex <= 'f';
|
||||
DN_U8 result = 0xFF;
|
||||
if (digit)
|
||||
result = hex - '0';
|
||||
if (upper)
|
||||
result = hex - 'A' + 10;
|
||||
if (lower)
|
||||
result = hex - 'a' + 10;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API int DN_CVT_FmtBuffer3DotTruncate(char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int size_required = DN_VSNPrintF(buffer, size, fmt, args);
|
||||
int result = DN_Max(DN_Min(size_required, size - 1), 0);
|
||||
if (result == size - 1) {
|
||||
buffer[size - 2] = '.';
|
||||
buffer[size - 3] = '.';
|
||||
}
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64(DN_U64 val, char separator)
|
||||
{
|
||||
DN_CVTU64Str8 result = {};
|
||||
if (val == 0) {
|
||||
result.data[result.size++] = '0';
|
||||
} else {
|
||||
// NOTE: The number is written in reverse because we form the string by
|
||||
// dividing by 10, so we write it in, then reverse it out after all is
|
||||
// done.
|
||||
DN_CVTU64Str8 temp = {};
|
||||
for (DN_USize digit_count = 0; val > 0; digit_count++) {
|
||||
if (separator && (digit_count != 0) && (digit_count % 3 == 0))
|
||||
temp.data[temp.size++] = separator;
|
||||
|
||||
auto digit = DN_CAST(char)(val % 10);
|
||||
temp.data[temp.size++] = '0' + digit;
|
||||
val /= 10;
|
||||
}
|
||||
|
||||
// NOTE: Reverse the string
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6293) // Ill-defined for-loop
|
||||
DN_MSVC_WARNING_DISABLE(6385) // Reading invalid data from 'temp.data' unsigned overflow is valid for loop termination
|
||||
for (DN_USize temp_index = temp.size - 1; temp_index < temp.size; temp_index--) {
|
||||
char ch = temp.data[temp_index];
|
||||
result.data[result.size++] = ch;
|
||||
}
|
||||
DN_MSVC_WARNING_POP
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64(DN_U64 bytes, DN_CVTBytesType type)
|
||||
{
|
||||
DN_Assert(type != DN_CVTBytesType_Count);
|
||||
DN_CVTU64Bytes result = {};
|
||||
result.bytes = DN_CAST(DN_F64) bytes;
|
||||
|
||||
if (type == DN_CVTBytesType_Auto)
|
||||
for (; result.type < DN_CVTBytesType_Count && result.bytes >= 1024.0; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1))
|
||||
result.bytes /= 1024.0;
|
||||
else
|
||||
for (; result.type < type; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1))
|
||||
result.bytes /= 1024.0;
|
||||
|
||||
result.suffix = DN_CVT_BytesTypeToStr8(result.type);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesStr8FromU64(DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType desired_type)
|
||||
{
|
||||
DN_CVTU64Bytes byte_size = DN_CVT_BytesFromU64(bytes, desired_type);
|
||||
DN_Str8 result = DN_Str8_FromF(arena, "%.2f%.*s", byte_size.bytes, DN_STR_FMT(byte_size.suffix));
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesTypeToStr8(DN_CVTBytesType type)
|
||||
{
|
||||
DN_Str8 result = DN_STR8("");
|
||||
switch (type) {
|
||||
case DN_CVTBytesType_B: result = DN_STR8("B"); break;
|
||||
case DN_CVTBytesType_KiB: result = DN_STR8("KiB"); break;
|
||||
case DN_CVTBytesType_MiB: result = DN_STR8("MiB"); break;
|
||||
case DN_CVTBytesType_GiB: result = DN_STR8("GiB"); break;
|
||||
case DN_CVTBytesType_TiB: result = DN_STR8("TiB"); break;
|
||||
case DN_CVTBytesType_Count: result = DN_STR8(""); break;
|
||||
case DN_CVTBytesType_Auto: result = DN_STR8(""); break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_AgeFromU64(DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!arena)
|
||||
return result;
|
||||
|
||||
char buffer[512];
|
||||
DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena);
|
||||
DN_U64 remainder = age_s;
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Year) {
|
||||
DN_USize value = remainder / DN_YearsToSec(1);
|
||||
remainder -= DN_YearsToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuyr", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Week) {
|
||||
DN_USize value = remainder / DN_WeeksToSec(1);
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuw", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Day) {
|
||||
DN_USize value = remainder / DN_DaysToSec(1);
|
||||
remainder -= DN_DaysToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zud", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Hr) {
|
||||
DN_USize value = remainder / DN_HoursToSec(1);
|
||||
remainder -= DN_HoursToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuh", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Min) {
|
||||
DN_USize value = remainder / DN_MinutesToSec(1);
|
||||
remainder -= DN_MinutesToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zum", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Sec) {
|
||||
DN_USize value = remainder;
|
||||
if (value || builder.string_size == 0)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zus", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_AgeFromF64(DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!arena)
|
||||
return result;
|
||||
|
||||
char buffer[256];
|
||||
DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena);
|
||||
DN_F64 remainder = age_s;
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Year) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_YearsToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_YearsToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fyr", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Week) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_WeeksToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fw", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Day) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_DaysToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fd", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Hr) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_HoursToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_HoursToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fh", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Min) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_MinutesToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_MinutesToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fm", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Sec) {
|
||||
DN_F64 value = remainder;
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fs", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_CVT_U64FromHex(DN_Str8 hex)
|
||||
{
|
||||
DN_Str8 real_hex = DN_Str8_TrimPrefix(DN_Str8_TrimPrefix(hex, DN_STR8("0x")), DN_STR8("0X"));
|
||||
DN_USize max_hex_size = sizeof(DN_U64) * 2 /*hex chars per byte*/;
|
||||
DN_Assert(real_hex.size <= max_hex_size);
|
||||
|
||||
DN_USize size = DN_Min(max_hex_size, real_hex.size);
|
||||
DN_U64 result = 0;
|
||||
for (DN_USize index = 0; index < size; index++) {
|
||||
char ch = real_hex.data[index];
|
||||
DN_U8 val = DN_CVT_U8FromHexNibble(ch);
|
||||
if (val == 0xFF)
|
||||
break;
|
||||
result = (result << 4) | val;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_HexFromU64(DN_Arena *arena, DN_U64 number, uint32_t flags)
|
||||
{
|
||||
DN_Str8 prefix = {};
|
||||
if ((flags & DN_CVTU64HexStrFlags_0xPrefix))
|
||||
prefix = DN_STR8("0x");
|
||||
|
||||
char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x";
|
||||
DN_USize required_size = DN_CStr8_FSize(fmt, number) + prefix.size;
|
||||
DN_Str8 result = DN_Str8_Alloc(arena, required_size, DN_ZeroMem_No);
|
||||
|
||||
if (DN_Str8_HasData(result)) {
|
||||
DN_Memcpy(result.data, prefix.data, prefix.size);
|
||||
int space = DN_CAST(int) DN_Max((result.size - prefix.size) + 1, 0); /*null-terminator*/
|
||||
DN_SNPrintF(result.data + prefix.size, space, fmt, number);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str8(DN_U64 number, DN_CVTU64HexStrFlags flags)
|
||||
{
|
||||
DN_Str8 prefix = {};
|
||||
if (flags & DN_CVTU64HexStrFlags_0xPrefix)
|
||||
prefix = DN_STR8("0x");
|
||||
|
||||
DN_CVTU64HexStr result = {};
|
||||
DN_Memcpy(result.data, prefix.data, prefix.size);
|
||||
result.size += DN_CAST(int8_t) prefix.size;
|
||||
|
||||
char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x";
|
||||
int size = DN_SNPrintF(result.data + result.size, DN_ArrayCountU(result.data) - result.size, fmt, number);
|
||||
result.size += DN_CAST(uint8_t) size;
|
||||
DN_Assert(result.size < DN_ArrayCountU(result.data));
|
||||
|
||||
// NOTE: snprintf returns the required size of the format string
|
||||
// irrespective of if there's space or not, but, always null terminates so
|
||||
// the last byte is wasted.
|
||||
result.size = DN_Min(result.size, DN_ArrayCountU(result.data) - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_CVT_HexFromBytesPtr(void const *src, DN_USize src_size, char *dest, DN_USize dest_size)
|
||||
{
|
||||
if (!src || !dest)
|
||||
return false;
|
||||
|
||||
if (!DN_Check(dest_size >= src_size * 2))
|
||||
return false;
|
||||
|
||||
char const *HEX = "0123456789abcdef";
|
||||
unsigned char const *src_u8 = DN_CAST(unsigned char const *) src;
|
||||
for (DN_USize src_index = 0, dest_index = 0; src_index < src_size; src_index++) {
|
||||
char byte = src_u8[src_index];
|
||||
char hex01 = (byte >> 4) & 0b1111;
|
||||
char hex02 = (byte >> 0) & 0b1111;
|
||||
dest[dest_index++] = HEX[(int)hex01];
|
||||
dest[dest_index++] = HEX[(int)hex02];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_HexFromBytes(DN_Arena *arena, void const *src, DN_USize size)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!src || size <= 0)
|
||||
return result;
|
||||
|
||||
result = DN_Str8_Alloc(arena, size * 2, DN_ZeroMem_No);
|
||||
result.data[result.size] = 0;
|
||||
bool converted = DN_CVT_HexFromBytesPtr(src, size, result.data, result.size);
|
||||
DN_Assert(converted);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked(DN_Str8 hex, void *dest, DN_USize dest_size)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
unsigned char *dest_u8 = DN_CAST(unsigned char *) dest;
|
||||
|
||||
for (DN_USize hex_index = 0; hex_index < hex.size; hex_index += 2, result += 1) {
|
||||
char hex01 = hex.data[hex_index];
|
||||
char hex02 = (hex_index + 1 < hex.size) ? hex.data[hex_index + 1] : 0;
|
||||
char bit4_01 = DN_CVT_U8FromHexNibble(hex01);
|
||||
char bit4_02 = DN_CVT_U8FromHexNibble(hex02);
|
||||
char byte = (bit4_01 << 4) | (bit4_02 << 0);
|
||||
dest_u8[result] = byte;
|
||||
}
|
||||
|
||||
DN_Assert(result <= dest_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtr(DN_Str8 hex, void *dest, DN_USize dest_size)
|
||||
{
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x"));
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X"));
|
||||
|
||||
DN_USize result = 0;
|
||||
if (!DN_Str8_HasData(hex))
|
||||
return result;
|
||||
|
||||
// NOTE: Trimmed hex can be "0xf" -> "f" or "0xAB" -> "AB"
|
||||
// Either way, the size can be odd or even, hence we round up to the nearest
|
||||
// multiple of two to ensure that we calculate the min buffer size orrectly.
|
||||
DN_USize hex_size_rounded_up = hex.size + (hex.size % 2);
|
||||
DN_USize min_buffer_size = hex_size_rounded_up / 2;
|
||||
if (hex.size <= 0 || !DN_Check(dest_size >= min_buffer_size))
|
||||
return result;
|
||||
|
||||
result = DN_CVT_BytesFromHexPtrUnchecked(hex, dest, dest_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked(DN_Arena *arena, DN_Str8 hex)
|
||||
{
|
||||
DN_USize hex_size_rounded_up = hex.size + (hex.size % 2);
|
||||
DN_Str8 result = DN_Str8_Alloc(arena, (hex_size_rounded_up / 2), DN_ZeroMem_No);
|
||||
if (result.data) {
|
||||
DN_USize bytes_written = DN_CVT_BytesFromHexPtr(hex, result.data, result.size);
|
||||
DN_Assert(bytes_written == result.size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHex(DN_Arena *arena, DN_Str8 hex)
|
||||
{
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x"));
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X"));
|
||||
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Str8_HasData(hex))
|
||||
return result;
|
||||
|
||||
if (!DN_Check(DN_Str8_IsAll(hex, DN_Str8IsAll_Hex)))
|
||||
return result;
|
||||
|
||||
result = DN_CVT_BytesFromHexUnchecked(arena, hex);
|
||||
return result;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
#if !defined(DN_BASE_CONVERT_H)
|
||||
#define DN_BASE_CONVERT_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
struct DN_CVTU64Str8
|
||||
{
|
||||
char data[27 + 1]; // NOTE(dn): 27 is the maximum size of DN_U64 including a separator
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
enum DN_CVTBytesType
|
||||
{
|
||||
DN_CVTBytesType_B,
|
||||
DN_CVTBytesType_KiB,
|
||||
DN_CVTBytesType_MiB,
|
||||
DN_CVTBytesType_GiB,
|
||||
DN_CVTBytesType_TiB,
|
||||
DN_CVTBytesType_Count,
|
||||
DN_CVTBytesType_Auto,
|
||||
};
|
||||
|
||||
struct DN_CVTU64Bytes
|
||||
{
|
||||
DN_CVTBytesType type;
|
||||
DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c
|
||||
DN_F64 bytes;
|
||||
};
|
||||
|
||||
struct DN_CVTU64HexStr
|
||||
{
|
||||
char data[2 /*0x*/ + 16 /*hex*/ + 1 /*null-terminator*/];
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_CVTU64HexStrFlags;
|
||||
enum DN_CVTU64HexStrFlags_
|
||||
{
|
||||
DN_CVTU64HexStrFlags_Nil = 0,
|
||||
DN_CVTU64HexStrFlags_0xPrefix = 1 << 0, /// Add the '0x' prefix from the string
|
||||
DN_CVTU64HexStrFlags_UppercaseHex = 1 << 1, /// Use uppercase ascii characters for hex
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_CVTU64AgeUnit;
|
||||
enum DN_CVTU64AgeUnit_
|
||||
{
|
||||
DN_CVTU64AgeUnit_Sec = 1 << 0,
|
||||
DN_CVTU64AgeUnit_Min = 1 << 1,
|
||||
DN_CVTU64AgeUnit_Hr = 1 << 2,
|
||||
DN_CVTU64AgeUnit_Day = 1 << 3,
|
||||
DN_CVTU64AgeUnit_Week = 1 << 4,
|
||||
DN_CVTU64AgeUnit_Year = 1 << 5,
|
||||
DN_CVTU64AgeUnit_HMS = DN_CVTU64AgeUnit_Sec | DN_CVTU64AgeUnit_Min | DN_CVTU64AgeUnit_Hr,
|
||||
DN_CVTU64AgeUnit_All = DN_CVTU64AgeUnit_HMS | DN_CVTU64AgeUnit_Day | DN_CVTU64AgeUnit_Week | DN_CVTU64AgeUnit_Year,
|
||||
};
|
||||
|
||||
struct DN_NibbleFromU8Result
|
||||
{
|
||||
char nibble0;
|
||||
char nibble1;
|
||||
};
|
||||
|
||||
DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8 (DN_U8 u8);
|
||||
DN_API DN_U8 DN_CVT_U8FromHexNibble (char hex);
|
||||
|
||||
DN_API int DN_CVT_FmtBuffer3DotTruncate (char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64 (DN_U64 val, char separator);
|
||||
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type);
|
||||
#define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto)
|
||||
DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type);
|
||||
#define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type)
|
||||
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
|
||||
#define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto)
|
||||
#define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type)
|
||||
#define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto)
|
||||
DN_API DN_Str8 DN_CVT_BytesTypeToStr8 (DN_CVTBytesType type);
|
||||
DN_API DN_Str8 DN_CVT_AgeFromU64 (DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit);
|
||||
DN_API DN_Str8 DN_CVT_AgeFromF64 (DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit);
|
||||
|
||||
DN_API DN_U64 DN_CVT_U64FromHex (DN_Str8 hex);
|
||||
DN_API DN_Str8 DN_CVT_HexFromU64 (DN_Arena *arena, DN_U64 number, DN_CVTU64HexStrFlags flags);
|
||||
#define DN_CVT_HexFromU64Frame(number, flags) DN_CVT_HexFromU64(DN_OS_TLSFrameArena(), number, flags)
|
||||
DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str (DN_U64 number, DN_CVTU64HexStrFlags flags);
|
||||
|
||||
DN_API bool DN_CVT_HexFromBytesPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_HexFromBytes (DN_Arena *arena, void const *src, DN_USize size);
|
||||
#define DN_CVT_HexFromBytesTLS(...) DN_CVT_HexFromBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#define DN_CVT_HexFromBytesFrame(...) DN_CVT_HexFromBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_BytesFromHexUncheckedFromTLS(...) DN_CVT_BytesFromHexUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHex (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_BytesFromHexFrame(...) DN_CVT_BytesFromHex(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
#define DN_CVT_BytesFromHexTLS(...) DN_CVT_BytesFromHex(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#endif // defined(DN_BASE_CONVERT_H)
|
||||
+14
-14
@@ -23,9 +23,9 @@ DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType colour, DN_U8
|
||||
|
||||
DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromU32(DN_LOGColourType colour, DN_U32 value)
|
||||
{
|
||||
DN_U8 r = DN_CAST(DN_U8)(value >> 24);
|
||||
DN_U8 g = DN_CAST(DN_U8)(value >> 16);
|
||||
DN_U8 b = DN_CAST(DN_U8)(value >> 8);
|
||||
DN_U8 r = DN_Cast(DN_U8)(value >> 24);
|
||||
DN_U8 g = DN_Cast(DN_U8)(value >> 16);
|
||||
DN_U8 b = DN_Cast(DN_U8)(value >> 8);
|
||||
DN_Str8 result = DN_LOG_ColourEscapeCodeStr8FromRGB(colour, r, g, b);
|
||||
return result;
|
||||
}
|
||||
@@ -35,35 +35,35 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ
|
||||
DN_Str8 type_str8 = type.str8;
|
||||
if (type.is_u32_enum) {
|
||||
switch (type.u32) {
|
||||
case DN_LOGType_Debug: type_str8 = DN_STR8("DEBUG"); break;
|
||||
case DN_LOGType_Info: type_str8 = DN_STR8("INFO "); break;
|
||||
case DN_LOGType_Warning: type_str8 = DN_STR8("WARN"); break;
|
||||
case DN_LOGType_Error: type_str8 = DN_STR8("ERROR"); break;
|
||||
case DN_LOGType_Count: type_str8 = DN_STR8("BADXX"); break;
|
||||
case DN_LOGType_Debug: type_str8 = DN_Str8Lit("DEBUG"); break;
|
||||
case DN_LOGType_Info: type_str8 = DN_Str8Lit("INFO "); break;
|
||||
case DN_LOGType_Warning: type_str8 = DN_Str8Lit("WARN"); break;
|
||||
case DN_LOGType_Error: type_str8 = DN_Str8Lit("ERROR"); break;
|
||||
case DN_LOGType_Count: type_str8 = DN_Str8Lit("BADXX"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static DN_USize max_type_length = 0;
|
||||
max_type_length = DN_Max(max_type_length, type_str8.size);
|
||||
int type_padding = DN_CAST(int)(max_type_length - type_str8.size);
|
||||
int type_padding = DN_Cast(int)(max_type_length - type_str8.size);
|
||||
|
||||
DN_Str8 colour_esc = {};
|
||||
DN_Str8 bold_esc = {};
|
||||
DN_Str8 reset_esc = {};
|
||||
if (style.colour) {
|
||||
bold_esc = DN_STR8(DN_LOG_BoldEscapeCode);
|
||||
reset_esc = DN_STR8(DN_LOG_ResetEscapeCode);
|
||||
bold_esc = DN_Str8Lit(DN_LOG_BoldEscapeCode);
|
||||
reset_esc = DN_Str8Lit(DN_LOG_ResetEscapeCode);
|
||||
colour_esc = DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b);
|
||||
}
|
||||
|
||||
DN_Str8 file_name = DN_Str8_FileNameFromPath(call_site.file);
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(call_site.file);
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wformat)
|
||||
DN_GCC_WARNING_DISABLE(-Wformat-extra-args)
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4477)
|
||||
int size = DN_SNPrintF(dest,
|
||||
DN_CAST(int)dest_size,
|
||||
DN_Cast(int)dest_size,
|
||||
"%04u-%02u-%02uT%02u:%02u:%02u" // date
|
||||
"%S" // colour
|
||||
"%S" // bold
|
||||
@@ -82,7 +82,7 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ
|
||||
colour_esc, // colour
|
||||
bold_esc, // bold
|
||||
type_str8, // type
|
||||
DN_CAST(int) type_padding,
|
||||
DN_Cast(int) type_padding,
|
||||
"", // type padding
|
||||
reset_esc, // reset
|
||||
file_name, // file name
|
||||
|
||||
@@ -2,553 +2,3 @@
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
static DN_ArenaBlock *DN_Arena_BlockFromMemFuncs_(DN_U64 reserve, DN_U64 commit, bool track_alloc, bool alloc_can_leak, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
DN_ArenaBlock *result = nullptr;
|
||||
switch (mem_funcs.type) {
|
||||
case DN_ArenaMemFuncType_Nil:
|
||||
break;
|
||||
|
||||
case DN_ArenaMemFuncType_Basic: {
|
||||
DN_AssertF(reserve > DN_ARENA_HEADER_SIZE, "%I64u > %I64u", reserve, DN_ARENA_HEADER_SIZE);
|
||||
result = DN_CAST(DN_ArenaBlock *) mem_funcs.basic_alloc(reserve);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
result->used = DN_ARENA_HEADER_SIZE;
|
||||
result->commit = reserve;
|
||||
result->reserve = reserve;
|
||||
} break;
|
||||
|
||||
case DN_ArenaMemFuncType_VMem: {
|
||||
DN_AssertF(mem_funcs.vmem_page_size, "Page size must be set to a non-zero, power of two value");
|
||||
DN_Assert(DN_IsPowerOfTwo(mem_funcs.vmem_page_size));
|
||||
|
||||
DN_USize const page_size = mem_funcs.vmem_page_size;
|
||||
DN_U64 real_reserve = reserve ? reserve : DN_ARENA_RESERVE_SIZE;
|
||||
DN_U64 real_commit = commit ? commit : DN_ARENA_COMMIT_SIZE;
|
||||
real_reserve = DN_AlignUpPowerOfTwo(real_reserve, page_size);
|
||||
real_commit = DN_Min(DN_AlignUpPowerOfTwo(real_commit, page_size), real_reserve);
|
||||
DN_AssertF(DN_ARENA_HEADER_SIZE < real_commit && real_commit <= real_reserve, "%I64u < %I64u <= %I64u", DN_ARENA_HEADER_SIZE, real_commit, real_reserve);
|
||||
|
||||
DN_MemCommit mem_commit = real_reserve == real_commit ? DN_MemCommit_Yes : DN_MemCommit_No;
|
||||
result = DN_CAST(DN_ArenaBlock *) mem_funcs.vmem_reserve(real_reserve, mem_commit, DN_MemPage_ReadWrite);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
if (mem_commit == DN_MemCommit_No && !mem_funcs.vmem_commit(result, real_commit, DN_MemPage_ReadWrite)) {
|
||||
mem_funcs.vmem_release(result, real_reserve);
|
||||
return result;
|
||||
}
|
||||
|
||||
result->used = DN_ARENA_HEADER_SIZE;
|
||||
result->commit = real_commit;
|
||||
result->reserve = real_reserve;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (track_alloc && result)
|
||||
DN_DBGTrackAlloc(result, result->reserve, alloc_can_leak);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DN_ArenaBlock *DN_Arena_BlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0;
|
||||
bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak;
|
||||
DN_ArenaBlock *result = DN_Arena_BlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs);
|
||||
if (result && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_Arena_UpdateStatsOnNewBlock_(DN_Arena *arena, DN_ArenaBlock const *block)
|
||||
{
|
||||
DN_Assert(arena);
|
||||
if (block) {
|
||||
arena->stats.info.used += block->used;
|
||||
arena->stats.info.commit += block->commit;
|
||||
arena->stats.info.reserve += block->reserve;
|
||||
arena->stats.info.blocks += 1;
|
||||
|
||||
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
|
||||
arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit);
|
||||
arena->stats.hwm.reserve = DN_Max(arena->stats.hwm.reserve, arena->stats.info.reserve);
|
||||
arena->stats.hwm.blocks = DN_Max(arena->stats.hwm.blocks, arena->stats.info.blocks);
|
||||
}
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromBuffer(void *buffer, DN_USize size, DN_ArenaFlags flags)
|
||||
{
|
||||
DN_Assert(buffer);
|
||||
DN_AssertF(DN_ARENA_HEADER_SIZE < size, "Buffer (%zu bytes) too small, need atleast %zu bytes to store arena metadata", size, DN_ARENA_HEADER_SIZE);
|
||||
DN_AssertF(DN_IsPowerOfTwo(size), "Buffer (%zu bytes) must be a power-of-two", size);
|
||||
|
||||
// NOTE: Init block
|
||||
DN_ArenaBlock *block = DN_CAST(DN_ArenaBlock *) buffer;
|
||||
block->commit = size;
|
||||
block->reserve = size;
|
||||
block->used = DN_ARENA_HEADER_SIZE;
|
||||
if (block && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE);
|
||||
|
||||
DN_Arena result = {};
|
||||
result.flags = flags | DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_UserBuffer;
|
||||
result.curr = block;
|
||||
DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromMemFuncs(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
DN_Arena result = {};
|
||||
result.flags = flags;
|
||||
result.mem_funcs = mem_funcs;
|
||||
result.flags |= DN_ArenaFlags_MemFuncs;
|
||||
result.curr = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, flags, mem_funcs);
|
||||
DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_Arena_BlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block)
|
||||
{
|
||||
DN_USize release_size = block->reserve;
|
||||
if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack))
|
||||
DN_DBGTrackDealloc(block);
|
||||
DN_ASanUnpoisonMemoryRegion(block, block->commit);
|
||||
if (arena->flags & DN_ArenaFlags_MemFuncs) {
|
||||
if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic)
|
||||
arena->mem_funcs.basic_dealloc(block);
|
||||
else
|
||||
arena->mem_funcs.vmem_release(block, release_size);
|
||||
}
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Deinit(DN_Arena *arena)
|
||||
{
|
||||
for (DN_ArenaBlock *block = arena ? arena->curr : nullptr; block;) {
|
||||
DN_ArenaBlock *block_to_free = block;
|
||||
block = block->prev;
|
||||
DN_Arena_BlockDeinit_(arena, block_to_free);
|
||||
}
|
||||
if (arena)
|
||||
*arena = {};
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_CommitTo(DN_Arena *arena, DN_U64 pos)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return false;
|
||||
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
if (pos <= curr->commit)
|
||||
return true;
|
||||
|
||||
DN_U64 real_pos = pos;
|
||||
if (!DN_Check(pos <= curr->reserve))
|
||||
real_pos = curr->reserve;
|
||||
|
||||
DN_Assert(arena->mem_funcs.vmem_page_size);
|
||||
DN_USize end_commit = DN_AlignUpPowerOfTwo(real_pos, arena->mem_funcs.vmem_page_size);
|
||||
DN_USize commit_size = end_commit - curr->commit;
|
||||
char *commit_ptr = DN_CAST(char *) curr + curr->commit;
|
||||
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
|
||||
return false;
|
||||
|
||||
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0);
|
||||
if (poison)
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
|
||||
curr->commit = end_commit;
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_Commit(DN_Arena *arena, DN_U64 size)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return false;
|
||||
DN_U64 pos = DN_Min(arena->curr->reserve, arena->curr->commit + size);
|
||||
bool result = DN_Arena_CommitTo(arena, pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_Grow(DN_Arena *arena, DN_U64 reserve, DN_U64 commit)
|
||||
{
|
||||
if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer))
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
DN_ArenaBlock *new_block = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, arena->flags, arena->mem_funcs);
|
||||
if (new_block) {
|
||||
result = true;
|
||||
new_block->prev = arena->curr;
|
||||
arena->curr = new_block;
|
||||
new_block->reserve_sum = new_block->prev->reserve_sum + new_block->prev->reserve;
|
||||
DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_Alloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem)
|
||||
{
|
||||
if (!arena)
|
||||
return nullptr;
|
||||
|
||||
if (!arena->curr) {
|
||||
arena->curr = DN_Arena_BlockFlagsFromMemFuncs_(DN_ARENA_RESERVE_SIZE, DN_ARENA_COMMIT_SIZE, arena->flags, arena->mem_funcs);
|
||||
DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr);
|
||||
}
|
||||
|
||||
if (!arena->curr)
|
||||
return nullptr;
|
||||
|
||||
try_alloc_again:
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0);
|
||||
uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align;
|
||||
DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0);
|
||||
DN_U64 end_pos = offset_pos + size;
|
||||
DN_U64 alloc_size = end_pos - curr->used;
|
||||
|
||||
if (end_pos > curr->reserve) {
|
||||
if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer))
|
||||
return nullptr;
|
||||
DN_USize new_reserve = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_RESERVE_SIZE);
|
||||
DN_USize new_commit = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_COMMIT_SIZE);
|
||||
if (!DN_Arena_Grow(arena, new_reserve, new_commit))
|
||||
return nullptr;
|
||||
goto try_alloc_again;
|
||||
}
|
||||
|
||||
DN_USize prev_arena_commit = curr->commit;
|
||||
if (end_pos > curr->commit) {
|
||||
DN_Assert(arena->mem_funcs.vmem_page_size);
|
||||
DN_Assert(arena->mem_funcs.type == DN_ArenaMemFuncType_VMem);
|
||||
DN_Assert((arena->flags & DN_ArenaFlags_UserBuffer) == 0);
|
||||
DN_USize end_commit = DN_AlignUpPowerOfTwo(end_pos, arena->mem_funcs.vmem_page_size);
|
||||
DN_USize commit_size = end_commit - curr->commit;
|
||||
char *commit_ptr = DN_CAST(char *) curr + curr->commit;
|
||||
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
|
||||
return nullptr;
|
||||
if (poison)
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
curr->commit = end_commit;
|
||||
arena->stats.info.commit += commit_size;
|
||||
arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit);
|
||||
}
|
||||
|
||||
void *result = DN_CAST(char *) curr + offset_pos;
|
||||
curr->used += alloc_size;
|
||||
arena->stats.info.used += alloc_size;
|
||||
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
|
||||
DN_ASanUnpoisonMemoryRegion(result, size);
|
||||
|
||||
if (zero_mem == DN_ZeroMem_Yes) {
|
||||
DN_USize reused_bytes = DN_Min(prev_arena_commit - offset_pos, size);
|
||||
DN_Memset(result, 0, reused_bytes);
|
||||
}
|
||||
|
||||
DN_Assert(arena->stats.hwm.used >= arena->stats.info.used);
|
||||
DN_Assert(arena->stats.hwm.commit >= arena->stats.info.commit);
|
||||
DN_Assert(arena->stats.hwm.reserve >= arena->stats.info.reserve);
|
||||
DN_Assert(arena->stats.hwm.blocks >= arena->stats.info.blocks);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_AllocContiguous(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem)
|
||||
{
|
||||
DN_ArenaFlags prev_flags = arena->flags;
|
||||
arena->flags |= (DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoPoison);
|
||||
void *memory = DN_Arena_Alloc(arena, size, align, zero_mem);
|
||||
arena->flags = prev_flags;
|
||||
return memory;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_Copy(DN_Arena *arena, void const *data, DN_U64 size, uint8_t align)
|
||||
{
|
||||
if (!arena || !data || size == 0)
|
||||
return nullptr;
|
||||
void *result = DN_Arena_Alloc(arena, size, align, DN_ZeroMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_PopTo(DN_Arena *arena, DN_U64 init_used)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return;
|
||||
DN_U64 used = DN_Max(DN_ARENA_HEADER_SIZE, init_used);
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
while (curr->reserve_sum >= used) {
|
||||
DN_ArenaBlock *block_to_free = curr;
|
||||
arena->stats.info.used -= block_to_free->used;
|
||||
arena->stats.info.commit -= block_to_free->commit;
|
||||
arena->stats.info.reserve -= block_to_free->reserve;
|
||||
arena->stats.info.blocks -= 1;
|
||||
if (arena->flags & DN_ArenaFlags_UserBuffer)
|
||||
break;
|
||||
curr = curr->prev;
|
||||
DN_Arena_BlockDeinit_(arena, block_to_free);
|
||||
}
|
||||
|
||||
arena->stats.info.used -= curr->used;
|
||||
arena->curr = curr;
|
||||
curr->used = used - curr->reserve_sum;
|
||||
char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT);
|
||||
DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr;
|
||||
DN_ASanPoisonMemoryRegion(poison_ptr, poison_size);
|
||||
arena->stats.info.used += curr->used;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Pop(DN_Arena *arena, DN_U64 amount)
|
||||
{
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
DN_USize used_sum = curr->reserve_sum + curr->used;
|
||||
if (!DN_Check(amount <= used_sum))
|
||||
amount = used_sum;
|
||||
DN_USize pop_to = used_sum - amount;
|
||||
DN_Arena_PopTo(arena, pop_to);
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_Arena_Pos(DN_Arena const *arena)
|
||||
{
|
||||
DN_U64 result = (arena && arena->curr) ? arena->curr->reserve_sum + arena->curr->used : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Clear(DN_Arena *arena)
|
||||
{
|
||||
DN_Arena_PopTo(arena, 0);
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_OwnsPtr(DN_Arena const *arena, void *ptr)
|
||||
{
|
||||
bool result = false;
|
||||
uintptr_t uint_ptr = DN_CAST(uintptr_t) ptr;
|
||||
for (DN_ArenaBlock const *block = arena ? arena->curr : nullptr; !result && block; block = block->prev) {
|
||||
uintptr_t begin = DN_CAST(uintptr_t) block + DN_ARENA_HEADER_SIZE;
|
||||
uintptr_t end = begin + block->reserve;
|
||||
result = uint_ptr >= begin && uint_ptr <= end;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray(DN_ArenaStats const *array, DN_USize size)
|
||||
{
|
||||
DN_ArenaStats result = {};
|
||||
for (DN_ForItSize(it, DN_ArenaStats const, array, size)) {
|
||||
DN_ArenaStats stats = *it.data;
|
||||
result.info.used += stats.info.used;
|
||||
result.info.commit += stats.info.commit;
|
||||
result.info.reserve += stats.info.reserve;
|
||||
result.info.blocks += stats.info.blocks;
|
||||
|
||||
result.hwm.used = DN_Max(result.hwm.used, result.info.used);
|
||||
result.hwm.commit = DN_Max(result.hwm.commit, result.info.commit);
|
||||
result.hwm.reserve = DN_Max(result.hwm.reserve, result.info.reserve);
|
||||
result.hwm.blocks = DN_Max(result.hwm.blocks, result.info.blocks);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats(DN_ArenaStats lhs, DN_ArenaStats rhs)
|
||||
{
|
||||
DN_ArenaStats array[] = {lhs, rhs};
|
||||
DN_ArenaStats result = DN_Arena_SumStatsArray(array, DN_ArrayCountU(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats(DN_Arena const *array, DN_USize size)
|
||||
{
|
||||
DN_ArenaStats result = {};
|
||||
for (DN_USize index = 0; index < size; index++) {
|
||||
DN_Arena const *arena = array + index;
|
||||
result = DN_Arena_SumStats(result, arena->stats);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin(DN_Arena *arena)
|
||||
{
|
||||
DN_ArenaTempMem result = {};
|
||||
if (arena) {
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
result = {arena, curr ? curr->reserve_sum + curr->used : 0};
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
DN_API void DN_Arena_TempMemEnd(DN_ArenaTempMem mem)
|
||||
{
|
||||
DN_Arena_PopTo(mem.arena, mem.used_sum);
|
||||
};
|
||||
|
||||
DN_ArenaTempMemScope::DN_ArenaTempMemScope(DN_Arena *arena)
|
||||
{
|
||||
mem = DN_Arena_TempMemBegin(arena);
|
||||
}
|
||||
|
||||
DN_ArenaTempMemScope::~DN_ArenaTempMemScope()
|
||||
{
|
||||
DN_Arena_TempMemEnd(mem);
|
||||
}
|
||||
|
||||
// NOTE: DN_Pool ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Pool DN_Pool_FromArena(DN_Arena *arena, uint8_t align)
|
||||
{
|
||||
DN_Pool result = {};
|
||||
if (arena) {
|
||||
result.arena = arena;
|
||||
result.align = align ? align : DN_POOL_DEFAULT_ALIGN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_Pool_IsValid(DN_Pool const *pool)
|
||||
{
|
||||
bool result = pool && pool->arena && pool->align;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Pool_Alloc(DN_Pool *pool, DN_USize size)
|
||||
{
|
||||
void *result = nullptr;
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
DN_USize const required_size = sizeof(DN_PoolSlot) + pool->align + size;
|
||||
DN_USize const size_to_slot_offset = 5; // __lzcnt64(32) e.g. DN_PoolSlotSize_32B
|
||||
DN_USize slot_index = 0;
|
||||
if (required_size > 32) {
|
||||
// NOTE: Round up if not PoT as the low bits are set.
|
||||
DN_USize dist_to_next_msb = DN_CountLeadingZerosUSize(required_size) + 1;
|
||||
dist_to_next_msb -= DN_CAST(DN_USize)(!DN_IsPowerOfTwo(required_size));
|
||||
|
||||
DN_USize const register_size = sizeof(DN_USize) * 8;
|
||||
DN_AssertF(register_size >= (dist_to_next_msb - size_to_slot_offset), "lhs=%zu, rhs=%zu", register_size, (dist_to_next_msb - size_to_slot_offset));
|
||||
slot_index = register_size - dist_to_next_msb - size_to_slot_offset;
|
||||
}
|
||||
|
||||
if (!DN_CheckF(slot_index < DN_PoolSlotSize_Count, "Chunk pool does not support the requested allocation size"))
|
||||
return result;
|
||||
|
||||
DN_USize slot_size_in_bytes = 1ULL << (slot_index + size_to_slot_offset);
|
||||
DN_AssertF(required_size <= (slot_size_in_bytes << 0), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes << 0));
|
||||
DN_AssertF(required_size >= (slot_size_in_bytes >> 1), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes >> 1));
|
||||
|
||||
DN_PoolSlot *slot = nullptr;
|
||||
if (pool->slots[slot_index]) {
|
||||
slot = pool->slots[slot_index];
|
||||
pool->slots[slot_index] = slot->next;
|
||||
DN_Memset(slot->data, 0, size);
|
||||
DN_Assert(DN_IsPowerOfTwoAligned(slot->data, pool->align));
|
||||
} else {
|
||||
void *bytes = DN_Arena_Alloc(pool->arena, slot_size_in_bytes, alignof(DN_PoolSlot), DN_ZeroMem_Yes);
|
||||
slot = DN_CAST(DN_PoolSlot *) bytes;
|
||||
|
||||
// NOTE: The raw pointer is round up to the next 'pool->align'-ed
|
||||
// address ensuring at least 1 byte of padding between the raw pointer
|
||||
// and the pointer given to the user and that the user pointer is
|
||||
// aligned to the pool's alignment.
|
||||
//
|
||||
// This allows us to smuggle 1 byte behind the user pointer that has
|
||||
// the offset to the original pointer.
|
||||
slot->data = DN_CAST(void *) DN_AlignDownPowerOfTwo(DN_CAST(uintptr_t) slot + sizeof(DN_PoolSlot) + pool->align, pool->align);
|
||||
|
||||
uintptr_t offset_to_original_ptr = DN_CAST(uintptr_t) slot->data - DN_CAST(uintptr_t) bytes;
|
||||
DN_Assert(slot->data > bytes);
|
||||
DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align);
|
||||
|
||||
// NOTE: Store the offset to the original pointer behind the user's
|
||||
// pointer.
|
||||
char *offset_to_original_storage = DN_CAST(char *) slot->data - 1;
|
||||
DN_Memcpy(offset_to_original_storage, &offset_to_original_ptr, 1);
|
||||
}
|
||||
|
||||
// NOTE: Smuggle the slot type in the next pointer so that we know, when the
|
||||
// pointer gets returned which free list to return the pointer to.
|
||||
result = slot->data;
|
||||
slot->next = DN_CAST(DN_PoolSlot *) slot_index;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
DN_USize size_required = DN_CStr8_FVSize(fmt, args);
|
||||
result.data = DN_CAST(char *) DN_Pool_Alloc(pool, size_required + 1);
|
||||
if (result.data) {
|
||||
result.size = size_required;
|
||||
DN_VSNPrintF(result.data, DN_CAST(int)(result.size + 1), fmt, args);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Pool_AllocStr8FV(pool, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy(DN_Pool *pool, DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
if (!DN_Str8_HasData(string))
|
||||
return result;
|
||||
|
||||
char *data = DN_CAST(char *) DN_Pool_Alloc(pool, string.size + 1);
|
||||
if (!data)
|
||||
return result;
|
||||
|
||||
DN_Memcpy(data, string.data, string.size);
|
||||
data[string.size] = 0;
|
||||
result = DN_Str8_Init(data, string.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Pool_Dealloc(DN_Pool *pool, void *ptr)
|
||||
{
|
||||
if (!DN_Pool_IsValid(pool) || !ptr)
|
||||
return;
|
||||
|
||||
DN_Assert(DN_Arena_OwnsPtr(pool->arena, ptr));
|
||||
|
||||
char const *one_byte_behind_ptr = DN_CAST(char *) ptr - 1;
|
||||
DN_USize offset_to_original_ptr = 0;
|
||||
DN_Memcpy(&offset_to_original_ptr, one_byte_behind_ptr, 1);
|
||||
DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align);
|
||||
|
||||
char *original_ptr = DN_CAST(char *) ptr - offset_to_original_ptr;
|
||||
DN_PoolSlot *slot = DN_CAST(DN_PoolSlot *) original_ptr;
|
||||
DN_PoolSlotSize slot_index = DN_CAST(DN_PoolSlotSize)(DN_CAST(uintptr_t) slot->next);
|
||||
DN_Assert(slot_index < DN_PoolSlotSize_Count);
|
||||
|
||||
slot->next = pool->slots[slot_index];
|
||||
pool->slots[slot_index] = slot;
|
||||
}
|
||||
|
||||
DN_API void *DN_Pool_Copy(DN_Pool *pool, void const *data, DN_U64 size, uint8_t align)
|
||||
{
|
||||
if (!pool || !data || size == 0)
|
||||
return nullptr;
|
||||
|
||||
// TODO: Hmm should align be part of the alloc interface in general? I'm not going to worry
|
||||
// about this until we crash because of misalignment.
|
||||
DN_Assert(pool->align >= align);
|
||||
|
||||
void *result = DN_Pool_Alloc(pool, size);
|
||||
if (result)
|
||||
DN_Memcpy(result, data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3,244 +3,4 @@
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
enum DN_MemCommit
|
||||
{
|
||||
DN_MemCommit_No,
|
||||
DN_MemCommit_Yes,
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_MemPage;
|
||||
enum DN_MemPage_
|
||||
{
|
||||
// Exception on read/write with a page. This flag overrides the read/write
|
||||
// access.
|
||||
DN_MemPage_NoAccess = 1 << 0,
|
||||
|
||||
DN_MemPage_Read = 1 << 1, // Only read permitted on the page.
|
||||
|
||||
// Only write permitted on the page. On Windows this is not supported and
|
||||
// will be promoted to read+write permissions.
|
||||
DN_MemPage_Write = 1 << 2,
|
||||
|
||||
DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write,
|
||||
|
||||
// Modifier used in conjunction with previous flags. Raises exception on
|
||||
// first access to the page, then, the underlying protection flags are
|
||||
// active. This is supported on Windows, on other OS's using this flag will
|
||||
// set the OS equivalent of DN_MemPage_NoAccess.
|
||||
// This flag must only be used in DN_Mem_Protect
|
||||
DN_MemPage_Guard = 1 << 3,
|
||||
|
||||
// If leak tracing is enabled, this flag will allow the allocation recorded
|
||||
// from the reserve call to be leaked, e.g. not printed when leaks are
|
||||
// dumped to the console.
|
||||
DN_MemPage_AllocRecordLeakPermitted = 1 << 4,
|
||||
|
||||
// If leak tracing is enabled this flag will prevent any allocation record
|
||||
// from being created in the allocation table at all. If this flag is
|
||||
// enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the
|
||||
// record will never be created.
|
||||
DN_MemPage_NoAllocRecordEntry = 1 << 5,
|
||||
|
||||
// [INTERNAL] Do not use. All flags together do not constitute a correct
|
||||
// configuration of pages.
|
||||
DN_MemPage_All = DN_MemPage_NoAccess |
|
||||
DN_MemPage_ReadWrite |
|
||||
DN_MemPage_Guard |
|
||||
DN_MemPage_AllocRecordLeakPermitted |
|
||||
DN_MemPage_NoAllocRecordEntry,
|
||||
};
|
||||
|
||||
#if !defined(DN_ARENA_RESERVE_SIZE)
|
||||
#define DN_ARENA_RESERVE_SIZE DN_Megabytes(64)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_ARENA_COMMIT_SIZE)
|
||||
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
|
||||
#endif
|
||||
|
||||
enum DN_Allocator
|
||||
{
|
||||
DN_Allocator_Arena,
|
||||
DN_Allocator_Pool,
|
||||
};
|
||||
|
||||
struct DN_ArenaBlock
|
||||
{
|
||||
DN_ArenaBlock *prev;
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 reserve_sum;
|
||||
};
|
||||
|
||||
typedef uint32_t DN_ArenaFlags;
|
||||
|
||||
enum DN_ArenaFlags_
|
||||
{
|
||||
DN_ArenaFlags_Nil = 0,
|
||||
DN_ArenaFlags_NoGrow = 1 << 0,
|
||||
DN_ArenaFlags_NoPoison = 1 << 1,
|
||||
DN_ArenaFlags_NoAllocTrack = 1 << 2,
|
||||
DN_ArenaFlags_AllocCanLeak = 1 << 3,
|
||||
|
||||
// NOTE: Internal flags. Do not use
|
||||
DN_ArenaFlags_UserBuffer = 1 << 4,
|
||||
DN_ArenaFlags_MemFuncs = 1 << 5,
|
||||
};
|
||||
|
||||
struct DN_ArenaInfo
|
||||
{
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 blocks;
|
||||
};
|
||||
|
||||
struct DN_ArenaStats
|
||||
{
|
||||
DN_ArenaInfo info;
|
||||
DN_ArenaInfo hwm;
|
||||
};
|
||||
|
||||
enum DN_ArenaMemFuncType
|
||||
{
|
||||
DN_ArenaMemFuncType_Nil,
|
||||
DN_ArenaMemFuncType_Basic,
|
||||
DN_ArenaMemFuncType_VMem,
|
||||
};
|
||||
|
||||
typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size);
|
||||
typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr);
|
||||
typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
|
||||
typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size);
|
||||
struct DN_ArenaMemFuncs
|
||||
{
|
||||
DN_ArenaMemFuncType type;
|
||||
DN_ArenaMemBasicAllocFunc *basic_alloc;
|
||||
DN_ArenaMemBasicDeallocFunc *basic_dealloc;
|
||||
|
||||
DN_U32 vmem_page_size;
|
||||
DN_ArenaMemVMemReserveFunc *vmem_reserve;
|
||||
DN_ArenaMemVMemCommitFunc *vmem_commit;
|
||||
DN_ArenaMemVMemReleaseFunc *vmem_release;
|
||||
};
|
||||
|
||||
struct DN_Arena
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs;
|
||||
DN_ArenaBlock *curr;
|
||||
DN_ArenaStats stats;
|
||||
DN_ArenaFlags flags;
|
||||
DN_Str8 label;
|
||||
DN_Arena *prev, *next;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMem
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_U64 used_sum;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMemScope
|
||||
{
|
||||
DN_ArenaTempMemScope(DN_Arena *arena);
|
||||
~DN_ArenaTempMemScope();
|
||||
DN_ArenaTempMem mem;
|
||||
};
|
||||
|
||||
DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64);
|
||||
|
||||
#if !defined(DN_POOL_DEFAULT_ALIGN)
|
||||
#define DN_POOL_DEFAULT_ALIGN 16
|
||||
#endif
|
||||
|
||||
struct DN_PoolSlot
|
||||
{
|
||||
void *data;
|
||||
DN_PoolSlot *next;
|
||||
};
|
||||
|
||||
enum DN_PoolSlotSize
|
||||
{
|
||||
DN_PoolSlotSize_32B,
|
||||
DN_PoolSlotSize_64B,
|
||||
DN_PoolSlotSize_128B,
|
||||
DN_PoolSlotSize_256B,
|
||||
DN_PoolSlotSize_512B,
|
||||
DN_PoolSlotSize_1KiB,
|
||||
DN_PoolSlotSize_2KiB,
|
||||
DN_PoolSlotSize_4KiB,
|
||||
DN_PoolSlotSize_8KiB,
|
||||
DN_PoolSlotSize_16KiB,
|
||||
DN_PoolSlotSize_32KiB,
|
||||
DN_PoolSlotSize_64KiB,
|
||||
DN_PoolSlotSize_128KiB,
|
||||
DN_PoolSlotSize_256KiB,
|
||||
DN_PoolSlotSize_512KiB,
|
||||
DN_PoolSlotSize_1MiB,
|
||||
DN_PoolSlotSize_2MiB,
|
||||
DN_PoolSlotSize_4MiB,
|
||||
DN_PoolSlotSize_8MiB,
|
||||
DN_PoolSlotSize_16MiB,
|
||||
DN_PoolSlotSize_32MiB,
|
||||
DN_PoolSlotSize_64MiB,
|
||||
DN_PoolSlotSize_128MiB,
|
||||
DN_PoolSlotSize_256MiB,
|
||||
DN_PoolSlotSize_512MiB,
|
||||
DN_PoolSlotSize_1GiB,
|
||||
DN_PoolSlotSize_2GiB,
|
||||
DN_PoolSlotSize_4GiB,
|
||||
DN_PoolSlotSize_8GiB,
|
||||
DN_PoolSlotSize_16GiB,
|
||||
DN_PoolSlotSize_32GiB,
|
||||
DN_PoolSlotSize_Count,
|
||||
};
|
||||
|
||||
struct DN_Pool
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_PoolSlot *slots[DN_PoolSlotSize_Count];
|
||||
DN_U8 align;
|
||||
};
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_Arena_FromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_Arena_Deinit (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_Commit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_Arena_CommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_Arena_Grow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_Arena_Alloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_AllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_Copy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_Arena_PopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_Arena_Pop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_Arena_Pos (DN_Arena const *arena);
|
||||
DN_API void DN_Arena_Clear (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_OwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats (DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_Arena_TempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_Arena_New_Frame(T, zero_mem) (T *)DN_Arena_Alloc(DN_OS_TLSGet()->frame_arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_New(arena, T, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewArray(arena, T, count, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T) * (count), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewCopy(arena, T, src) (T *)DN_Arena_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Arena_NewArrayCopy(arena, T, src, count) (T *)DN_Arena_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API DN_Pool DN_Pool_FromArena (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_Pool_IsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_Pool_Alloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API void DN_Pool_Dealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_Pool_Copy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
|
||||
#define DN_Pool_New(pool, T) (T *)DN_Pool_Alloc(pool, sizeof(T))
|
||||
#define DN_Pool_NewArray(pool, T, count) (T *)DN_Pool_Alloc(pool, count * sizeof(T))
|
||||
#define DN_Pool_NewCopy(arena, T, src) (T *)DN_Pool_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Pool_NewArrayCopy(arena, T, src, count) (T *)DN_Pool_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
#endif // !defined(DN_BASE_MEM_H)
|
||||
|
||||
@@ -34,12 +34,12 @@ struct DN_StackTraceWalkResultIterator
|
||||
|
||||
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_Walk(...)
|
||||
#define DN_StackTrace_WalkResultIterate(...)
|
||||
#define DN_StackTrace_WalkResultToStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkResultToStr8(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_WalkStr8(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_GetFrames(...)
|
||||
#define DN_StackTrace_RawFrameToFrame(...)
|
||||
#define DN_StackTrace_Print(...)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,244 +0,0 @@
|
||||
#if !defined(DN_BASE_STRING_H)
|
||||
#define DN_BASE_STRING_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
#if !defined(DN_STB_SPRINTF_HEADER_ONLY)
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#define STB_SPRINTF_STATIC
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4505) // Unused function warning
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wunused-function)
|
||||
#include "../External/stb_sprintf.h"
|
||||
DN_GCC_WARNING_POP
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__)
|
||||
#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__)
|
||||
#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__)
|
||||
#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__)
|
||||
|
||||
struct DN_Str8Link
|
||||
{
|
||||
DN_Str8 string; // The string
|
||||
DN_Str8Link *next; // The next string in the linked list
|
||||
DN_Str8Link *prev; // The prev string in the linked list
|
||||
};
|
||||
|
||||
struct DN_Str8BSplitResult
|
||||
{
|
||||
DN_Str8 lhs;
|
||||
DN_Str8 rhs;
|
||||
};
|
||||
|
||||
struct DN_Str8FindResult
|
||||
{
|
||||
bool found; // True if string was found. If false, the subsequent fields below are not set.
|
||||
DN_USize index; // Index in the buffer where the found string starts
|
||||
DN_Str8 match; // Matching string in the buffer that was searched
|
||||
DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer
|
||||
DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer
|
||||
DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it
|
||||
};
|
||||
|
||||
enum DN_Str8IsAll
|
||||
{
|
||||
DN_Str8IsAll_Digits,
|
||||
DN_Str8IsAll_Hex,
|
||||
};
|
||||
|
||||
enum DN_Str8EqCase
|
||||
{
|
||||
DN_Str8EqCase_Sensitive,
|
||||
DN_Str8EqCase_Insensitive,
|
||||
};
|
||||
|
||||
enum DN_Str8FindFlag
|
||||
{
|
||||
DN_Str8FindFlag_Digit = 1 << 0, // 0-9
|
||||
DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
|
||||
DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
|
||||
DN_Str8FindFlag_Plus = 1 << 3, // +
|
||||
DN_Str8FindFlag_Minus = 1 << 4, // -
|
||||
DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit,
|
||||
};
|
||||
|
||||
enum DN_Str8SplitIncludeEmptyStrings
|
||||
{
|
||||
DN_Str8SplitIncludeEmptyStrings_No,
|
||||
DN_Str8SplitIncludeEmptyStrings_Yes,
|
||||
};
|
||||
|
||||
struct DN_Str8ToU64Result
|
||||
{
|
||||
bool success;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
struct DN_Str8ToI64Result
|
||||
{
|
||||
bool success;
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
struct DN_Str8DotTruncateResult
|
||||
{
|
||||
bool truncated;
|
||||
DN_Str8 str8;
|
||||
};
|
||||
|
||||
struct DN_Str8Builder
|
||||
{
|
||||
DN_Arena *arena; // Allocator to use to back the string list
|
||||
DN_Str8Link *head; // First string in the linked list of strings
|
||||
DN_Str8Link *tail; // Last string in the linked list of strings
|
||||
DN_USize string_size; // The size in bytes necessary to construct the current string
|
||||
DN_USize count; // The number of links in the linked list of strings
|
||||
};
|
||||
|
||||
enum DN_Str8BuilderAdd
|
||||
{
|
||||
DN_Str8BuilderAdd_Append,
|
||||
DN_Str8BuilderAdd_Prepend,
|
||||
};
|
||||
|
||||
struct DN_Str8x64
|
||||
{
|
||||
char data[64];
|
||||
DN_USize size;
|
||||
};
|
||||
|
||||
struct DN_Str8x256
|
||||
{
|
||||
char data[256];
|
||||
DN_USize size;
|
||||
};
|
||||
|
||||
DN_API DN_USize DN_CStr8_FSize (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_USize DN_CStr8_FVSize (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_USize DN_CStr8_Size (char const *a);
|
||||
DN_API DN_USize DN_CStr16_Size (wchar_t const *a);
|
||||
|
||||
#define DN_STR16(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1}
|
||||
#define DN_Str16_HasData(string) ((string).data && (string).size)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
DN_API bool operator== (DN_Str16 const &lhs, DN_Str16 const &rhs);
|
||||
DN_API bool operator!= (DN_Str16 const &lhs, DN_Str16 const &rhs);
|
||||
#endif
|
||||
|
||||
#define DN_STR8(string) DN_Str8{(char *)(string), (sizeof(string) - 1)}
|
||||
#define DN_STR_FMT(string) (int)((string).size), (string).data
|
||||
#define DN_Str8_Init(data, size) DN_Str8{(char *)(data), (size_t)(size)}
|
||||
#define DN_Str8_HasData(string) ((string).data && (string).size)
|
||||
DN_API DN_Str8 DN_Str8_Alloc (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src);
|
||||
DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FromFPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all);
|
||||
DN_API char * DN_Str8_End (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount);
|
||||
DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8_FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8_Find (DN_Str8 string, uint32_t flags);
|
||||
DN_API DN_Str8 DN_Str8_Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API bool DN_Str8_Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_EqInsensitive (DN_Str8 lhs, DN_Str8 rhs);
|
||||
DN_API bool DN_Str8_StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_StartsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8_EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8_HasChar (DN_Str8 string, char ch);
|
||||
DN_API DN_Str8 DN_Str8_TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8_TrimHexPrefix (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8_TrimAround (DN_Str8 string, DN_Str8 trim_string);
|
||||
DN_API DN_Str8 DN_Str8_TrimHeadWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimTailWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimWhitespaceAround (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimByteOrderMark (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_FileNameFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileNameNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FilePathNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileDirectoryFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8ToU64Result DN_Str8_ToU64 (DN_Str8 string, char separator);
|
||||
DN_API DN_Str8ToI64Result DN_Str8_ToI64 (DN_Str8 string, char separator);
|
||||
DN_API DN_Str8 DN_Str8_AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args);
|
||||
DN_API void DN_Str8_Remove (DN_Str8 *string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddle (DN_Arena *arena, DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8 DN_Str8_Lower (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_Upper (DN_Arena *arena, DN_Str8 string);
|
||||
#if defined(__cplusplus)
|
||||
DN_API bool operator== (DN_Str8 const &lhs, DN_Str8 const &rhs);
|
||||
DN_API bool operator!= (DN_Str8 const &lhs, DN_Str8 const &rhs);
|
||||
#endif
|
||||
|
||||
DN_API DN_Str8 DN_LStr8_AppendFV (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_LStr8_AppendF (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...);
|
||||
#define DN_IStr8_AppendF(struct_ptr, fmt, ...) DN_LStr8_AppendF((struct_ptr)->data, &(struct_ptr)->size, DN_ArrayCountU((struct_ptr)->data), fmt, ##__VA_ARGS__)
|
||||
#define DN_Str8_FromIStr8(struct_ptr) DN_Str8_Init((struct_ptr)->data, (struct_ptr)->size)
|
||||
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromArena (DN_Arena *arena);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromBuilder (DN_Arena *arena, DN_Str8Builder const *builder);
|
||||
DN_API bool DN_Str8Builder_AddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8Builder_AddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8Builder_AddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
#define DN_Str8Builder_AppendArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
DN_API bool DN_Str8Builder_AppendRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8Builder_AppendCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8Builder_AppendFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Append, fmt, args)
|
||||
DN_API bool DN_Str8Builder_AppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8Builder_AppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8Builder_AppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8Builder_AppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
DN_API bool DN_Str8Builder_AppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
#define DN_Str8Builder_PrependArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
DN_API bool DN_Str8Builder_PrependRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8Builder_PrependCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8Builder_PrependFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args)
|
||||
DN_API bool DN_Str8Builder_PrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8Builder_Erase (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Builder_Build (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8Builder_BuildSlice (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
|
||||
DN_API bool DN_Char_IsAlphabet (char ch);
|
||||
DN_API bool DN_Char_IsDigit (char ch);
|
||||
DN_API bool DN_Char_IsAlphaNum (char ch);
|
||||
DN_API bool DN_Char_IsWhitespace (char ch);
|
||||
DN_API bool DN_Char_IsHex (char ch);
|
||||
DN_API char DN_Char_ToHex (char ch);
|
||||
DN_API char DN_Char_ToHexUnchecked (char ch);
|
||||
DN_API char DN_Char_ToLower (char ch);
|
||||
DN_API char DN_Char_ToUpper (char ch);
|
||||
|
||||
DN_API int DN_UTF8_EncodeCodepoint (uint8_t utf8[4], uint32_t codepoint);
|
||||
DN_API int DN_UTF16_EncodeCodepoint (uint16_t utf16[2], uint32_t codepoint);
|
||||
#endif // !defined(DN_BASE_STRING_H)
|
||||
Reference in New Issue
Block a user