preogress on getting dependencies compilable in C-library

This commit is contained in:
Edward R. Gonzalez 2024-12-05 02:53:14 -05:00
parent a3e7ec4c72
commit 1c3134218e
24 changed files with 206 additions and 134 deletions

View File

@ -26,7 +26,7 @@ GEN_NS_END
using namespace gen; using namespace gen;
constexpr char const* generation_notice = constexpr char const* generation_notice =
"// This file was generated automatially by gencpp's c_library.cpp" "// This file was generated automatially by gencpp's c_library.cpp "
"(See: https://github.com/Ed94/gencpp)\n\n"; "(See: https://github.com/Ed94/gencpp)\n\n";
constexpr StrC roll_own_dependencies_guard_start = txt(R"( constexpr StrC roll_own_dependencies_guard_start = txt(R"(
@ -198,7 +198,7 @@ int gen_main()
(body_entry->Type) { (body_entry->Type) {
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), body_entry, body ); ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), body_entry, body, new_body );
} }
break; break;
@ -213,10 +213,10 @@ int gen_main()
break; break;
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory ); b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory, memory );
if (found) break; if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_memory ); found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_memory, memory );
if (found) break; if (found) break;
memory.append(entry); memory.append(entry);
@ -224,7 +224,7 @@ int gen_main()
break; break;
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
{ {
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_memory ); b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_memory, memory );
if (found) break; if (found) break;
memory.append(entry); memory.append(entry);
@ -251,14 +251,10 @@ int gen_main()
} }
} }
// CodeBody selectors = generate_generic_selectors(needs_selectors);
// memory.append_at(selectors, 0)
// memory.append(fmt_newline);
header.print( dump_to_scratch_and_retireve(memory) ); header.print( dump_to_scratch_and_retireve(memory) );
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" ); Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
// header.print( string_ops ); header.print( string_ops );
CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" ); CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" );
CodeBody printing = def_body(CT_Global_Body); CodeBody printing = def_body(CT_Global_Body);
@ -268,7 +264,7 @@ int gen_main()
{ {
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
{ {
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed ); b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed, printing );
if (found) break; if (found) break;
printing.append(entry); printing.append(entry);
@ -290,7 +286,7 @@ int gen_main()
break; break;
} }
} }
// header.print(dump_to_scratch_and_retireve(printing)); header.print(dump_to_scratch_and_retireve(printing));
CodeBody containers = def_body(CT_Global_Body); CodeBody containers = def_body(CT_Global_Body);
{ {
@ -301,11 +297,11 @@ int gen_main()
containers.append( def_pragma(code(endregion Containers))); containers.append( def_pragma(code(endregion Containers)));
} }
// header.print(fmt_newline); header.print(fmt_newline);
// header.print(dump_to_scratch_and_retireve(containers)); header.print(dump_to_scratch_and_retireve(containers));
Code hashing = scan_file( project_dir "dependencies/hashing.hpp" ); Code hashing = scan_file( project_dir "dependencies/hashing.hpp" );
// header.print( hashing ); header.print( hashing );
CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" ); CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" );
CodeBody strings = def_body(CT_Global_Body); CodeBody strings = def_body(CT_Global_Body);
@ -318,8 +314,8 @@ int gen_main()
CodePreprocessCond cond = cast(CodePreprocessCond, entry); CodePreprocessCond cond = cast(CodePreprocessCond, entry);
if (cond->Content.starts_with(txt("GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES"))) if (cond->Content.starts_with(txt("GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES")))
{ {
++ entry; for (; entry != end(parsed_strings) && entry->Type != CT_Typedef; ++ entry) {}
strings.append(entry); // typedef strings.append(entry);
strings.append(fmt_newline); strings.append(fmt_newline);
for (; entry != end(parsed_strings) && entry->Type != CT_Preprocess_EndIf; ++ entry) {} for (; entry != end(parsed_strings) && entry->Type != CT_Preprocess_EndIf; ++ entry) {}
@ -327,16 +323,16 @@ int gen_main()
break; break;
} }
bool found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), entry, parsed_strings); bool found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_strings, strings);
if (found) break; if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_strings); found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_strings, strings );
} }
break; break;
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
{ {
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings ); ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings, strings );
} }
break; break;
@ -362,7 +358,7 @@ int gen_main()
(body_entry->Type) { (body_entry->Type) {
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
b32 found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), body_entry, body ); b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), body_entry, body, new_body );
if (found) break; if (found) break;
new_body.append(body_entry); new_body.append(body_entry);
@ -382,7 +378,7 @@ int gen_main()
break; break;
} }
} }
// header.print(dump_to_scratch_and_retireve(strings)); header.print(dump_to_scratch_and_retireve(strings));
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" ); Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
Code timing = scan_file( project_dir "dependencies/timing.hpp" ); Code timing = scan_file( project_dir "dependencies/timing.hpp" );

View File

