/* * 4coder base types */ // TOP #if !defined(FCODER_BASE_TYPES) #define FCODER_BASE_TYPES //////////////////////////////// #if defined(_MSC_VER) # define COMPILER_CL 1 # if defined(_WIN32) # define OS_WINDOWS 1 # else # error This compiler/platform combo is not supported yet # endif # if defined(_M_AMD64) # define ARCH_X64 1 # elif defined(_M_IX86) # define ARCH_X86 1 # elif defined(_M_ARM64) # define ARCH_ARM64 1 # elif defined(_M_ARM) # define ARCH_ARM32 1 # else # error architecture not supported yet # endif #elif defined(__GNUC__) || defined(__GNUG__) # define COMPILER_GCC 1 # if defined(__gnu_linux__) # define OS_LINUX 1 # elif defined(__APPLE__) && defined(__MACH__) # define OS_MAC 1 # else # error This compiler/platform combo is not supported yet # endif # if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) # define ARCH_X64 1 # elif defined(i386) || defined(__i386) || defined(__i386__) # define ARCH_X86 1 # elif defined(__aarch64__) # define ARCH_ARM64 1 # elif defined(__arm__) # define ARCH_ARM32 1 # else # error architecture not supported yet # endif #else # error This compiler is not supported yet #endif #if defined(ARCH_X64) # define ARCH_64BIT 1 #elif defined(ARCH_X86) # define ARCH_32BIT 1 #endif // zeroify #if !defined(ARCH_32BIT) #define ARCH_32BIT 0 #endif #if !defined(ARCH_64BIT) #define ARCH_64BIT 0 #endif #if !defined(ARCH_X64) #define ARCH_X64 0 #endif #if !defined(ARCH_X86) #define ARCH_X86 0 #endif #if !defined(ARCH_ARM64) #define ARCH_ARM64 0 #endif #if !defined(ARCH_ARM32) #define ARCH_ARM32 0 #endif #if !defined(COMPILER_CL) #define COMPILER_CL 0 #endif #if !defined(COMPILER_GCC) #define COMPILER_GCC 0 #endif #if !defined(OS_WINDOWS) #define OS_WINDOWS 0 #endif #if !defined(OS_LINUX) #define OS_LINUX 0 #endif #if !defined(OS_MAC) #define OS_MAC 0 #endif #if !defined(SHIP_MODE) #define SHIP_MODE 0 #endif //////////////////////////////// #if COMPILER_CL #if _MSC_VER <= 1800 # define snprintf _snprintf #endif #if (_MSC_VER <= 1500) #define JUST_GUESS_INTS #endif #endif #if OS_WINDOWS # if ARCH_32BIT # define CALL_CONVENTION __stdcall # else # define CALL_CONVENTION # endif #endif #if defined(JUST_GUESS_INTS) typedef signed char i8; typedef signed short i16; typedef signed int i32; typedef signed long long i64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; #else #include typedef int8_t i8; typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; #endif typedef i8 b8; typedef i32 b32; #if ARCH_32BIT typedef u32 umem; typedef i32 imem; #else typedef u64 umem; typedef i64 imem; #endif typedef float f32; typedef double f64; typedef void Void_Func(void); #define glue_(a,b) a##b #define glue(a,b) glue_(a,b) #define stringify_(a) #a #define stringify(a) stringify_(a) #define internal static #define local_persist static #define global static #define local_const static const #define global_const static const #define external extern "C" #define ArrayCount(a) ((sizeof(a))/(sizeof(*a))) #define ExpandArray(a) (a), (ArrayCount(a)) #define FixSize(s) struct{ u8 __size_fixer__[s]; } #define PtrDif(a,b) ((u8*)(a) - (u8*)(b)) #define PtrAsInt(a) PtrDif(a,0) #define HandleAsU64(a) (u64)(PtrAsInt(a)) #define Member(S,m) (((S*)0)->m) #define NullMember(S,m) (&Member(S,m)) #define OffsetOfMember(S,m) PtrAsInt(&Member(S,m)) #define OffsetOfMemberStruct(s,m) PtrDif(&(s)->m, (s)) #define SizeAfterMember(S,m) (sizeof(S) - OffsetOfMember(S,m)) #define CastFromMember(S,m,ptr) (S*)( (u8*)(ptr) - OffsetOfMember(S,m) ) #define IntAsPtr(a) (void*)(((u8*)0) + a) #define Stmnt(s) do{ s }while(0) #define AssertBreak(m) (*((i32*)0) = 0xA11E) #define AssertAlways(c) Stmnt( if (!(c)) { AssertBreak(c); } ) #define AssertMessageAlways(m) AssertBreak(m) #define StaticAssertDisambiguateAlways(c,d) char glue(__ignore__, glue(__LINE__, d))[(c)?1:-1]; #define StaticAssertAlways(c) StaticAssertDisambiguateAlways(c,__default__) #if !SHIP_MODE #define Assert(c) AssertAlways(c) #define AssertMessage(m) AssertMessageAlways(m) #define StaticAssertDisambiguate(c,d) StaticAssertDisambiguateAlways(c,d) #define StaticAssert(c) StaticAssertAlways(c) #else #define Assert(c) #define AssertMessage(m) #define StaticAssertDisambiguate(c,d) #define StaticAssert(c) #endif #define AssertImplies(a,b) Assert(!(a) || (b)) #define InvalidPath AssertMessage("invalid path") #define NotImplemented AssertMessage("not implemented") #define DontCompile NoSeriouslyDontCompile #define B(x) (x) #define KB(x) ((x) << 10) #define MB(x) ((x) << 20) #define GB(x) ((x) << 30) #define TB(x) (((u64)x) << 40) #define Thousand(x) ((x)*1000) #define Million(x) ((x)*1000000) #define Billion(x) ((x)*1000000000) #define HasFlag(fi,fl) (((fi)&(fl))!=0) #define HasAllFlag(fi,fl) (((fi)&(fl))==(fl)) #define AddFlag(fi,fl) ((fi)|=(fl)) #define RemFlag(fi,fl) ((fi)&=(~(fl))) #define MovFlag(fi1,fl1,fi2,fl2) ((HasFlag(fi1,fl1))?(AddFlag(fi2,fl2)):(fi2)) #define Swap(t,a,b) do { t glue(hidden_temp_,__LINE__) = a; a = b; b = glue(hidden_temp_,__LINE__); } while(0) #define div_round_up_positive_(n,d) (n + d - 1)/d #define div_round_up_positive(n,d) (div_round_up_positive_((n),(d))) #define DrCase(PC) case PC: goto resumespot_##PC #define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } #define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } #define Max(a,b) (((a)>(b))?(a):(b)) #define Min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b)) #define clamp_top(a,b) Min(a,b) #define clamp_bot(a,b) Max(a,b) #define clamp_(a,x,b) ((a>x)?a:((bnext=s,s->prev=s #define dll_insert_NP_(p,n1,n2,next,prev) n2->next=p->next,n1->prev=p,p->next->prev=n2,p->next=n1 #define dll_remove_NP_(n1,n2,next,prev) n2->next->prev=n1->prev,n1->prev->next=n2->next,n2->next=n1->prev=0 #define dll_init_sentinel_(s) dll_init_sentinel_NP_(s,next,prev) #define dll_insert_(p,n) dll_insert_NP_(p,n,n,next,prev) #define dll_insert_multiple_(p,n1,n2) dll_insert_NP_(p,n1,n2,next,prev) #define dll_insert_back_(p,n) dll_insert_NP_(p,n,n,prev,next) #define dll_insert_multiple_back_(p,n1,n2) dll_insert_NP_(p,n2,n1,prev,next) #define dll_remove_(n) dll_remove_NP_(n,n,next,prev) #define dll_remove_multiple_(n1,n2) dll_remove_NP_(n1,n2,next,prev) #define dll_init_sentinel(s) (dll_init_sentinel_((s))) #define dll_insert(p,n) (dll_insert_((p),(n))) #define dll_insert_multiple(p,n1,n2) (dll_insert_multiple_((p),(n1),(n2))) #define dll_insert_back(p,n) (dll_insert_back_((p),(n))) #define dll_insert_multiple_back(p,n1,n2) (dll_insert_multiple_back_((p),(n1),(n2))) #define dll_remove(n) (dll_remove_((n))) #define dll_remove_multiple(n1,n2) (dll_remove_multiple_((n1),(n2))) #define sll_stack_push_(h,n) n->next=h,h=n #define sll_stack_pop_(h) h=h=h->next #define sll_queue_push_multiple_(f,l,ff,ll) if(ll){if(f){l->next=ff;}else{f=ff;}l=ll;l->next=0;} #define sll_queue_push_(f,l,n) sll_queue_push_multiple_(f,l,n,n) #define sll_queue_pop_(f,l) if (f==l) { f=l=0; } else { f->next=0;f=f->next; } #define sll_stack_push(h,n) (sll_stack_push_((h),(n))) #define sll_stack_pop(h) (sll_stack_pop_((h))) #define sll_queue_push_multiple(f,l,ff,ll) Stmnt( sll_queue_push_multiple_((f),(l),(ff),(ll)) ) #define sll_queue_push(f,l,n) Stmnt( sll_queue_push_((f),(l),(n)) ) #define sll_queue_pop(f,l) Stmnt( sll_queue_pop_((f),(l)) ) #define zdll_push_back_NP_(f,l,n,next,prev) ((f==0)?(n->next=n->prev=0,f=l=n):(n->prev=l,n->next=0,l->next=n,l=n)) #define zdll_remove_back_NP_(f,l,next,prev) ((f==l)?(f=l=0):(l->prev->next=0,l=l->prev)) #define zdll_remove_NP_(f,l,n,next,prev) \ ((l==n)?(zdll_remove_back_NP_(f,l,next,prev)) \ :(f==n)?(zdll_remove_back_NP_(l,f,prev,next)) \ : (dll_remove_NP_(n,n,next,prev))) #define zdll_push_back(f,l,n) zdll_push_back_NP_((f),(l),(n),next,prev) #define zdll_push_front(f,l,n) zdll_push_back_NP_((l),(f),(n),prev,next) #define zdll_remove_back(f,l) zdll_remove_back_NP_((f),(l),next,prev) #define zdll_remove_front(f,l) zdll_remove_back_NP_((l),(f),prev,next) #define zdll_remove(f,l,n) zdll_remove_NP_((f),(l),(n),next,prev) //////////////////////////////// union Vec2_i8{ struct{ i8 x; i8 y; }; i8 v[2]; }; union Vec3_i8{ struct{ i8 x; i8 y; i8 z; }; struct{ i8 r; i8 g; i8 b; }; i8 v[3]; }; union Vec4_i8{ struct{ i8 x; i8 y; i8 z; i8 w; }; struct{ i8 r; i8 g; i8 b; i8 a; }; i8 v[4]; }; union Vec2_i16{ struct{ i16 x; i16 y; }; i16 v[2]; }; union Vec3_i16{ struct{ i16 x; i16 y; i16 z; }; struct{ i16 r; i16 g; i16 b; }; i16 v[3]; }; union Vec4_i16{ struct{ i16 x; i16 y; i16 z; i16 w; }; struct{ i16 r; i16 g; i16 b; i16 a; }; i16 v[4]; }; union Vec2_i32{ struct{ i32 x; i32 y; }; i32 v[2]; }; union Vec3_i32{ struct{ i32 x; i32 y; i32 z; }; struct{ i32 r; i32 g; i32 b; }; i32 v[3]; }; union Vec4_i32{ struct{ i32 x; i32 y; i32 z; i32 w; }; struct{ i32 r; i32 g; i32 b; i32 a; }; i32 v[4]; }; union Vec2_f32{ struct{ f32 x; f32 y; }; f32 v[2]; }; union Vec3_f32{ struct{ f32 x; f32 y; f32 z; }; struct{ f32 r; f32 g; f32 b; }; f32 v[3]; }; union Vec4_f32{ struct{ f32 x; f32 y; f32 z; f32 w; }; struct{ f32 r; f32 g; f32 b; f32 a; }; struct{ f32 h; f32 s; f32 l; f32 __a; }; f32 v[4]; }; union Range_i32{ struct{ i32 min; i32 max; }; struct{ i32 start; i32 end; }; struct{ i32 first; i32 one_past_last; }; }; union Range_i64{ struct{ i64 min; i64 max; }; struct{ i64 start; i64 end; }; struct{ i64 first; i64 one_past_last; }; }; union Range_u64{ struct{ u64 min; u64 max; }; struct{ u64 start; u64 end; }; struct{ u64 first; u64 one_past_last; }; }; union Range_f32{ struct{ f32 min; f32 max; }; struct{ f32 start; f32 end; }; struct{ f32 first; f32 one_past_last; }; }; typedef Range_i32 Interval_i32; typedef Range_i64 Interval_i64; typedef Range_u64 Interval_u64; typedef Range_f32 Interval_f32; typedef Range_i32 Range; struct Range_i32_Array{ Range_i32 *ranges; i32 count; }; struct Range_i64_Array{ Range_i64 *ranges; i32 count; }; struct Range_u64_Array{ Range_u64 *ranges; i32 count; }; struct Range_f32_Array{ Range_f32 *ranges; i32 count; }; typedef Range_i32_Array Range_Array; union Rect_i32{ struct{ i32 x0; i32 y0; i32 x1; i32 y1; }; struct{ Vec2_i32 p0; Vec2_i32 p1; }; Vec2_i32 p[2]; }; union Rect_f32{ struct{ f32 x0; f32 y0; f32 x1; f32 y1; }; struct{ Vec2_f32 p0; Vec2_f32 p1; }; Vec2_f32 p[2]; }; typedef Vec2_f32 Vec2; typedef Vec3_f32 Vec3; typedef Vec4_f32 Vec4; typedef Rect_f32 f32_Rect; typedef Rect_i32 i32_Rect; struct f32_Rect_Pair{ f32_Rect E[2]; }; typedef f32_Rect_Pair Rect_f32_Pair; //////////////////////////////// struct i8_Array{ i8 *vals; i32 coint; }; struct i16_Array{ i16 *vals; i32 coint; }; struct i32_Array{ i32 *vals; i32 coint; }; struct i64_Array{ i64 *vals; i32 coint; }; struct u8_Array{ u8 *vals; i32 count; }; struct u16_Array{ u16 *vals; i32 count; }; struct u32_Array{ u32 *vals; i32 count; }; struct u64_Array{ u64 *vals; i32 count; }; //////////////////////////////// typedef i32 String_Fill_Terminate_Rule; enum{ StringFill_NoTerminate = 0, StringFill_NullTerminate = 1, }; typedef u32 String_Separator_Flag; enum{ StringSeparator_NoFlags = 0, }; enum{ StringSeparator_BeforeFirst = 1, StringSeparator_AfterLast = 2, }; typedef i32 String_Match_Rule; enum{ StringMatch_Exact = 0, StringMatch_CaseInsensitive = 1, }; struct String_Const_char{ char *str; u64 size; }; struct String_Const_u8{ union{ void *data; u8 *str; }; u64 size; }; struct String_Const_u16{ u16 *str; u64 size; }; struct String_Const_u32{ u32 *str; u64 size; }; struct String_Const_char_Array{ union{ String_Const_char *strings; String_Const_char *vals; }; i32 count; }; struct String_Const_u8_Array{ union{ String_Const_u8 *strings; String_Const_u8 *vals; }; i32 count; }; struct String_Const_u16_Array{ union{ String_Const_u16 *strings; String_Const_u16 *vals; }; i32 count; }; struct String_Const_u32_Array{ union{ String_Const_u32 *strings; String_Const_u32 *vals; }; i32 count; }; typedef i32 String_Encoding; enum{ StringEncoding_ASCII = 0, StringEncoding_UTF8 = 1, StringEncoding_UTF16 = 2, StringEncoding_UTF32 = 3, }; struct String_Const_Any{ String_Encoding encoding; union{ struct{ void *str; u64 size; }; String_Const_char s_char; String_Const_u8 s_u8; String_Const_u16 s_u16; String_Const_u32 s_u32; }; }; struct Node_String_Const_char{ Node_String_Const_char *next; String_Const_char string; }; struct Node_String_Const_u8{ Node_String_Const_u8 *next; String_Const_u8 string; }; struct Node_String_Const_u16{ Node_String_Const_u16 *next; String_Const_u16 string; }; struct Node_String_Const_u32{ Node_String_Const_u32 *next; String_Const_u32 string; }; struct List_String_Const_char{ Node_String_Const_char *first; Node_String_Const_char *last; u64 total_size; i32 node_count; }; struct List_String_Const_u8{ Node_String_Const_u8 *first; Node_String_Const_u8 *last; u64 total_size; i32 node_count; }; struct List_String_Const_u16{ Node_String_Const_u16 *first; Node_String_Const_u16 *last; u64 total_size; i32 node_count; }; struct List_String_Const_u32{ Node_String_Const_u32 *first; Node_String_Const_u32 *last; u64 total_size; i32 node_count; }; struct Node_String_Const_Any{ Node_String_Const_Any *next; String_Const_Any string; }; struct List_String_Const_Any{ Node_String_Const_Any *first; Node_String_Const_Any *last; u64 total_size; i32 node_count; }; struct String_char{ union{ String_Const_char string; struct{ char *str; umem size; }; }; umem cap; }; struct String_u8{ union{ String_Const_u8 string; struct{ u8 *str; umem size; }; }; umem cap; }; struct String_u16{ union{ String_Const_u16 string; struct{ u16 *str; umem size; }; }; umem cap; }; struct String_u32{ union{ String_Const_u32 string; struct{ u32 *str; umem size; }; }; umem cap; }; struct String_Any{ String_Encoding encoding; union{ struct{ void *str; umem size; umem cap; }; String_char s_char; String_u8 s_u8; String_u16 s_u16; String_u32 s_u32; }; }; struct Character_Consume_Result{ u32 inc; u32 codepoint; }; struct Data{ u8 *data; umem size; }; //////////////////////////////// typedef u32 Access_Flag; enum{ AccessFlag_Read = 1, AccessFlag_Write = 2, AccessFlag_Exec = 4, }; typedef i32 Dimension; enum{ Dimension_X = 0, Dimension_Y = 1, Dimension_Z = 2, Dimension_W = 3, }; typedef i32 Coordinate; enum{ Coordinate_X = 0, Coordinate_Y = 1, Coordinate_Z = 2, Coordinate_W = 3, }; typedef i32 Side; enum{ Side_Min = 0, Side_Max = 1, }; typedef i32 Scan_Direction; enum{ Scan_Backward = -1, Scan_Forward = 1, }; //////////////////////////////// typedef void *Base_Allocator_Reserve_Signature(void *user_data, umem size, umem *size_out); typedef void Base_Allocator_Commit_Signature(void *user_data, void *ptr, umem size); typedef void Base_Allocator_Uncommit_Signature(void *user_data, void *ptr, umem size); typedef void Base_Allocator_Free_Signature(void *user_data, void *ptr); typedef void Base_Allocator_Set_Access_Signature(void *user_data, void *ptr, umem size, Access_Flag flags); struct Base_Allocator{ Base_Allocator_Reserve_Signature *reserve; Base_Allocator_Commit_Signature *commit; Base_Allocator_Uncommit_Signature *uncommit; Base_Allocator_Free_Signature *free; Base_Allocator_Set_Access_Signature *set_access; void *user_data; }; struct Cursor{ u8 *base; umem pos; umem cap; }; struct Temp_Memory_Cursor{ Cursor *cursor; umem pos; }; struct Cursor_Node{ union{ Cursor_Node *next; Cursor_Node *prev; }; Cursor cursor; }; struct Arena{ Base_Allocator *base_allocator; Cursor_Node *cursor_node; umem chunk_size; umem alignment; }; struct Temp_Memory_Arena{ Arena *arena; Cursor_Node *cursor_node; umem pos; }; typedef i32 Linear_Allocator_Kind; enum{ LinearAllocatorKind_Cursor, LinearAllocatorKind_Arena, }; struct Temp_Memory{ Linear_Allocator_Kind kind; union{ Temp_Memory_Cursor temp_memory_cursor; Temp_Memory_Arena temp_memory_arena; }; }; //////////////////////////////// union Arena_Node{ Arena_Node *next; Arena arena; }; struct Thread_Context{ Base_Allocator *allocator; Arena node_arena; Arena_Node *free_arenas; Arena *sharable_scratch; }; typedef i32 Scratch_Share_Code; enum{ Scratch_DontShare, Scratch_Share, }; struct Scratch_Block{ Arena *arena; Temp_Memory temp; b32 do_full_clear; Thread_Context *tctx; Arena *sharable_restore; Scratch_Block(Temp_Memory temp); Scratch_Block(Arena *arena); Scratch_Block(struct Thread_Context *tctx, Scratch_Share_Code share); Scratch_Block(struct Thread_Context *tctx); Scratch_Block(struct Application_Links *app, Scratch_Share_Code share); Scratch_Block(struct Application_Links *app); ~Scratch_Block(); operator Arena*(); void restore(void); }; //////////////////////////////// struct Heap_Basic_Node{ Heap_Basic_Node *next; Heap_Basic_Node *prev; }; struct Heap_Node{ union{ struct{ Heap_Basic_Node order; Heap_Basic_Node alloc; umem size; }; u8 force_size__[64]; }; }; struct Heap{ Arena arena_; Arena *arena; Heap_Basic_Node in_order; Heap_Basic_Node free_nodes; umem used_space; umem total_space; }; //#define DO_HEAP_CHECKS #endif // BOTTOM