44#include <cx/debug/dbgtypes.h>
49#define sarrayref(typ) sa_##typ
50#define sarrayhdl(typ) sa_##typ*
80#define saDeclareType(name, typ) \
81 typedef union sa_##name { \
84 void* _is_sarray_##name; \
93#define saDeclare(name) saDeclareType(name, name)
100#define saDeclarePtr(name) saDeclareType(name, name*)
105#define saInitNone { .a = 0 }
108typedef sa_ref sa_opaque;
136typedef struct SArrayHeader {
153enum SARRAY_GROW_ENUM {
184 SAINT_Consume = 0x10000000,
187#define SA_GROW_MASK (0xff000000)
229#define SA_Grow(rate) (((uint32)SA_GROW_##rate) << 24)
232#define SA_GET_GROW(flags) ((flags) >> 24)
234#define SARRAY_HDRSIZE (offsetof(SArrayHeader, data))
235#define SARRAY_HDR(ref) ((SArrayHeader*)(((uintptr)((ref).a)) - SARRAY_HDRSIZE))
236#define SAREF(r) (unused_noeval(&((r)._is_sarray)), *(sa_ref*)(&(r)))
237#define SAHANDLE(h) ((sahandle)(unused_noeval((h != NULL) && &((h)->_is_sarray)), (h)))
239_Ret_notnull_ _meta_inline SArrayHeader* _saHdr(_In_ sa_ref ref)
241 return SARRAY_HDR(ref);
250#define saSize(ref) ((ref)._is_sarray ? _saHdr(SAREF(ref))->count : 0)
258#define saCapacity(ref) ((ref)._is_sarray ? _saHdr(SAREF(ref))->capacity : 0)
266#define saElemSize(ref) ((ref)._is_sarray ? stGetSize(_saHdr(SAREF(ref))->elemtype) : 0)
274#define saElemType(ref) ((ref)._is_sarray ? _saHdr(SAREF(ref))->elemtype : 0)
282#define saValid(ref) ((ref).a)
291_Success_(!canfail ||
return) _When_(canfail, _Check_return_) _At_(out->a, _Post_notnull_)
bool
292_saInit(_Out_ sahandle out,
stype elemtype, int32 capacity,
bool canfail, flags_t flags);
315#define saInit(out, type, capacity, ...) \
316 _saInit(SAHANDLE(out), stType(type), capacity, false, opt_flags(__VA_ARGS__))
327#define saTryInit(out, type, capacity, ...) \
328 _saInit(SAHANDLE(out), stType(type), capacity, true, opt_flags(__VA_ARGS__))
330_At_(handle->a, _Pre_maybenull_ _Post_null_)
void _saDestroy(_Inout_ sahandle handle);
345#define saDestroy(handle) _saDestroy(SAHANDLE(handle))
347_When_(canfail, _Check_return_) _At_(handle->a, _Pre_notnull_ _Post_notnull_)
bool _saReserve(_Inout_ sahandle handle, int32 capacity,
bool canfail);
364#define saReserve(handle, capacity) _saReserve(SAHANDLE(handle), capacity, true)
366_At_(handle->a, _Pre_notnull_ _Post_notnull_)
void _saShrink(_Inout_ sahandle handle, int32 capacity);
385#define saShrink(handle, capacity) _saShrink(SAHANDLE(handle), capacity)
387_At_(handle->a, _Pre_notnull_ _Post_notnull_)
void _saSetSize(_Inout_ sahandle handle, int32 size);
403#define saSetSize(handle, size) _saSetSize(SAHANDLE(handle), size)
405_At_(handle->a, _Pre_maybenull_)
void _saClear(_Inout_ sahandle handle);
420#define saClear(handle) _saClear(SAHANDLE(handle))
429#define _sa_Consume_Arg_ \
430 _When_(flags& SAINT_Consume, _Pre_notnull_ _Post_invalid_) \
431 _When_(!(flags & SAINT_Consume), _Inout_)
432_At_(handle->a, _Pre_maybenull_ _Post_notnull_) int32 _saPush(_Inout_ sahandle handle,
stype elemtype, _In_ stgeneric elem,
434_At_(handle->a, _Pre_maybenull_ _Post_notnull_) int32 _saPushPtr(_Inout_ sahandle handle,
stype elemtype,
435 _sa_Consume_Arg_ stgeneric* elem, flags_t flags);
460#define saPush(handle, type, elem, ...) \
461 _saPush(SAHANDLE(handle), stCheckedArg(type, elem), opt_flags(__VA_ARGS__))
486#define saPushC(handle, type, elem, ...) \
487 _saPushPtr(SAHANDLE(handle), \
488 stCheckedPtrArg(type, elem), \
489 opt_flags(__VA_ARGS__) | SAINT_Consume)
491_Ret_opt_valid_ _At_(handle->a, _Pre_maybenull_)
void* _saPopPtr(_Inout_ sahandle handle, int32 idx);
510#define saPopPtr(handle) _saPopPtr(SAHANDLE(handle), -1)
527#define saPopPtrI(handle, idx) _saPopPtr(SAHANDLE(handle), idx)
529_At_(ref.a, _Pre_notnull_) int32 _saFind(_In_ sa_ref ref, _In_ stgeneric elem, flags_t flags);
530_At_(ref.a, _Pre_maybenull_) _meta_inline int32
531_saFindChecked(_In_ sa_ref ref,
stype elemtype, _In_ stgeneric elem, flags_t flags)
536 return _saFind(ref, elem, flags);
561#define saFind(ref, type, elem, ...) \
562 _saFindChecked(SAREF(ref), stCheckedArg(type, elem), opt_flags(__VA_ARGS__))
564_At_(handle->a, _Pre_notnull_ _Post_notnull_)
bool _saFindRemove(_Inout_ sahandle handle, _In_ stgeneric elem, flags_t flags);
565_At_(handle->a, _Pre_maybenull_) _meta_inline
bool
566_saFindRemoveChecked(_Inout_ sahandle handle,
stype elemtype, _In_ stgeneric elem, flags_t flags)
571 return _saFindRemove(handle, elem, flags);
594#define saFindRemove(handle, type, elem, ...) \
595 _saFindRemoveChecked(SAHANDLE(handle), stCheckedArg(type, elem), opt_flags(__VA_ARGS__))
597_At_(handle->a, _Pre_notnull_ _Post_notnull_) int32 _saInsert(_Inout_ sahandle handle, int32 idx, _In_ stgeneric elem);
598_At_(handle->a, _Pre_notnull_ _Post_notnull_) _meta_inline int32
599_saInsertChecked(_Inout_ sahandle handle, int32 idx,
stype elemtype, _In_ stgeneric elem)
603 return _saInsert(handle, idx, elem);
628#define saInsert(handle, idx, type, elem) \
629 _saInsertChecked(SAHANDLE(handle), idx, stCheckedArg(type, elem))
631_At_(handle->a, _Pre_notnull_ _Post_notnull_)
bool _saExtract(_Inout_ sahandle handle, int32 idx, _Inout_opt_ stgeneric* elem,
634_At_(handle->a, _Pre_maybenull_) _meta_inline
bool
635_saExtractChecked(_Inout_ sahandle handle, int32 idx,
stype elemtype,
636 _stCopyDest_Anno_opt_(elemtype) stgeneric* elem, flags_t flags)
641 return _saExtract(handle, idx, elem, flags);
667#define saExtract(handle, idx, type, elem_copy_out, ...) \
668 _saExtractChecked(SAHANDLE(handle), \
670 stCheckedPtrArg(type, elem_copy_out), \
671 opt_flags(__VA_ARGS__))
690#define saRemove(handle, idx, ...) \
691 _saExtractChecked(SAHANDLE(handle), idx, stType(none), NULL, opt_flags(__VA_ARGS__))
693_At_(handle->a, _Pre_maybenull_)
void _saSort(_Inout_ sahandle handle,
bool keep);
714#define saSort(handle, keep) _saSort(SAHANDLE(handle), keep)
736_At_(handle->a, _Pre_maybenull_)
void _saSortCustom(_Inout_ sahandle handle,
775#define saSortCustom(handle, cmp, ctx, ...) \
776 _saSortCustom(SAHANDLE(handle), cmp, ctx, opt_flags(__VA_ARGS__))
784_At_(out->a, _When_(ref.a, _Post_notnull_) )
void _saSlice(_Out_ sahandle out, _In_ sa_ref ref, int32 start, int32 end);
806#define saSlice(out, src, start, end) _saSlice(SAHANDLE(out), SAREF(src), start, end)
825#define saClone(out, src) _saSlice(SAHANDLE(out), SAREF(src), 0, 0)
827_At_(out->a, _Post_maybenull_)
void _saMerge(_Out_ sahandle out,
int n, _In_ sa_ref* refs, flags_t flags);
846#define saMerge(out, ...) \
847 _saMerge(SAHANDLE(out), \
848 sizeof((sa_ref[]) { __VA_ARGS__ }) / sizeof(sa_ref), \
849 (sa_ref[]) { __VA_ARGS__ }, \
869#define saMergeF(out, flags, ...) \
870 _saMerge(SAHANDLE(out), \
871 sizeof((sa_ref[]) { __VA_ARGS__ }) / sizeof(sa_ref), \
872 (sa_ref[]) { __VA_ARGS__ }, \
891template <
typename... SAs> _meta_inline
void _cxSaMerge(sahandle out, flags_t flags, SAs... arrs)
893 static_assert(
sizeof...(SAs) > 0,
"saMerge requires at least one source array");
894 sa_ref refs[] = { *(sa_ref*)&arrs... };
895 _saMerge(out, (
int)(
sizeof...(SAs)), refs, flags);
899#define saMerge(out, ...) _cxSaMerge(SAHANDLE(out), 0, __VA_ARGS__)
900#define saMergeF(out, flags, ...) _cxSaMerge(SAHANDLE(out), flags, __VA_ARGS__)
Runtime assertion macros and failure handling.
#define saDeclareType(name, typ)
SARRAY_CREATE_FLAGS_ENUM
Creation flags for sarray initialization.
SARRAY_FUNC_FLAGS_ENUM
Operation flags for sarray functions.
@ SA_Ref
Array references data without copying/destroying (pointer types only)
@ SA_Sorted
Maintain sorted order with O(log n) search and O(n) insert.
@ SA_AutoShrink
Automatically release memory when array shrinks.
intptr(* saCmpFunc)(stype st, stgeneric gen1, stgeneric gen2, flags_t flags, void *ctx)
#define stvar(typen, val)
bool stEq(stype s1, stype s2)
128-bit sortable unique identifier
Macros for suppressing compiler warnings.