Add more array helper functions, add U64 to I64 saturate cast

This commit is contained in:
doylet 2024-02-02 00:08:31 +11:00
parent 105ee9f4b1
commit f6c836ba84
3 changed files with 68 additions and 22 deletions

View File

@ -192,8 +192,11 @@ template <typename T> Dqn_ArrayFindResult<T> Dqn_CArra
#if !defined(DQN_NO_VARRAY) #if !defined(DQN_NO_VARRAY)
template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize (Dqn_usize byte_size, uint8_t arena_flags); template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize (Dqn_usize byte_size, uint8_t arena_flags);
template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_usize max, uint8_t arena_flags); template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_usize max, uint8_t arena_flags);
template <typename T> Dqn_VArray<T> Dqn_VArray_InitSlice (Dqn_Slice<T> slice, Dqn_usize max, uint8_t arena_flags);
template <typename T, Dqn_usize N> Dqn_VArray<T> Dqn_VArray_InitCArray (T const (&items)[N], Dqn_usize max, uint8_t arena_flags);
template <typename T> void Dqn_VArray_Deinit (Dqn_VArray<T> *array); template <typename T> void Dqn_VArray_Deinit (Dqn_VArray<T> *array);
template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array); template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array);
template <typename T> Dqn_Slice<T> Dqn_VArray_Slice (Dqn_VArray<T> const *array);
template <typename T> bool Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count); template <typename T> bool Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count);
template <typename T> T * Dqn_VArray_AddArray (Dqn_VArray<T> *array, T const *items, Dqn_usize count); template <typename T> T * Dqn_VArray_AddArray (Dqn_VArray<T> *array, T const *items, Dqn_usize count);
template <typename T, Dqn_usize N> T * Dqn_VArray_AddCArray (Dqn_VArray<T> *array, T const (&items)[N]); template <typename T, Dqn_usize N> T * Dqn_VArray_AddCArray (Dqn_VArray<T> *array, T const (&items)[N]);
@ -216,9 +219,11 @@ template <typename T> T Dqn_VArra
template <typename T> Dqn_ArrayEraseResult Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_ArrayErase erase); template <typename T> Dqn_ArrayEraseResult Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_ArrayErase erase);
template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array, Dqn_ZeroMem zero_mem); template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array, Dqn_ZeroMem zero_mem);
#endif // !defined(DQN_NO_VARRAY) #endif // !defined(DQN_NO_VARRAY)
// NOTE: [$SARR] Dqn_SArray ////////////////////////////////////////////////////////////////////////
#if !defined(DQN_NO_SARRAY) #if !defined(DQN_NO_SARRAY)
template <typename T> Dqn_SArray<T> Dqn_SArray_Init (Dqn_Arena *arena, Dqn_usize size, Dqn_ZeroMem zero_mem); template <typename T> Dqn_SArray<T> Dqn_SArray_Init (Dqn_Arena *arena, Dqn_usize size, Dqn_ZeroMem zero_mem);
template <typename T, size_t N> Dqn_SArray<T> Dqn_SArray_InitCArray (Dqn_Arena *arena, T const (&array)[N]); template <typename T> Dqn_SArray<T> Dqn_SArray_InitSlice (Dqn_Arena *arena, Dqn_Slice<T> slice, Dqn_usize size, Dqn_ZeroMem zero_mem);
template <typename T, size_t N> Dqn_SArray<T> Dqn_SArray_InitCArray (Dqn_Arena *arena, T const (&array)[N], Dqn_usize size);
template <typename T> bool Dqn_SArray_IsValid (Dqn_SArray<T> const *array); template <typename T> bool Dqn_SArray_IsValid (Dqn_SArray<T> const *array);
template <typename T> Dqn_Slice<T> Dqn_SArray_Slice (Dqn_SArray<T> const *array); template <typename T> Dqn_Slice<T> Dqn_SArray_Slice (Dqn_SArray<T> const *array);
template <typename T> T * Dqn_SArray_AddArray (Dqn_SArray<T> *array, T const *items, Dqn_usize count); template <typename T> T * Dqn_SArray_AddArray (Dqn_SArray<T> *array, T const *items, Dqn_usize count);
@ -244,6 +249,7 @@ template <typename T> void Dqn_SArra
#endif // !defined(DQN_NO_SARRAY) #endif // !defined(DQN_NO_SARRAY)
#if !defined(DQN_NO_FARRAY) #if !defined(DQN_NO_FARRAY)
template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count); template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count);
template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_InitSlice (Dqn_Slice<T> slice);
template <typename T, Dqn_usize N, Dqn_usize K> Dqn_FArray<T, N> Dqn_FArray_InitCArray (T const (&items)[K]); template <typename T, Dqn_usize N, Dqn_usize K> Dqn_FArray<T, N> Dqn_FArray_InitCArray (T const (&items)[K]);
template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array); template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array);
template <typename T, Dqn_usize N> Dqn_usize Dqn_FArray_Max (Dqn_FArray<T, N> const *) { return N; } template <typename T, Dqn_usize N> Dqn_usize Dqn_FArray_Max (Dqn_FArray<T, N> const *) { return N; }
@ -270,6 +276,7 @@ template <typename T, Dqn_usize N> Dqn_ArrayEraseResult Dqn_FArra
template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array); template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array);
#endif // !defined(DQN_NO_FARRAY) #endif // !defined(DQN_NO_FARRAY)
#if !defined(DQN_NO_SLICE) #if !defined(DQN_NO_SLICE)
#define DQN_TO_SLICE(val) Dqn_Slice_Init((val)->data, (val)->size)
template <typename T> Dqn_Slice<T> Dqn_Slice_Init (T* const data, Dqn_usize size); template <typename T> Dqn_Slice<T> Dqn_Slice_Init (T* const data, Dqn_usize size);
template <typename T, Dqn_usize N> Dqn_Slice<T> Dqn_Slice_InitCArray (Dqn_Arena *arena, T const (&array)[N]); template <typename T, Dqn_usize N> Dqn_Slice<T> Dqn_Slice_InitCArray (Dqn_Arena *arena, T const (&array)[N]);
template <typename T> Dqn_Slice<T> Dqn_Slice_Alloc (Dqn_Arena *arena, Dqn_usize size, Dqn_ZeroMem zero_mem); template <typename T> Dqn_Slice<T> Dqn_Slice_Alloc (Dqn_Arena *arena, Dqn_usize size, Dqn_ZeroMem zero_mem);
@ -454,8 +461,10 @@ template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize(Dqn_usize byte_size,
{ {
Dqn_VArray<T> result = {}; Dqn_VArray<T> result = {};
result.arena = Dqn_Arena_InitSize(DQN_ARENA_HEADER_SIZE + byte_size, 0 /*commit*/, arena_flags | Dqn_ArenaFlag_NoGrow | Dqn_ArenaFlag_NoPoison); result.arena = Dqn_Arena_InitSize(DQN_ARENA_HEADER_SIZE + byte_size, 0 /*commit*/, arena_flags | Dqn_ArenaFlag_NoGrow | Dqn_ArenaFlag_NoPoison);
if (result.arena.curr) {
result.data = DQN_CAST(T *)(DQN_CAST(char *)result.arena.curr + result.arena.curr->used); result.data = DQN_CAST(T *)(DQN_CAST(char *)result.arena.curr + result.arena.curr->used);
result.max = (result.arena.curr->reserve - result.arena.curr->used) / sizeof(T); result.max = (result.arena.curr->reserve - result.arena.curr->used) / sizeof(T);
}
return result; return result;
} }
@ -466,6 +475,22 @@ template <typename T> Dqn_VArray<T> Dqn_VArray_Init(Dqn_usize max, uint8_t arena
return result; return result;
} }
template <typename T> Dqn_VArray<T> Dqn_VArray_InitSlice(Dqn_Slice<T> slice, Dqn_usize max, uint8_t arena_flags)
{
Dqn_usize real_max = DQN_MAX(slice.size, max);
Dqn_VArray<T> result = Dqn_VArray_Init(real_max, arena_flags);
if (Dqn_VArray_IsValid(&result))
Dqn_VArray_AddArray(&result, slice.data, slice.size);
return result;
}
template <typename T, Dqn_usize N> Dqn_VArray<T> Dqn_VArray_InitCArray(T const (&items)[N], Dqn_usize max, uint8_t arena_flags)
{
Dqn_usize real_max = DQN_MAX(N, max);
Dqn_VArray<T> result = Dqn_VArray_InitSlice(Dqn_Slice_Init(items, N), real_max, arena_flags);
return result;
}
template <typename T> void Dqn_VArray_Deinit(Dqn_VArray<T> *array) template <typename T> void Dqn_VArray_Deinit(Dqn_VArray<T> *array)
{ {
Dqn_Arena_Deinit(&array->arena); Dqn_Arena_Deinit(&array->arena);
@ -478,6 +503,14 @@ template <typename T> bool Dqn_VArray_IsValid(Dqn_VArray<T> const *array)
return result; return result;
} }
template <typename T> Dqn_Slice<T> Dqn_VArray_Slice(Dqn_VArray<T> const *array)
{
Dqn_Slice<T> result = {};
if (array)
result = Dqn_Slice_Init<T>(array->data, array->size);
return result;
}
template <typename T> T *Dqn_VArray_AddArray(Dqn_VArray<T> *array, T const *items, Dqn_usize count) template <typename T> T *Dqn_VArray_AddArray(Dqn_VArray<T> *array, T const *items, Dqn_usize count)
{ {
T *result = Dqn_VArray_MakeArray(array, count, Dqn_ZeroMem_No); T *result = Dqn_VArray_MakeArray(array, count, Dqn_ZeroMem_No);
@ -599,31 +632,35 @@ template <typename T> Dqn_SArray<T> Dqn_SArray_Init(Dqn_Arena *arena, Dqn_usize
return result; return result;
} }
template <typename T, size_t N> Dqn_SArray<T> Dqn_SArray_InitCArray(Dqn_Arena *arena, T const (&array)[N]) template <typename T> Dqn_SArray<T> Dqn_SArray_InitSlice(Dqn_Arena *arena, Dqn_Slice<T> slice, Dqn_usize size, Dqn_ZeroMem zero_mem)
{ {
Dqn_SArray<T> result = {}; Dqn_usize max = DQN_MAX(slice.size, size);
if (!arena || !N) Dqn_SArray<T> result = Dqn_SArray_Init<T>(arena, max, Dqn_ZeroMem_No);
return result; if (Dqn_SArray_IsValid(&result)) {
result.data = Dqn_Arena_NewArray(arena, T, N, Dqn_ZeroMem_No); Dqn_SArray_AddArray(&result, slice.data, slice.size);
if (result.data) { if (zero_mem == Dqn_ZeroMem_Yes)
DQN_MEMCOPY(result.data, array, sizeof(T) * N); DQN_MEMSET(result.data + result.size, 0, (result.max - result.size) * sizeof(T));
result.size = N;
result.max = N;
} }
return result; return result;
} }
template <typename T, size_t N> Dqn_SArray<T> Dqn_SArray_InitCArray(Dqn_Arena *arena, T const (&array)[N], Dqn_usize size, Dqn_ZeroMem zero_mem)
{
Dqn_SArray<T> result = Dqn_SArray_InitSlice(arena, Dqn_Slice_Init(array, N), size, zero_mem);
return result;
}
template <typename T> bool Dqn_SArray_IsValid(Dqn_SArray<T> const *array) template <typename T> bool Dqn_SArray_IsValid(Dqn_SArray<T> const *array)
{ {
bool result = array && array->data && array->size <= array->max; bool result = array && array->data && array->size <= array->max;
return result; return result;
} }
template <typename T, Dqn_usize N> Dqn_Slice<T> Dqn_SArray_Slice(Dqn_SArray<T> const *array) template <typename T> Dqn_Slice<T> Dqn_SArray_Slice(Dqn_SArray<T> const *array)
{ {
Dqn_Slice<T> result = {}; Dqn_Slice<T> result = {};
if (array) if (array)
Dqn_Slice_Init<T>(DQN_CAST(T *)array->data, array->size); result = Dqn_Slice_Init<T>(DQN_CAST(T *)array->data, array->size);
return result; return result;
} }
@ -643,9 +680,10 @@ template <typename T> T *Dqn_SArray_Make(Dqn_SArray<T> *array, Dqn_ZeroMem zero_
template <typename T> T *Dqn_SArray_AddArray(Dqn_SArray<T> *array, T const *items, Dqn_usize count) template <typename T> T *Dqn_SArray_AddArray(Dqn_SArray<T> *array, T const *items, Dqn_usize count)
{ {
T *result = Dqn_SArray_Make(array, count, Dqn_ZeroMem_No); T *result = Dqn_SArray_MakeArray(array, count, Dqn_ZeroMem_No);
if (result) if (result)
DQN_MEMCPY(result, items, count * sizeof(T)); DQN_MEMCPY(result, items, count * sizeof(T));
return result;
} }
template <typename T, Dqn_usize N> T *Dqn_SArray_AddCArray(Dqn_SArray<T> *array, T const (&items)[N]) template <typename T, Dqn_usize N> T *Dqn_SArray_AddCArray(Dqn_SArray<T> *array, T const (&items)[N])
@ -719,11 +757,15 @@ template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init(T const *arr
return result; return result;
} }
template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_InitSlice(Dqn_Slice<T> slice)
{
Dqn_FArray<T, N> result = Dqn_FArray_Init(slice.data, slice.size);
return result;
}
template <typename T, Dqn_usize N, Dqn_usize K> Dqn_FArray<T, N> Dqn_FArray_InitCArray(T const (&items)[K]) template <typename T, Dqn_usize N, Dqn_usize K> Dqn_FArray<T, N> Dqn_FArray_InitCArray(T const (&items)[K])
{ {
Dqn_FArray<T, N> result = {}; Dqn_FArray<T, N> result = Dqn_FArray_Init<T, N>(items, K);
bool added = Dqn_FArray_AddArray(&result, items, K);
DQN_ASSERT(added);
return result; return result;
} }

View File

@ -585,16 +585,19 @@ DQN_API uint64_t Dqn_Safe_SaturateCastUSizeToU64(Dqn_usize val)
return result; return result;
} }
// NOTE: Dqn_Safe_SaturateCastU64To* // NOTE: Dqn_Safe_SaturateCastU64To* ///////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// INT*_MAX literals will be promoted to the type of val as val is
// the highest possible rank (unsigned > signed).
DQN_API int Dqn_Safe_SaturateCastU64ToInt(uint64_t val) DQN_API int Dqn_Safe_SaturateCastU64ToInt(uint64_t val)
{ {
int result = DQN_CHECK(val <= INT_MAX) ? DQN_CAST(int)val : INT_MAX; int result = DQN_CHECK(val <= INT_MAX) ? DQN_CAST(int)val : INT_MAX;
return result; return result;
} }
DQN_API int64_t Dqn_Safe_SaturateCastU64ToI64(uint64_t val)
{
int64_t result = DQN_CHECK(val <= INT64_MAX) ? DQN_CAST(int64_t)val : INT64_MAX;
return result;
}
// Both operands are unsigned and the lowest rank operand will be promoted to // Both operands are unsigned and the lowest rank operand will be promoted to
// match the highest rank operand. // match the highest rank operand.
DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt(uint64_t val) DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt(uint64_t val)

View File

@ -380,6 +380,7 @@ DQN_API int32_t Dqn_Safe_SaturateCastUSizeToI32 (Dqn_usize
DQN_API int64_t Dqn_Safe_SaturateCastUSizeToI64 (Dqn_usize val); DQN_API int64_t Dqn_Safe_SaturateCastUSizeToI64 (Dqn_usize val);
DQN_API int Dqn_Safe_SaturateCastU64ToInt (uint64_t val); DQN_API int Dqn_Safe_SaturateCastU64ToInt (uint64_t val);
DQN_API int64_t Dqn_Safe_SaturateCastU64ToI64 (uint64_t val);
DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt (uint64_t val); DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt (uint64_t val);
DQN_API uint8_t Dqn_Safe_SaturateCastU64ToU8 (uint64_t val); DQN_API uint8_t Dqn_Safe_SaturateCastU64ToU8 (uint64_t val);
DQN_API uint16_t Dqn_Safe_SaturateCastU64ToU16 (uint64_t val); DQN_API uint16_t Dqn_Safe_SaturateCastU64ToU16 (uint64_t val);