@ -7,7 +7,7 @@ using namespace gen;
CodeBody gen_hashtable_base() CodeBody gen_hashtable_base()
{ {
return parse_global_body( code( CodeBody struct_def = parse_global_body( code(
typedef struct HT_FindResult HT_FindResult; typedef struct HT_FindResult HT_FindResult;
struct HT_FindResult struct HT_FindResult
{ {
@ -16,6 +16,13 @@ CodeBody gen_hashtable_base()
ssize EntryIndex; ssize EntryIndex;
}; };
)); ));
Code define_type = untyped_str(txt(
R"(#define Hashtable(_type) HTE_##_type
)"
));
return def_global_body(args(struct_def, define_type));
} }
CodeBody gen_hashtable( StrC type, StrC hashtable_name ) CodeBody gen_hashtable( StrC type, StrC hashtable_name )

View File

@ -5,7 +5,7 @@
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body )
{ {
b32 found = false; b32 found = false;
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
@ -16,7 +16,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
s32 depth = 1; s32 depth = 1;
++ entry_iter; ++ entry_iter;
for(b32 continue_for = true; continue_for && entry_iter != body.end(); ) switch for(b32 continue_for = true; continue_for && entry_iter != parsed_body.end(); ) switch
(entry_iter->Type) { (entry_iter->Type) {
case CT_Preprocess_If: case CT_Preprocess_If:
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
@ -27,7 +27,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
case CT_Preprocess_Else: case CT_Preprocess_Else:
++ entry_iter; ++ entry_iter;
for(; continue_for && entry_iter != body.end(); ++ entry_iter) for(; continue_for && entry_iter != parsed_body.end(); ++ entry_iter)
{ {
if (entry_iter->Type == CT_Preprocess_EndIf) if (entry_iter->Type == CT_Preprocess_EndIf)
{ {

View File

@ -5,6 +5,7 @@
#endif #endif
#pragma region Basic Types #pragma region Basic Types
GEN_API_C_BEGIN
#define GEN_U8_MIN 0u #define GEN_U8_MIN 0u
#define GEN_U8_MAX 0xffu #define GEN_U8_MAX 0xffu
@ -127,11 +128,13 @@ typedef void* mem_ptr;
typedef void const* mem_ptr_const ; typedef void const* mem_ptr_const ;
#if ! GEN_COMPILER_C #if ! GEN_COMPILER_C
GEN_API_C_END
template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; } template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; }
template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; } template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; }
template<typename Type> mem_ptr to_mem_ptr ( Type ptr ) { return (mem_ptr) ptr; } template<typename Type> mem_ptr to_mem_ptr ( Type ptr ) { return (mem_ptr) ptr; }
template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; } template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; }
GEN_API_C_BEGIN
#else #else
#define to_uptr( ptr ) ((uptr)(ptr)) #define to_uptr( ptr ) ((uptr)(ptr))
#define to_sptr( ptr ) ((sptr)(ptr)) #define to_sptr( ptr ) ((sptr)(ptr))
@ -140,4 +143,5 @@ template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem
#define to_mem_ptr_const( ptr) ((mem_ptr)ptr) #define to_mem_ptr_const( ptr) ((mem_ptr)ptr)
#endif #endif
GEN_API_C_END
#pragma endregion Basic Types #pragma endregion Basic Types

View File

@ -394,8 +394,8 @@ bool array_set_capacity(Array<Type>* array, usize new_capacity)
// They are undefined in gen.hpp and gen.cpp at the end of the files. // They are undefined in gen.hpp and gen.cpp at the end of the files.
// We cpp library expects the user to use the regular calls as they can resolve the type fine. // We cpp library expects the user to use the regular calls as they can resolve the type fine.
#define array_init(type, allocator) array_init <type> (allocator ) #define array_init(type, allocator) array_init <type> (allocator )
#define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap) #define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)
#define array_append_array(array, other) array_append < get_array_underlying_type(array) > (& array, other ) #define array_append_array(array, other) array_append < get_array_underlying_type(array) > (& array, other )
#define array_append_value(array, value) array_append < get_array_underlying_type(array) > (& array, value ) #define array_append_value(array, value) array_append < get_array_underlying_type(array) > (& array, value )
#define array_append_items(array, items, item_num) array_append < get_array_underlying_type(array) > (& array, items, item_num ) #define array_append_items(array, items, item_num) array_append < get_array_underlying_type(array) > (& array, items, item_num )
@ -423,6 +423,10 @@ bool array_set_capacity(Array<Type>* array, usize new_capacity)
template<class Type> struct HashTable; template<class Type> struct HashTable;
#ifndef get_hashtable_underlying_type
#define get_hashtable_underlying_type(table) typename TRemovePtr<typeof(table)>:: DataType
#endif
struct HashTableFindResult { struct HashTableFindResult {
ssize HashIndex; ssize HashIndex;
ssize PrevIndex; ssize PrevIndex;
@ -483,6 +487,8 @@ struct HashTable
forceinline void map_mut(void (*proc)(u64, Type*)) { GEN_NS map_mut<Type>(*this, proc); } forceinline void map_mut(void (*proc)(u64, Type*)) { GEN_NS map_mut<Type>(*this, proc); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif
using DataType = Type;
}; };
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_SUPPORT_CPP_REFERENCES
@ -708,23 +714,23 @@ bool hashtable_full(HashTable<Type> table) {
return result; return result;
} }
#define hashtable_init(type, allocator) hashtable_init <type>(allocator) #define hashtable_init(type, allocator) hashtable_init <type >(allocator)
#define hashtable_init_reserve(type, allocator, num) hashtable_init_reserve<type>(allocator, num) #define hashtable_init_reserve(type, allocator, num) hashtable_init_reserve<type >(allocator, num)
#define hashtable_clear(table) hashtable_clear < TStripPtr<table> >(table) #define hashtable_clear(table) hashtable_clear < get_hashtable_underlying_type(table) >(table)
#define hashtable_destroy(table) hashtable_destroy < TStripPtr<table> >(& table) #define hashtable_destroy(table) hashtable_destroy < get_hashtable_underlying_type(table) >(& table)
#define hashtable_get(table, key) hashtable_get < TStripPtr<table> >(table, key) #define hashtable_get(table, key) hashtable_get < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_grow(table) hashtable_grow < TStripPtr<table> >(& table) #define hashtable_grow(table) hashtable_grow < get_hashtable_underlying_type(table) >(& table)
#define hashtable_rehash(table, new_num) hashtable_rehash < TStripPtr<table> >(& table, new_num) #define hashtable_rehash(table, new_num) hashtable_rehash < get_hashtable_underlying_type(table) >(& table, new_num)
#define hashtable_rehash_fast(table) hashtable_rehash_fast < TStripPtr<table> >(table) #define hashtable_rehash_fast(table) hashtable_rehash_fast < get_hashtable_underlying_type(table) >(table)
#define hashtable_remove(table, key) hashtable_remove < TStripPtr<table> >(table, key) #define hashtable_remove(table, key) hashtable_remove < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_remove_entry(table, idx) hashtable_remove_entry< TStripPtr<table> >(table, idx) #define hashtable_remove_entry(table, idx) hashtable_remove_entry< get_hashtable_underlying_type(table) >(table, idx)
#define hashtable_set(table, key, value) hashtable_set < TStripPtr<table> >(& table, key, value) #define hashtable_set(table, key, value) hashtable_set < get_hashtable_underlying_type(table) >(& table, key, value)
#define hashtable_slot(table, key) hashtable_slot < TStripPtr<table> >(table, key) #define hashtable_slot(table, key) hashtable_slot < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_add_entry(table, key) hashtable_add_entry < TStripPtr<table> >(& table, key) #define hashtable_add_entry(table, key) hashtable_add_entry < get_hashtable_underlying_type(table) >(& table, key)
#define hashtable_find(table, key) hashtable_find < TStripPtr<table> >(table, key) #define hashtable_find(table, key) hashtable_find < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_full(table) hashtable_full < TStripPtr<table> >(table) #define hashtable_full(table) hashtable_full < get_hashtable_underlying_type(table) >(table)
#define hashtable_map(table, map_proc) hashtable_map < TStripPtr<table> >(table, map_proc) #define hashtable_map(table, map_proc) hashtable_map < get_hashtable_underlying_type(table) >(table, map_proc)
#define hashtable_map_mut(table, map_proc) hashtable_map_mut < TStripPtr<table> >(table, map_proc) #define hashtable_map_mut(table, map_proc) hashtable_map_mut < get_hashtable_underlying_type(table) >(table, map_proc)
#pragma endregion HashTable #pragma endregion HashTable

View File

@ -6,6 +6,7 @@
#endif #endif
#pragma region Debug #pragma region Debug
GEN_API_C_BEGIN
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... ) void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... )
{ {
@ -45,4 +46,5 @@ s32 assert_crash( char const* condition )
} }
#endif #endif
GEN_API_C_END
#pragma endregion Debug #pragma endregion Debug

View File

@ -4,6 +4,7 @@
#endif #endif
#pragma region File Handling #pragma region File Handling
GEN_API_C_BEGIN
#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN ) #if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
@ -655,4 +656,5 @@ GEN_FILE_CLOSE_PROC( _memory_file_close )
FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close }; FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close };
GEN_API_C_END
#pragma endregion File Handling #pragma endregion File Handling

View File

@ -4,10 +4,11 @@
#endif #endif
#pragma region File Handling #pragma region File Handling
GEN_API_C_BEGIN
typedef u32 FileMode; typedef u32 FileMode;
enum FileModeFlag enum FileModeFlag_Def
{ {
EFileMode_READ = bit( 0 ), EFileMode_READ = bit( 0 ),
EFileMode_WRITE = bit( 1 ), EFileMode_WRITE = bit( 1 ),
@ -15,16 +16,18 @@ enum FileModeFlag
EFileMode_RW = bit( 3 ), EFileMode_RW = bit( 3 ),
GEN_FILE_MODES = EFileMode_READ | EFileMode_WRITE | EFileMode_APPEND | EFileMode_RW, GEN_FILE_MODES = EFileMode_READ | EFileMode_WRITE | EFileMode_APPEND | EFileMode_RW,
}; };
typedef enum FileModeFlag_Def FileModeFlag;
// NOTE: Only used internally and for the file operations // NOTE: Only used internally and for the file operations
enum SeekWhenceType enum SeekWhenceType_Def
{ {
ESeekWhence_BEGIN = 0, ESeekWhence_BEGIN = 0,
ESeekWhence_CURRENT = 1, ESeekWhence_CURRENT = 1,
ESeekWhence_END = 2, ESeekWhence_END = 2,
}; };
typedef enum SeekWhenceType_Def SeekWhenceType;
enum FileError enum FileError_Def
{ {
EFileError_NONE, EFileError_NONE,
EFileError_INVALID, EFileError_INVALID,
@ -37,15 +40,17 @@ enum FileError
EFileError_NAME_TOO_LONG, EFileError_NAME_TOO_LONG,
EFileError_UNKNOWN, EFileError_UNKNOWN,
}; };
typedef enum FileError_Def FileError;
union FileDescriptor union FileDescriptor_Def
{ {
void* p; void* p;
sptr i; sptr i;
uptr u; uptr u;
}; };
typedef union FileDescriptor_Def FileDescriptor;
typedef struct FileOperations FileOperations; typedef struct FileOperations_Def FileOperations;
#define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename ) #define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
#define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline ) #define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline )
@ -59,35 +64,39 @@ typedef GEN_FILE_WRITE_AT_PROC( FileWriteProc );
typedef GEN_FILE_SEEK_PROC( FileSeekProc ); typedef GEN_FILE_SEEK_PROC( FileSeekProc );
typedef GEN_FILE_CLOSE_PROC( FileCloseProc ); typedef GEN_FILE_CLOSE_PROC( FileCloseProc );
struct FileOperations struct FileOperations_Def
{ {
FileReadProc* read_at; FileReadProc* read_at;
FileWriteProc* write_at; FileWriteProc* write_at;
FileSeekProc* seek; FileSeekProc* seek;
FileCloseProc* close; FileCloseProc* close;
}; };
typedef struct FileOperations_Def FileOperations;
extern FileOperations const default_file_operations; extern FileOperations const default_file_operations;
typedef u64 FileTime; typedef u64 FileTime;
enum DirType enum DirType_Def
{ {
GEN_DIR_TYPE_FILE, GEN_DIR_TYPE_FILE,
GEN_DIR_TYPE_FOLDER, GEN_DIR_TYPE_FOLDER,
GEN_DIR_TYPE_UNKNOWN, GEN_DIR_TYPE_UNKNOWN,
}; };
typedef enum DirType_Def DirType;
struct DirInfo; struct DirInfo_Def;
typedef struct DirInfo_Def DirInfo;
struct DirEntry struct DirEntry_Def
{ {
char const* filename; char const* filename;
struct DirInfo* dir_info; DirInfo* dir_info;
u8 type; u8 type;
}; };
typedef struct DirEntry_Def DirEntry;
struct DirInfo struct DirInfo_Def
{ {
char const* fullpath; char const* fullpath;
DirEntry* entries; // zpl_array DirEntry* entries; // zpl_array
@ -97,7 +106,7 @@ struct DirInfo
String buf; String buf;
}; };
struct FileInfo struct FileInfo_Def
{ {
FileOperations ops; FileOperations ops;
FileDescriptor fd; FileDescriptor fd;
@ -107,8 +116,9 @@ struct FileInfo
FileTime last_write_time; FileTime last_write_time;
DirEntry* dir; DirEntry* dir;
}; };
typedef struct FileInfo_Def FileInfo;
enum FileStandardType enum FileStandardType_Def
{ {
EFileStandard_INPUT, EFileStandard_INPUT,
EFileStandard_OUTPUT, EFileStandard_OUTPUT,
@ -116,6 +126,7 @@ enum FileStandardType
EFileStandard_COUNT, EFileStandard_COUNT,
}; };
typedef enum FileStandardType_Def FileStandardType;
/** /**
* Get standard file I/O. * Get standard file I/O.
@ -257,7 +268,7 @@ b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
*/ */
b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written ); b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written );
enum FileStreamFlags : u32 enum FileStreamFlags_Def enum_underlying(u32)
{ {
/* Allows us to write to the buffer directly. Beware: you can not append a new data! */ /* Allows us to write to the buffer directly. Beware: you can not append a new data! */
EFileStream_WRITABLE = bit( 0 ), EFileStream_WRITABLE = bit( 0 ),
@ -265,7 +276,10 @@ enum FileStreamFlags : u32
/* Clones the input buffer so you can write (zpl_file_write*) data into it. */ /* Clones the input buffer so you can write (zpl_file_write*) data into it. */
/* Since we work with a clone, the buffer size can dynamically grow as well. */ /* Since we work with a clone, the buffer size can dynamically grow as well. */
EFileStream_CLONE_WRITABLE = bit( 1 ), EFileStream_CLONE_WRITABLE = bit( 1 ),
EFileStream_UNDERLYING = GEN_U32_MAX,
}; };
typedef enum FileStreamFlags_Def FileStreamFlags;
/** /**
* Opens a new memory stream * Opens a new memory stream
@ -381,4 +395,5 @@ b32 file_write_at_check( FileInfo* f, void const* buffer, ssize size, s64 offset
return f->ops.write_at( f->fd, buffer, size, offset, bytes_written ); return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
} }
GEN_API_C_END
#pragma endregion File Handling #pragma endregion File Handling

View File

@ -4,6 +4,7 @@
#endif #endif
#pragma region Hashing #pragma region Hashing
GEN_API_C_BEGIN
global u32 const _crc32_table[ 256 ] = { global u32 const _crc32_table[ 256 ] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
@ -87,4 +88,5 @@ u64 crc64( void const* data, ssize len )
return result; return result;
} }
GEN_API_C_END
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -4,12 +4,10 @@
#endif #endif
#pragma region Hashing #pragma region Hashing
GEN_API_C_BEGIN GEN_API_C_BEGIN
u32 crc32( void const* data, ssize len ); u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len ); u64 crc64( void const* data, ssize len );
GEN_API_C_END GEN_API_C_END
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -183,6 +183,18 @@
# endif # endif
#endif #endif
#if GEN_COMPILER_CPP
// Already Defined
#elif GEN_COMPILER_C && __STDC_VERSION__ >= 201112L
# define thread_local _Thread_local
#elif GEN_COMPILER_MSVC
# define thread_local __declspec(thread)
#elif GEN_COMPILER_CLANG
# define thread_local __thread
#else
# error "No thread local support"
#endif
#if !defined(GEN_SUPPORT_CPP_REFERENCES) #if !defined(GEN_SUPPORT_CPP_REFERENCES)
# define GEN_SUPPORT_CPP_REFERENCES 1 # define GEN_SUPPORT_CPP_REFERENCES 1
#endif #endif
@ -203,7 +215,7 @@
# if ! GEN_COMPILER_C # if ! GEN_COMPILER_C
# define typeof decltype # define typeof decltype
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# define typeof(x) __typeof(x) # define typeof(x) __typeof__(x)
# elif defined(__GNUC__) || defined(__clang__) # elif defined(__GNUC__) || defined(__clang__)
# define typeof(x) __typeof__(x) # define typeof(x) __typeof__(x)
# else # else
@ -247,4 +259,10 @@
# define GEN_PARAM_DEFAULT # define GEN_PARAM_DEFAULT
#endif #endif
#if GEN_COMPILER_CPP
#define struct_init(type, value) {value}
#else
#define struct_init(type, value) {value}
#endif
#pragma endregion Macros #pragma endregion Macros

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region Memory #pragma region Memory
GEN_API_C_BEGIN GEN_API_C_BEGIN
void* mem_copy( void* dest, void const* source, ssize n ) void* mem_copy( void* dest, void const* source, ssize n )
@ -520,5 +519,4 @@ void pool_clear(Pool* pool)
} }
GEN_API_C_END GEN_API_C_END
#pragma endregion Memory #pragma endregion Memory

View File

@ -3,6 +3,7 @@
#endif #endif
#pragma region ADT #pragma region ADT
GEN_API_C_BEGIN
#define _adt_fprintf( s_, fmt_, ... ) \ #define _adt_fprintf( s_, fmt_, ... ) \
do \ do \
@ -1110,5 +1111,5 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
return output; return output;
} }
GEN_API_C_END
#pragma endregion CSV #pragma endregion CSV

View File

@ -3,6 +3,7 @@
#endif #endif
#pragma region ADT #pragma region ADT
GEN_API_C_BEGIN
enum ADT_Type : u32 enum ADT_Type : u32
{ {
@ -429,4 +430,5 @@ String csv_write_string( AllocatorInfo a, CSV_Object* obj )
return csv_write_string_delimiter( a, obj, ',' ); return csv_write_string_delimiter( a, obj, ',' );
} }
GEN_API_C_END
#pragma endregion CSV #pragma endregion CSV

View File

@ -158,7 +158,7 @@
# define GEN_NS_PARSER_END } # define GEN_NS_PARSER_END }
# define GEN_USING_NS_PARSER using namespace parser # define GEN_USING_NS_PARSER using namespace parser
# define GEN_NS_PARSER parser:: # define GEN_NS_PARSER parser::
# define GEN_NS :: # define GEN_NS ::
# define GEN_NS_BEGIN # define GEN_NS_BEGIN
# define GEN_NS_END # define GEN_NS_END
# endif # endif
@ -167,7 +167,7 @@
# define GEN_NS_PARSER_END } # define GEN_NS_PARSER_END }
# define GEN_NS_PARSER parser:: # define GEN_NS_PARSER parser::
# define GEN_USING_NS_PARSER using namespace parser # define GEN_USING_NS_PARSER using namespace parser
# define GEN_NS gen:: # define GEN_NS gen::
# define GEN_NS_BEGIN namespace gen { # define GEN_NS_BEGIN namespace gen {
# define GEN_NS_END } # define GEN_NS_END }
#endif #endif

View File

@ -6,6 +6,7 @@
#endif #endif
#pragma region Printing #pragma region Printing
GEN_API_C_BEGIN
enum enum
{ {
@ -549,7 +550,7 @@ char* str_fmt_buf( char const* fmt, ... )
return str; return str;
} }
ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va ) ssize str_fmt_file_va( FileInfo* f, char const* fmt, va_list va )
{ {
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ]; local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
ssize len = str_fmt_va( buf, size_of( buf ), fmt, va ); ssize len = str_fmt_va( buf, size_of( buf ), fmt, va );
@ -557,7 +558,7 @@ ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
return res ? len : -1; return res ? len : -1;
} }
ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... ) ssize str_fmt_file( FileInfo* f, char const* fmt, ... )
{ {
ssize res; ssize res;
va_list va; va_list va;
@ -597,4 +598,5 @@ ssize str_fmt_out_err( char const* fmt, ... )
return res; return res;
} }
GEN_API_C_END
#pragma endregion Printing #pragma endregion Printing

View File

@ -7,11 +7,12 @@
GEN_API_C_BEGIN GEN_API_C_BEGIN
struct FileInfo; typedef struct FileInfo_Def FileInfo;
#ifndef GEN_PRINTF_MAXLEN #ifndef GEN_PRINTF_MAXLEN
# define GEN_PRINTF_MAXLEN kilobytes(128) # define GEN_PRINTF_MAXLEN kilobytes(128)
#endif #endif
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
// NOTE: A locally persisting buffer is used internally // NOTE: A locally persisting buffer is used internally
char* str_fmt_buf ( char const* fmt, ... ); char* str_fmt_buf ( char const* fmt, ... );

View File

@ -5,6 +5,7 @@
#endif #endif
#pragma region String Ops #pragma region String Ops
GEN_API_C_BEGIN
internal internal
ssize _scan_zpl_i64( const char* text, s32 base, s64* value ) ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
@ -212,4 +213,5 @@ f64 str_to_f64( const char* str, char** end_ptr )
return result; return result;
} }
GEN_API_C_END
#pragma endregion String Ops #pragma endregion String Ops

View File

@ -4,6 +4,8 @@
#endif #endif
#pragma region String #pragma region String
GEN_API_C_BEGIN
String string_make_length( AllocatorInfo allocator, char const* str, ssize length ) String string_make_length( AllocatorInfo allocator, char const* str, ssize length )
{ {
constexpr ssize header_size = sizeof( StringHeader ); constexpr ssize header_size = sizeof( StringHeader );
@ -51,4 +53,6 @@ String string_make_reserve( AllocatorInfo allocator, ssize capacity )
String result = { rcast(char*, allocation) + header_size }; String result = { rcast(char*, allocation) + header_size };
return result; return result;
} }
GEN_API_C_END
#pragma endregion String #pragma endregion String

View File

@ -7,7 +7,8 @@
GEN_API_C_BEGIN GEN_API_C_BEGIN
struct StrC; struct StrC_Def;
typedef struct StrC_Def StrC;
bool strc_are_equal (StrC lhs, StrC rhs); bool strc_are_equal (StrC lhs, StrC rhs);
char const* strc_back (StrC str); char const* strc_back (StrC str);
@ -20,7 +21,7 @@ StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator);
GEN_API_C_END GEN_API_C_END
// Constant string with length. // Constant string with length.
struct StrC struct StrC_Def
{ {
ssize Len; ssize Len;
char const* Ptr; char const* Ptr;
@ -41,7 +42,14 @@ struct StrC
}; };
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
#ifndef txt
# if GEN_COMPILER_CPP
# define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
# else
# define txt( text ) (StrC){ sizeof( text ) - 1, ( text ) }
# endif
#endif
GEN_API_C_BEGIN GEN_API_C_BEGIN
forceinline char const* strc_begin(StrC str) { return str.Ptr; } forceinline char const* strc_begin(StrC str) { return str.Ptr; }
@ -64,7 +72,7 @@ bool strc_are_equal(StrC lhs, StrC rhs)
return false; return false;
for (ssize idx = 0; idx < lhs.Len; ++idx) for (ssize idx = 0; idx < lhs.Len; ++idx)
if (lhs[idx] != rhs[idx]) if (lhs.Ptr[idx] != rhs.Ptr[idx])
return false; return false;
return true; return true;
@ -102,7 +110,8 @@ b32 strc_starts_with(StrC str, StrC substring) {
inline inline
StrC to_strc_from_c_str( char const* bad_str ) { StrC to_strc_from_c_str( char const* bad_str ) {
return { str_len( bad_str ), bad_str }; StrC result = { str_len( bad_str ), bad_str };
return result;
} }
GEN_API_C_END GEN_API_C_END
@ -111,7 +120,8 @@ GEN_API_C_END
// They used a header pattern // They used a header pattern
// I kept it for simplicty of porting but its not necessary to keep it that way. // I kept it for simplicty of porting but its not necessary to keep it that way.
#pragma region String #pragma region String
struct StringHeader; struct StringHeader_Def;
typedef struct StringHeader_Def StringHeader;
#if GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES
typedef char* String; typedef char* String;
@ -160,7 +170,7 @@ String string_visualize_whitespace(String const str);
GEN_API_C_END GEN_API_C_END
struct StringHeader { struct StringHeader_Def {
AllocatorInfo Allocator; AllocatorInfo Allocator;
ssize Capacity; ssize Capacity;
ssize Length; ssize Length;
@ -324,7 +334,7 @@ inline
String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...) String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
{ {
local_persist thread_local local_persist thread_local
char buf[GEN_PRINTF_MAXLEN] = { 0 }; PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
@ -366,7 +376,7 @@ inline
bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length) bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length)
{ {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
if (sptr(str_to_append) > 0) if ( rcast(sptr, str_to_append) > 0)
{ {
ssize curr_len = string_length(* str); ssize curr_len = string_length(* str);
@ -521,8 +531,8 @@ StringHeader* string_get_header(String str) {
forceinline forceinline
ssize string_length(String const str) ssize string_length(String const str)
{ {
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
return header.Length; return header->Length;
} }
inline inline
@ -627,7 +637,8 @@ void strip_space(String str)
forceinline forceinline
StrC string_to_strc(String str) { StrC string_to_strc(String str) {
return { string_length(str), (char const*)str }; StrC result = { string_length(str), (char const*)str };
return result;
} }
inline inline
@ -695,15 +706,17 @@ String visualize_whitespace(String const str)
} }
#pragma endregion String #pragma endregion String
#if GEN_COMPILER_CPP
struct String_POD { struct String_POD {
char* Data; char* Data;
}; };
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
#endif
forceinline forceinline
StrC strc_duplicate(StrC str, AllocatorInfo allocator) { StrC strc_duplicate(StrC str, AllocatorInfo allocator) {
String result = string_make_length(allocator, str.Ptr, str.Len); StrC result = string_to_strc( string_make_length(allocator, str.Ptr, str.Len));
return { string_get_header(result)->Length, result }; return result;
} }
inline inline
@ -745,5 +758,5 @@ typedef StrC StringCached;
GEN_API_C_END GEN_API_C_END
// Implements basic string interning. Data structure is based off the ZPL Hashtable. // Implements basic string interning. Data structure is based off the ZPL Hashtable.
typedef HashTable<StringCached> StringTable; typedef HashTable(StringCached) StringTable;
#pragma endregion Strings #pragma endregion Strings

View File

@ -4,6 +4,7 @@
#endif #endif
#pragma region Timing #pragma region Timing
GEN_API_C_BEGIN
#ifdef GEN_BENCHMARK #ifdef GEN_BENCHMARK
#if defined( GEN_COMPILER_MSVC ) && ! defined( __clang__ ) #if defined( GEN_COMPILER_MSVC ) && ! defined( __clang__ )
@ -164,4 +165,5 @@
} }
#endif #endif
GEN_API_C_END
#pragma endregion Timing #pragma endregion Timing

View File

@ -5,6 +5,8 @@
#pragma region Timing #pragma region Timing
GEN_API_C_BEGIN
#ifdef GEN_BENCHMARK #ifdef GEN_BENCHMARK
//! Return CPU timestamp. //! Return CPU timestamp.
u64 read_cpu_time_stamp_counter( void ); u64 read_cpu_time_stamp_counter( void );
@ -16,4 +18,6 @@ f64 time_rel( void );
u64 time_rel_ms( void ); u64 time_rel_ms( void );
#endif #endif
GEN_API_C_END
#pragma endregion Timing #pragma endregion Timing

View File

@ -13,8 +13,8 @@
// They are undefined in gen.hpp and gen.cpp at the end of the files. // They are undefined in gen.hpp and gen.cpp at the end of the files.
// We cpp library expects the user to use the regular calls as they can resolve the type fine. // We cpp library expects the user to use the regular calls as they can resolve the type fine.
#define array_init(type, allocator) array_init <type> (allocator ) #define array_init(type, allocator) array_init <type> (allocator )
#define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap) #define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)
#define array_append_array(array, other) array_append < get_array_underlying_type(array) > (& array, other ) #define array_append_array(array, other) array_append < get_array_underlying_type(array) > (& array, other )
#define array_append_value(array, value) array_append < get_array_underlying_type(array) > (& array, value ) #define array_append_value(array, value) array_append < get_array_underlying_type(array) > (& array, value )
#define array_append_items(array, items, item_num) array_append < get_array_underlying_type(array) > (& array, items, item_num ) #define array_append_items(array, items, item_num) array_append < get_array_underlying_type(array) > (& array, items, item_num )
@ -33,23 +33,23 @@
#define arary_set_capacity(new_capacity) arary_set_capacity < get_array_underlying_type(array) > (& array, new_capacity ) #define arary_set_capacity(new_capacity) arary_set_capacity < get_array_underlying_type(array) > (& array, new_capacity )
#define arary_get_header(array) arary_get_header < get_array_underlying_type(array) > (array ) #define arary_get_header(array) arary_get_header < get_array_underlying_type(array) > (array )
#define hashtable_init(type, allocator) hashtable_init <type>(allocator) #define hashtable_init(type, allocator) hashtable_init <type >(allocator)
#define hashtable_init_reserve(type, allocator, num) hashtable_init_reserve<type>(allocator, num) #define hashtable_init_reserve(type, allocator, num) hashtable_init_reserve<type >(allocator, num)
#define hashtable_clear(table) hashtable_clear (table) #define hashtable_clear(table) hashtable_clear < get_hashtable_underlying_type(table) >(table)
#define hashtable_destroy(table) hashtable_destroy (& table) #define hashtable_destroy(table) hashtable_destroy < get_hashtable_underlying_type(table) >(& table)
#define hashtable_get(table, key) hashtable_get (table, key) #define hashtable_get(table, key) hashtable_get < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_grow(table) hashtable_grow (& table) #define hashtable_grow(table) hashtable_grow < get_hashtable_underlying_type(table) >(& table)
#define hashtable_rehash(table, new_num) hashtable_rehash (& table, new_num) #define hashtable_rehash(table, new_num) hashtable_rehash < get_hashtable_underlying_type(table) >(& table, new_num)
#define hashtable_rehash_fast(table) hashtable_rehash_fast (table) #define hashtable_rehash_fast(table) hashtable_rehash_fast < get_hashtable_underlying_type(table) >(table)
#define hashtable_remove(table, key) hashtable_remove (table, key) #define hashtable_remove(table, key) hashtable_remove < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_remove_entry(table, idx) hashtable_remove_entry(table, idx) #define hashtable_remove_entry(table, idx) hashtable_remove_entry< get_hashtable_underlying_type(table) >(table, idx)
#define hashtable_set(table, key, value) hashtable_set (& table, key, value) #define hashtable_set(table, key, value) hashtable_set < get_hashtable_underlying_type(table) >(& table, key, value)
#define hashtable_slot(table, key) hashtable_slot (table, key) #define hashtable_slot(table, key) hashtable_slot < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_add_entry(table, key) hashtable_add_entry (& table, key) #define hashtable_add_entry(table, key) hashtable_add_entry < get_hashtable_underlying_type(table) >(& table, key)
#define hashtable_find(table, key) hashtable_find (table, key) #define hashtable_find(table, key) hashtable_find < get_hashtable_underlying_type(table) >(table, key)
#define hashtable_full(table) hashtable_full (table) #define hashtable_full(table) hashtable_full < get_hashtable_underlying_type(table) >(table)
#define hashtable_map(table, map_proc) hashtable_map (table, map_proc) #define hashtable_map(table, map_proc) hashtable_map < get_hashtable_underlying_type(table) >(table, map_proc)
#define hashtable_map_mut(table, map_proc) hashtable_map_mut (table, map_proc) #define hashtable_map_mut(table, map_proc) hashtable_map_mut < get_hashtable_underlying_type(table) >(table, map_proc)
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl //! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl

View File

@ -1,26 +1,19 @@
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #define array_init(type, allocator) array_init <type> (allocator )
// These are intended for use in the base library of gencpp and the C-variant of the library #define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)
// It provides a interoperability between the C++ and C implementation of arrays. (not letting these do any crazy substiution though) #define array_append_array(array, other) array_append < get_array_underlying_type(array) > (& array, other )
// They are undefined in gen.hpp and gen.cpp at the end of the files. #define array_append_value(array, value) array_append < get_array_underlying_type(array) > (& array, value )
// We cpp library expects the user to use the regular calls as they can resolve the type fine. #define array_append_items(array, items, item_num) array_append < get_array_underlying_type(array) > (& array, items, item_num )
#define array_append_at(array, item, idx ) array_append_at < get_array_underlying_type(array) > (& array, item, idx )
#define array_init(type, allocator) array_init <typeof(array)>(type, allocator ) #define array_append_at_items(array, items, item_num, idx) array_append_at_items< get_array_underlying_type(array) > (& items, item_num, idx )
#define array_init_reserve(type, allocator, cap) array_init_reserve<typeof(array)>(type, allocator, cap) #define array_back(array) array_back < get_array_underlying_type(array) > (array )
#define array_append_array(type, array, other) array_append <typeof(array)>(type, & array, other ) #define array_clear(array) array_clear < get_array_underlying_type(array) > (array )
#define array_append_value(type, array, value) array_append <typeof(array)>(type, & array, value ) #define array_fill(array, begin, end, value) array_fill < get_array_underlying_type(array) > (array, begin, end, value )
#define array_append_items(type, array, items, item_num) array_append <typeof(array)>(type, & array, items, item_num ) #define array_free(array) array_free < get_array_underlying_type(array) > (& array )
#define array_append_at(type, array, item, idx ) array_append_at <typeof(array)>(type, & array, item, idx ) #define arary_grow(array, min_capacity) arary_grow < get_array_underlying_type(array) > (& array, min_capacity)
#define array_append_at(type, array, items, item_num, idx) array_append_at <typeof(array)>(type, & items, item_num, idx ) #define array_num(array) array_num < get_array_underlying_type(array) > (array )
#define array_back(type, array ) array_back <typeof(array)>(type, array ) #define arary_pop(array) arary_pop < get_array_underlying_type(array) > (array )
#define array_clear(type, array ) array_clear <typeof(array)>(type, array ) #define arary_remove_at(array, idx) arary_remove_at < get_array_underlying_type(array) > (idx)
#define array_fill(type, array, begin, end, value) array_fill <typeof(array)>(type, array, begin, end, value ) #define arary_reserve(array, new_capacity) arary_reserve < get_array_underlying_type(array) > (& array, new_capacity )
#define array_free(type, array) array_free <typeof(array)>(type, & array ) #define arary_resize(array, num) arary_resize < get_array_underlying_type(array) > (& array, num)
#define arary_grow(type, array, min_capacity) arary_grow <typeof(array)>(type, & array, min_capacity) #define arary_set_capacity(new_capacity) arary_set_capacity < get_array_underlying_type(array) > (& array, new_capacity )
#define array_num(type, array) array_num <typeof(array)>(type, array ) #define arary_get_header(array) arary_get_header < get_array_underlying_type(array) > (array )
#define arary_pop(type, array) arary_pop <typeof(array)>(type, array )
#define arary_remove_at(type, array, idx) arary_remove_at <typeof(array)>(type, idx)
#define arary_reserve(type, array, new_capacity) arary_reserve <typeof(array)>(type, & array, new_capacity )
#define arary_resize(type, array, num) arary_resize <typeof(array)>(type, & array, num)
#define arary_set_capacity(array, new_capacity) arary_set_capacity<typeof(array)>(type, & array, new_capacity )
#define arary_get_header(array) arary_get_header <typeof(array)>(type, array )
#endif