mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 14:30:53 -07:00 
			
		
		
		
	gencpp : General refactors to dependencies
Mostly just cleanup and renaming of certain stuff (mostly in dependencies). * Changed uw and sw to usize and ssize. * Removed zpl_cast usage throughout dependencies * No longer using GEN_DEF_INLINE & GEN_IMPL_INLINE * header_start.hpp renamed to platform.hpp for depdendencies header.
This commit is contained in:
		| @@ -47,21 +47,21 @@ | ||||
| #if defined( GEN_COMPILER_MSVC ) | ||||
| #	if _MSC_VER < 1300 | ||||
| typedef unsigned char  u8; | ||||
| typedef signed char    s8; | ||||
| typedef signed   char  s8; | ||||
| typedef unsigned short u16; | ||||
| typedef signed short   s16; | ||||
| typedef signed   short s16; | ||||
| typedef unsigned int   u32; | ||||
| typedef signed int     s32; | ||||
| typedef signed   int   s32; | ||||
| #    else | ||||
| typedef unsigned __int8  u8; | ||||
| typedef signed __int8    s8; | ||||
| typedef signed   __int8  s8; | ||||
| typedef unsigned __int16 u16; | ||||
| typedef signed __int16   s16; | ||||
| typedef signed   __int16 s16; | ||||
| typedef unsigned __int32 u32; | ||||
| typedef signed __int32   s32; | ||||
| typedef signed   __int32 s32; | ||||
| #    endif | ||||
| typedef unsigned __int64 u64; | ||||
| typedef signed __int64   s64; | ||||
| typedef signed   __int64 s64; | ||||
| #else | ||||
| #	include <stdint.h> | ||||
|  | ||||
| @@ -85,10 +85,10 @@ static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" ); | ||||
| static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" ); | ||||
| static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" ); | ||||
|  | ||||
| typedef size_t    uw; | ||||
| typedef ptrdiff_t sw; | ||||
| typedef size_t    usize; | ||||
| typedef ptrdiff_t ssize; | ||||
|  | ||||
| static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" ); | ||||
| static_assert( sizeof( usize ) == sizeof( ssize ), "sizeof(usize) != sizeof(ssize)" ); | ||||
|  | ||||
| // NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes. | ||||
| #if defined( _WIN64 ) | ||||
| @@ -122,4 +122,13 @@ typedef s8  b8; | ||||
| typedef s16 b16; | ||||
| typedef s32 b32; | ||||
|  | ||||
| using mem_ptr       = void*; | ||||
| using mem_ptr_const = void const*; | ||||
|  | ||||
| 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> 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; } | ||||
|  | ||||
| #pragma endregion Basic Types | ||||
|   | ||||
| @@ -5,10 +5,10 @@ | ||||
|  | ||||
| #pragma region Containers | ||||
|  | ||||
| template<class TType>          struct RemoveConst                    { typedef TType Type;       }; | ||||
| template<class TType>          struct RemoveConst<const TType>       { typedef TType Type;       }; | ||||
| template<class TType>          struct RemoveConst<const TType[]>     { typedef TType Type[];     }; | ||||
| template<class TType, uw Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; }; | ||||
| template<class TType>             struct RemoveConst                    { typedef TType Type;       }; | ||||
| template<class TType>             struct RemoveConst<const TType>       { typedef TType Type;       }; | ||||
| template<class TType>             struct RemoveConst<const TType[]>     { typedef TType Type[];     }; | ||||
| template<class TType, usize Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; }; | ||||
|  | ||||
| template<class TType> | ||||
| using TRemoveConst = typename RemoveConst<TType>::Type; | ||||
| @@ -19,8 +19,8 @@ struct Array | ||||
| 	struct Header | ||||
| 	{ | ||||
| 		AllocatorInfo Allocator; | ||||
| 		uw            Capacity; | ||||
| 		uw            Num; | ||||
| 		usize            Capacity; | ||||
| 		usize            Num; | ||||
| 	}; | ||||
|  | ||||
| 	static | ||||
| @@ -30,7 +30,7 @@ struct Array | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	Array init_reserve( AllocatorInfo allocator, sw capacity ) | ||||
| 	Array init_reserve( AllocatorInfo allocator, ssize capacity ) | ||||
| 	{ | ||||
| 		Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) * capacity )); | ||||
|  | ||||
| @@ -45,7 +45,7 @@ struct Array | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	uw grow_formula( uw value ) | ||||
| 	usize grow_formula( usize value ) | ||||
| 	{ | ||||
| 		return 2 * value + 8; | ||||
| 	} | ||||
| @@ -73,7 +73,7 @@ struct Array | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool append( Type* items, uw item_num ) | ||||
| 	bool append( Type* items, usize item_num ) | ||||
| 	{ | ||||
| 		Header* header = get_header(); | ||||
|  | ||||
| @@ -91,7 +91,7 @@ struct Array | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool append_at( Type item, uw idx ) | ||||
| 	bool append_at( Type item, usize idx ) | ||||
| 	{ | ||||
| 		Header* header = get_header(); | ||||
|  | ||||
| @@ -117,7 +117,7 @@ struct Array | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool append_at( Type* items, uw item_num, uw idx ) | ||||
| 	bool append_at( Type* items, usize item_num, usize idx ) | ||||
| 	{ | ||||
| 		Header* header = get_header(); | ||||
|  | ||||
| @@ -156,14 +156,14 @@ struct Array | ||||
| 		header.Num     = 0; | ||||
| 	} | ||||
|  | ||||
| 	bool fill( uw begin, uw end, Type value ) | ||||
| 	bool fill( usize begin, usize end, Type value ) | ||||
| 	{ | ||||
| 		Header& header = * get_header(); | ||||
|  | ||||
| 		if ( begin < 0 || end > header.Num ) | ||||
| 			return false; | ||||
|  | ||||
| 		for ( sw idx = sw(begin); idx < sw(end); idx++ ) | ||||
| 		for ( ssize idx = ssize(begin); idx < ssize(end); idx++ ) | ||||
| 		{ | ||||
| 			Data[ idx ] = value; | ||||
| 		} | ||||
| @@ -184,10 +184,10 @@ struct Array | ||||
| 		return rcast( Header*, const_cast<NonConstType*>(Data) ) - 1 ; | ||||
| 	} | ||||
|  | ||||
| 	bool grow( uw min_capacity ) | ||||
| 	bool grow( usize min_capacity ) | ||||
| 	{ | ||||
| 		Header& header       = * get_header(); | ||||
| 		uw      new_capacity = grow_formula( header.Capacity ); | ||||
| 		usize      new_capacity = grow_formula( header.Capacity ); | ||||
|  | ||||
| 		if ( new_capacity < min_capacity ) | ||||
| 			new_capacity = min_capacity; | ||||
| @@ -195,7 +195,7 @@ struct Array | ||||
| 		return set_capacity( new_capacity ); | ||||
| 	} | ||||
|  | ||||
| 	uw num( void ) | ||||
| 	usize num( void ) | ||||
| 	{ | ||||
| 		return get_header()->Num; | ||||
| 	} | ||||
| @@ -208,7 +208,7 @@ struct Array | ||||
| 		header.Num--; | ||||
| 	} | ||||
|  | ||||
| 	void remove_at( uw idx ) | ||||
| 	void remove_at( usize idx ) | ||||
| 	{ | ||||
| 		Header* header = get_header(); | ||||
| 		GEN_ASSERT( idx < header->Num ); | ||||
| @@ -217,7 +217,7 @@ struct Array | ||||
| 		header->Num--; | ||||
| 	} | ||||
|  | ||||
| 	bool reserve( uw new_capacity ) | ||||
| 	bool reserve( usize new_capacity ) | ||||
| 	{ | ||||
| 		Header& header = * get_header(); | ||||
|  | ||||
| @@ -227,7 +227,7 @@ struct Array | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool resize( uw num ) | ||||
| 	bool resize( usize num ) | ||||
| 	{ | ||||
| 		Header* header = get_header(); | ||||
|  | ||||
| @@ -243,7 +243,7 @@ struct Array | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool set_capacity( uw new_capacity ) | ||||
| 	bool set_capacity( usize new_capacity ) | ||||
| 	{ | ||||
| 		Header& header = * get_header(); | ||||
|  | ||||
| @@ -257,7 +257,7 @@ struct Array | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		sw      size       = sizeof( Header ) + sizeof( Type ) * new_capacity; | ||||
| 		ssize      size       = sizeof( Header ) + sizeof( Type ) * new_capacity; | ||||
| 		Header* new_header = rcast( Header*, alloc( header.Allocator, size ) ); | ||||
|  | ||||
| 		if ( new_header == nullptr ) | ||||
| @@ -305,15 +305,15 @@ struct HashTable | ||||
| { | ||||
| 	struct FindResult | ||||
| 	{ | ||||
| 		sw HashIndex; | ||||
| 		sw PrevIndex; | ||||
| 		sw EntryIndex; | ||||
| 		ssize HashIndex; | ||||
| 		ssize PrevIndex; | ||||
| 		ssize EntryIndex; | ||||
| 	}; | ||||
|  | ||||
| 	struct Entry | ||||
| 	{ | ||||
| 		u64  Key; | ||||
| 		sw   Next; | ||||
| 		ssize   Next; | ||||
| 		Type Value; | ||||
| 	}; | ||||
|  | ||||
| @@ -327,11 +327,11 @@ struct HashTable | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	HashTable init_reserve( AllocatorInfo allocator, uw num ) | ||||
| 	HashTable init_reserve( AllocatorInfo allocator, usize num ) | ||||
| 	{ | ||||
| 		HashTable<Type> result = { { nullptr }, { nullptr } }; | ||||
|  | ||||
| 		result.Hashes  = Array<sw>::init_reserve( allocator, num ); | ||||
| 		result.Hashes  = Array<ssize>::init_reserve( allocator, num ); | ||||
| 		result.Hashes.get_header()->Num = num; | ||||
| 		result.Hashes.resize( num ); | ||||
| 		result.Hashes.fill( 0, num, -1); | ||||
| @@ -357,7 +357,7 @@ struct HashTable | ||||
|  | ||||
| 	Type* get( u64 key ) | ||||
| 	{ | ||||
| 		sw idx = find( key ).EntryIndex; | ||||
| 		ssize idx = find( key ).EntryIndex; | ||||
| 		if ( idx >= 0 ) | ||||
| 			return & Entries[ idx ].Value; | ||||
|  | ||||
| @@ -370,7 +370,7 @@ struct HashTable | ||||
| 	{ | ||||
| 		GEN_ASSERT_NOT_NULL( map_proc ); | ||||
|  | ||||
| 		for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx ) | ||||
| 		{ | ||||
| 			map_proc( Entries[ idx ].Key, Entries[ idx ].Value ); | ||||
| 		} | ||||
| @@ -382,7 +382,7 @@ struct HashTable | ||||
| 	{ | ||||
| 		GEN_ASSERT_NOT_NULL( map_proc ); | ||||
|  | ||||
| 		for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx ) | ||||
| 		{ | ||||
| 			map_proc( Entries[ idx ].Key, & Entries[ idx ].Value ); | ||||
| 		} | ||||
| @@ -390,16 +390,16 @@ struct HashTable | ||||
|  | ||||
| 	void grow() | ||||
| 	{ | ||||
| 		sw new_num = Array<Entry>::grow_formula( Entries.num() ); | ||||
| 		ssize new_num = Array<Entry>::grow_formula( Entries.num() ); | ||||
| 		rehash( new_num ); | ||||
| 	} | ||||
|  | ||||
| 	void rehash( sw new_num ) | ||||
| 	void rehash( ssize new_num ) | ||||
| 	{ | ||||
| 		sw last_added_index; | ||||
| 		ssize last_added_index; | ||||
|  | ||||
| 		HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num ); | ||||
| 		for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx ) | ||||
| 		{ | ||||
| 			FindResult find_result; | ||||
|  | ||||
| @@ -422,15 +422,15 @@ struct HashTable | ||||
|  | ||||
| 	void rehash_fast() | ||||
| 	{ | ||||
| 		sw idx; | ||||
| 		ssize idx; | ||||
|  | ||||
| 		for ( idx = 0; idx < sw(Entries.num()); idx++ ) | ||||
| 		for ( idx = 0; idx < ssize(Entries.num()); idx++ ) | ||||
| 			Entries[ idx ].Next = -1; | ||||
|  | ||||
| 		for ( idx = 0; idx < sw(Hashes.num()); idx++ ) | ||||
| 		for ( idx = 0; idx < ssize(Hashes.num()); idx++ ) | ||||
| 			Hashes[ idx ] = -1; | ||||
|  | ||||
| 		for ( idx = 0; idx < sw(Entries.num()); idx++ ) | ||||
| 		for ( idx = 0; idx < ssize(Entries.num()); idx++ ) | ||||
| 		{ | ||||
| 			Entry*     entry; | ||||
| 			FindResult find_result; | ||||
| @@ -456,14 +456,14 @@ struct HashTable | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void remove_entry( sw idx ) | ||||
| 	void remove_entry( ssize idx ) | ||||
| 	{ | ||||
| 		Entries.remove_at( idx ); | ||||
| 	} | ||||
|  | ||||
| 	void set( u64 key, Type value ) | ||||
| 	{ | ||||
| 		sw idx; | ||||
| 		ssize idx; | ||||
| 		FindResult find_result; | ||||
|  | ||||
| 		if ( full() ) | ||||
| @@ -494,23 +494,23 @@ struct HashTable | ||||
| 			grow(); | ||||
| 	} | ||||
|  | ||||
| 	sw slot( u64 key ) | ||||
| 	ssize slot( u64 key ) | ||||
| 	{ | ||||
| 		for ( sw idx = 0; idx < sw(Hashes.num()); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < ssize(Hashes.num()); ++idx ) | ||||
| 			if ( Hashes[ idx ] == key ) | ||||
| 				return idx; | ||||
|  | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	Array< sw>    Hashes; | ||||
| 	Array< ssize>    Hashes; | ||||
| 	Array< Entry> Entries; | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	sw add_entry( u64 key ) | ||||
| 	ssize add_entry( u64 key ) | ||||
| 	{ | ||||
| 		sw idx; | ||||
| 		ssize idx; | ||||
| 		Entry entry = { key, -1 }; | ||||
|  | ||||
| 		idx = Entries.num(); | ||||
| @@ -542,7 +542,7 @@ protected: | ||||
|  | ||||
| 	b32 full() | ||||
| 	{ | ||||
| 		uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) ); | ||||
| 		usize critical_load = usize( CriticalLoadScale * f32(Hashes.num()) ); | ||||
| 		b32 result = Entries.num() > critical_load; | ||||
| 		return result; | ||||
| 	} | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| 	{                                                                                        \ | ||||
| 		if ( ! ( cond ) )                                                                    \ | ||||
| 		{                                                                                    \ | ||||
| 			assert_handler( #cond, __FILE__, zpl_cast( s64 ) __LINE__, msg, ##__VA_ARGS__ ); \ | ||||
| 			assert_handler( #cond, __FILE__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \ | ||||
| 			GEN_DEBUG_TRAP();                                                                \ | ||||
| 		}                                                                                    \ | ||||
| 	} while ( 0 ) | ||||
| @@ -34,10 +34,6 @@ | ||||
| // NOTE: Things that shouldn't happen with a message! | ||||
| #define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ ) | ||||
|  | ||||
| void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... ); | ||||
| s32  assert_crash( char const* condition ); | ||||
| void process_exit( u32 code ); | ||||
|  | ||||
| #if Build_Debug | ||||
| 	#define GEN_FATAL( ... )                               \ | ||||
| 	do                                                     \ | ||||
| @@ -60,4 +56,8 @@ void process_exit( u32 code ); | ||||
| 	while (0) | ||||
| #endif | ||||
|  | ||||
| void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... ); | ||||
| s32  assert_crash( char const* condition ); | ||||
| void process_exit( u32 code ); | ||||
|  | ||||
| #pragma endregion Debug | ||||
|   | ||||
| @@ -7,10 +7,11 @@ | ||||
|  | ||||
| #if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN ) | ||||
|  | ||||
| internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_len_ ) | ||||
| internal | ||||
| wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ ) | ||||
| { | ||||
| 	wchar_t* w_text = NULL; | ||||
| 	sw       len = 0, w_len = 0, w_len1 = 0; | ||||
| 	ssize       len = 0, w_len = 0, w_len1 = 0; | ||||
| 	if ( text == NULL ) | ||||
| 	{ | ||||
| 		if ( w_len_ ) | ||||
| @@ -24,7 +25,7 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_ | ||||
| 			*w_len_ = w_len; | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, NULL, 0 ); | ||||
| 	w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), NULL, 0 ); | ||||
| 	if ( w_len == 0 ) | ||||
| 	{ | ||||
| 		if ( w_len_ ) | ||||
| @@ -32,7 +33,7 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_ | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	w_text = alloc_array( a, wchar_t, w_len + 1 ); | ||||
| 	w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, w_text, zpl_cast( int ) w_len ); | ||||
| 	w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) ); | ||||
| 	if ( w_len1 == 0 ) | ||||
| 	{ | ||||
| 		free( a, w_text ); | ||||
| @@ -46,7 +47,8 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_ | ||||
| 	return w_text; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_SEEK_PROC( _win32_file_seek ) | ||||
| internal | ||||
| GEN_FILE_SEEK_PROC( _win32_file_seek ) | ||||
| { | ||||
| 	LARGE_INTEGER li_offset; | ||||
| 	li_offset.QuadPart = offset; | ||||
| @@ -60,12 +62,13 @@ internal GEN_FILE_SEEK_PROC( _win32_file_seek ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_READ_AT_PROC( _win32_file_read ) | ||||
| internal | ||||
| GEN_FILE_READ_AT_PROC( _win32_file_read ) | ||||
| { | ||||
| 	// unused( stop_at_newline ); | ||||
| 	b32 result = false; | ||||
| 	_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL ); | ||||
| 	DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size ); | ||||
| 	DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size )); | ||||
| 	DWORD bytes_read_; | ||||
| 	if ( ReadFile( fd.p, buffer, size_, &bytes_read_, NULL ) ) | ||||
| 	{ | ||||
| @@ -77,9 +80,10 @@ internal GEN_FILE_READ_AT_PROC( _win32_file_read ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_WRITE_AT_PROC( _win32_file_write ) | ||||
| internal | ||||
| GEN_FILE_WRITE_AT_PROC( _win32_file_write ) | ||||
| { | ||||
| 	DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size ); | ||||
| 	DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size )); | ||||
| 	DWORD bytes_written_; | ||||
| 	_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL ); | ||||
| 	if ( WriteFile( fd.p, buffer, size_, &bytes_written_, NULL ) ) | ||||
| @@ -91,14 +95,16 @@ internal GEN_FILE_WRITE_AT_PROC( _win32_file_write ) | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_CLOSE_PROC( _win32_file_close ) | ||||
| internal | ||||
| GEN_FILE_CLOSE_PROC( _win32_file_close ) | ||||
| { | ||||
| 	CloseHandle( fd.p ); | ||||
| } | ||||
|  | ||||
| FileOperations const default_file_operations = { _win32_file_read, _win32_file_write, _win32_file_seek, _win32_file_close }; | ||||
|  | ||||
| neverinline GEN_FILE_OPEN_PROC( _win32_file_open ) | ||||
| neverinline | ||||
| GEN_FILE_OPEN_PROC( _win32_file_open ) | ||||
| { | ||||
| 	DWORD    desired_access; | ||||
| 	DWORD    creation_disposition; | ||||
| @@ -176,7 +182,8 @@ neverinline GEN_FILE_OPEN_PROC( _win32_file_open ) | ||||
| #else    // POSIX | ||||
| #	include <fcntl.h> | ||||
|  | ||||
| internal GEN_FILE_SEEK_PROC( _posix_file_seek ) | ||||
| internal | ||||
| GEN_FILE_SEEK_PROC( _posix_file_seek ) | ||||
| { | ||||
| #	if defined( GEN_SYSTEM_OSX ) | ||||
| 	s64 res = lseek( fd.i, offset, whence ); | ||||
| @@ -190,10 +197,11 @@ internal GEN_FILE_SEEK_PROC( _posix_file_seek ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_READ_AT_PROC( _posix_file_read ) | ||||
| internal | ||||
| GEN_FILE_READ_AT_PROC( _posix_file_read ) | ||||
| { | ||||
| 	unused( stop_at_newline ); | ||||
| 	sw res = pread( fd.i, buffer, size, offset ); | ||||
| 	ssize res = pread( fd.i, buffer, size, offset ); | ||||
| 	if ( res < 0 ) | ||||
| 		return false; | ||||
| 	if ( bytes_read ) | ||||
| @@ -201,19 +209,20 @@ internal GEN_FILE_READ_AT_PROC( _posix_file_read ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_WRITE_AT_PROC( _posix_file_write ) | ||||
| internal | ||||
| GEN_FILE_WRITE_AT_PROC( _posix_file_write ) | ||||
| { | ||||
| 	sw  res; | ||||
| 	ssize  res; | ||||
| 	s64 curr_offset = 0; | ||||
| 	_posix_file_seek( fd, 0, ESeekWhence_CURRENT, &curr_offset ); | ||||
| 	if ( curr_offset == offset ) | ||||
| 	{ | ||||
| 		// NOTE: Writing to stdout et al. doesn't like pwrite for numerous reasons | ||||
| 		res = write( zpl_cast( int ) fd.i, buffer, size ); | ||||
| 		res = write( scast( int, fd.i), buffer, size ); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		res = pwrite( zpl_cast( int ) fd.i, buffer, size, offset ); | ||||
| 		res = pwrite( scast( int, fd.i), buffer, size, offset ); | ||||
| 	} | ||||
| 	if ( res < 0 ) | ||||
| 		return false; | ||||
| @@ -222,14 +231,16 @@ internal GEN_FILE_WRITE_AT_PROC( _posix_file_write ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_CLOSE_PROC( _posix_file_close ) | ||||
| internal | ||||
| GEN_FILE_CLOSE_PROC( _posix_file_close ) | ||||
| { | ||||
| 	close( fd.i ); | ||||
| } | ||||
|  | ||||
| FileOperations const default_file_operations = { _posix_file_read, _posix_file_write, _posix_file_seek, _posix_file_close }; | ||||
|  | ||||
| neverinline GEN_FILE_OPEN_PROC( _posix_file_open ) | ||||
| neverinline | ||||
| GEN_FILE_OPEN_PROC( _posix_file_open ) | ||||
| { | ||||
| 	s32 os_mode; | ||||
| 	switch ( mode & GEN_FILE_MODES ) | ||||
| @@ -329,7 +340,7 @@ FileError file_close( FileInfo* f ) | ||||
| 		return EFileError_INVALID; | ||||
|  | ||||
| 	if ( f->filename ) | ||||
| 		free( heap(), zpl_cast( char* ) f->filename ); | ||||
| 		free( heap(), ccast( char*, f->filename )); | ||||
|  | ||||
| #if defined( GEN_SYSTEM_WINDOWS ) | ||||
| 	if ( f->fd.p == INVALID_HANDLE_VALUE ) | ||||
| @@ -364,14 +375,14 @@ FileError file_close( FileInfo* f ) | ||||
| FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename ) | ||||
| { | ||||
| 	FileError err = EFileError_NONE; | ||||
| 	sw        len = str_len( filename ); | ||||
| 	ssize        len = str_len( filename ); | ||||
|  | ||||
| 	f->ops             = ops; | ||||
| 	f->fd              = fd; | ||||
| 	f->dir             = nullptr; | ||||
| 	f->last_write_time = 0; | ||||
| 	f->filename        = alloc_array( heap(), char, len + 1 ); | ||||
| 	mem_copy( zpl_cast( char* ) f->filename, zpl_cast( char* ) filename, len + 1 ); | ||||
| 	mem_copy( ccast( char*, f->filename), ccast( char*, filename), len + 1 ); | ||||
|  | ||||
| 	return err; | ||||
| } | ||||
| @@ -430,7 +441,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const | ||||
|  | ||||
| 	if ( file_open( &file, filepath ) == EFileError_NONE ) | ||||
| 	{ | ||||
| 		sw fsize = zpl_cast( sw ) file_size( &file ); | ||||
| 		ssize fsize = scast( ssize , file_size( &file )); | ||||
| 		if ( fsize > 0 ) | ||||
| 		{ | ||||
| 			result.data = alloc( a, zero_terminate ? fsize + 1 : fsize ); | ||||
| @@ -438,7 +449,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const | ||||
| 			file_read_at( &file, result.data, result.size, 0 ); | ||||
| 			if ( zero_terminate ) | ||||
| 			{ | ||||
| 				u8* str      = zpl_cast( u8* ) result.data; | ||||
| 				u8* str      = rcast( u8*, result.data); | ||||
| 				str[ fsize ] = '\0'; | ||||
| 			} | ||||
| 		} | ||||
| @@ -452,26 +463,28 @@ struct _memory_fd | ||||
| { | ||||
| 	u8            magic; | ||||
| 	u8*           buf;    //< zpl_array OR plain buffer if we can't write | ||||
| 	sw            cursor; | ||||
| 	ssize         cursor; | ||||
| 	AllocatorInfo allocator; | ||||
|  | ||||
| 	FileStreamFlags flags; | ||||
| 	sw              cap; | ||||
| 	ssize           cap; | ||||
| }; | ||||
|  | ||||
| #define GEN__FILE_STREAM_FD_MAGIC 37 | ||||
|  | ||||
| GEN_DEF_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d ); | ||||
| GEN_DEF_INLINE _memory_fd*    _file_stream_from_fd( FileDescriptor fd ); | ||||
| FileDescriptor _file_stream_fd_make( _memory_fd* d ); | ||||
| _memory_fd*    _file_stream_from_fd( FileDescriptor fd ); | ||||
|  | ||||
| GEN_IMPL_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d ) | ||||
| inline | ||||
| FileDescriptor _file_stream_fd_make( _memory_fd* d ) | ||||
| { | ||||
| 	FileDescriptor fd = { 0 }; | ||||
| 	fd.p              = ( void* )d; | ||||
| 	return fd; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd ) | ||||
| inline | ||||
| _memory_fd* _file_stream_from_fd( FileDescriptor fd ) | ||||
| { | ||||
| 	_memory_fd* d = ( _memory_fd* )fd.p; | ||||
| 	GEN_ASSERT( d->magic == GEN__FILE_STREAM_FD_MAGIC ); | ||||
| @@ -506,7 +519,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags ) | ||||
| b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags ) | ||||
| { | ||||
| 	GEN_ASSERT_NOT_NULL( file ); | ||||
| 	_memory_fd* d = ( _memory_fd* )alloc( allocator, size_of( _memory_fd ) ); | ||||
| @@ -543,7 +556,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw siz | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| u8* file_stream_buf( FileInfo* file, sw* size ) | ||||
| u8* file_stream_buf( FileInfo* file, ssize* size ) | ||||
| { | ||||
| 	GEN_ASSERT_NOT_NULL( file ); | ||||
| 	_memory_fd* d = _file_stream_from_fd( file->fd ); | ||||
| @@ -552,10 +565,11 @@ u8* file_stream_buf( FileInfo* file, sw* size ) | ||||
| 	return d->buf; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_SEEK_PROC( _memory_file_seek ) | ||||
| internal | ||||
| GEN_FILE_SEEK_PROC( _memory_file_seek ) | ||||
| { | ||||
| 	_memory_fd* d      = _file_stream_from_fd( fd ); | ||||
| 	sw          buflen = d->cap; | ||||
| 	ssize          buflen = d->cap; | ||||
|  | ||||
| 	if ( whence == ESeekWhence_BEGIN ) | ||||
| 		d->cursor = 0; | ||||
| @@ -568,7 +582,8 @@ internal GEN_FILE_SEEK_PROC( _memory_file_seek ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_READ_AT_PROC( _memory_file_read ) | ||||
| internal | ||||
| GEN_FILE_READ_AT_PROC( _memory_file_read ) | ||||
| { | ||||
| 	// unused( stop_at_newline ); | ||||
| 	_memory_fd* d = _file_stream_from_fd( fd ); | ||||
| @@ -578,23 +593,24 @@ internal GEN_FILE_READ_AT_PROC( _memory_file_read ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
| internal | ||||
| GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
| { | ||||
| 	_memory_fd* d = _file_stream_from_fd( fd ); | ||||
|  | ||||
| 	if ( ! ( d->flags & ( EFileStream_CLONE_WRITABLE | EFileStream_WRITABLE ) ) ) | ||||
| 		return false; | ||||
|  | ||||
| 	sw buflen   = d->cap; | ||||
| 	sw extralen = max( 0, size - ( buflen - offset ) ); | ||||
| 	sw rwlen    = size - extralen; | ||||
| 	sw new_cap  = buflen + extralen; | ||||
| 	ssize buflen   = d->cap; | ||||
| 	ssize extralen = max( 0, size - ( buflen - offset ) ); | ||||
| 	ssize rwlen    = size - extralen; | ||||
| 	ssize new_cap  = buflen + extralen; | ||||
|  | ||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||
| 	{ | ||||
| 		Array<u8> arr = { d->buf }; | ||||
|  | ||||
| 		if ( arr.get_header()->Capacity < uw(new_cap) ) | ||||
| 		if ( arr.get_header()->Capacity < usize(new_cap) ) | ||||
| 		{ | ||||
| 			if ( ! arr.grow( ( s64 )( new_cap ) ) ) | ||||
| 				return false; | ||||
| @@ -622,7 +638,8 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| internal GEN_FILE_CLOSE_PROC( _memory_file_close ) | ||||
| internal | ||||
| GEN_FILE_CLOSE_PROC( _memory_file_close ) | ||||
| { | ||||
| 	_memory_fd*   d         = _file_stream_from_fd( fd ); | ||||
| 	AllocatorInfo allocator = d->allocator; | ||||
|   | ||||
| @@ -48,8 +48,8 @@ union FileDescriptor | ||||
| typedef struct FileOperations FileOperations; | ||||
|  | ||||
| #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, sw size, s64 offset, sw* bytes_read, b32 stop_at_newline ) | ||||
| #define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, sw size, s64 offset, sw* bytes_written ) | ||||
| #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_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, ssize size, s64 offset, ssize* bytes_written ) | ||||
| #define GEN_FILE_SEEK_PROC( name )     b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset ) | ||||
| #define GEN_FILE_CLOSE_PROC( name )    void name( FileDescriptor fd ) | ||||
|  | ||||
| @@ -161,7 +161,7 @@ FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename ); | ||||
| 	* @param  buffer Buffer to read to | ||||
| 	* @param  size   Size to read | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size ); | ||||
| b32 file_read( FileInfo* file, void* buffer, ssize size ); | ||||
|  | ||||
| /** | ||||
| 	* Reads file at a specific offset | ||||
| @@ -171,7 +171,7 @@ GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size ); | ||||
| 	* @param  offset     Offset to read from | ||||
| 	* @param  bytes_read How much data we've actually read | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offset ); | ||||
| b32 file_read_at( FileInfo* file, void* buffer, ssize size, s64 offset ); | ||||
|  | ||||
| /** | ||||
| 	* Reads file safely | ||||
| @@ -181,13 +181,13 @@ GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offs | ||||
| 	* @param  offset     Offset to read from | ||||
| 	* @param  bytes_read How much data we've actually read | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_read_at_check( FileInfo* file, void* buffer, sw size, s64 offset, sw* bytes_read ); | ||||
| b32 file_read_at_check( FileInfo* file, void* buffer, ssize size, s64 offset, ssize* bytes_read ); | ||||
|  | ||||
| struct FileContents | ||||
| { | ||||
| 	AllocatorInfo allocator; | ||||
| 	void*         data; | ||||
| 	sw            size; | ||||
| 	ssize            size; | ||||
| }; | ||||
|  | ||||
| constexpr b32 zero_terminate    = true; | ||||
| @@ -214,20 +214,20 @@ s64 file_size( FileInfo* file ); | ||||
| 	* @param  file | ||||
| 	* @param  offset Offset to seek to | ||||
| 	*/ | ||||
| GEN_DEF_INLINE s64 file_seek( FileInfo* file, s64 offset ); | ||||
| s64 file_seek( FileInfo* file, s64 offset ); | ||||
|  | ||||
| /** | ||||
| 	* Seeks the file cursor to the end of the file | ||||
| 	* @param  file | ||||
| 	*/ | ||||
| GEN_DEF_INLINE s64 file_seek_to_end( FileInfo* file ); | ||||
| s64 file_seek_to_end( FileInfo* file ); | ||||
|  | ||||
| /** | ||||
| 	* Returns the length from the beginning of the file we've read so far | ||||
| 	* @param  file | ||||
| 	* @return      Our current position in file | ||||
| 	*/ | ||||
| GEN_DEF_INLINE s64 file_tell( FileInfo* file ); | ||||
| s64 file_tell( FileInfo* file ); | ||||
|  | ||||
| /** | ||||
| 	* Writes to a file | ||||
| @@ -235,7 +235,7 @@ GEN_DEF_INLINE s64 file_tell( FileInfo* file ); | ||||
| 	* @param  buffer Buffer to read from | ||||
| 	* @param  size   Size to read | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size ); | ||||
| b32 file_write( FileInfo* file, void const* buffer, ssize size ); | ||||
|  | ||||
| /** | ||||
| 	* Writes to file at a specific offset | ||||
| @@ -245,7 +245,7 @@ GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size ); | ||||
| 	* @param  offset        Offset to write to | ||||
| 	* @param  bytes_written How much data we've actually written | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s64 offset ); | ||||
| b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset ); | ||||
|  | ||||
| /** | ||||
| 	* Writes to file safely | ||||
| @@ -255,86 +255,7 @@ GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s | ||||
| 	* @param  offset        Offset to write to | ||||
| 	* @param  bytes_written How much data we've actually written | ||||
| 	*/ | ||||
| GEN_DEF_INLINE b32 file_write_at_check( FileInfo* file, void const* buffer, sw size, s64 offset, sw* bytes_written ); | ||||
|  | ||||
| GEN_IMPL_INLINE s64 file_seek( FileInfo* f, s64 offset ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s64 file_seek_to_end( FileInfo* f ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s64 file_tell( FileInfo* f ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_read( FileInfo* f, void* buffer, sw size ) | ||||
| { | ||||
| 	s64 cur_offset = file_tell( f ); | ||||
| 	b32 result     = file_read_at( f, buffer, size, file_tell( f ) ); | ||||
| 	file_seek( f, cur_offset + size ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_read_at( FileInfo* f, void* buffer, sw size, s64 offset ) | ||||
| { | ||||
| 	return file_read_at_check( f, buffer, size, offset, NULL ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_read_at_check( FileInfo* f, void* buffer, sw size, s64 offset, sw* bytes_read ) | ||||
| { | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
| 	return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_write( FileInfo* f, void const* buffer, sw size ) | ||||
| { | ||||
| 	s64 cur_offset = file_tell( f ); | ||||
| 	b32 result     = file_write_at( f, buffer, size, file_tell( f ) ); | ||||
|  | ||||
| 	file_seek( f, cur_offset + size ); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_write_at( FileInfo* f, void const* buffer, sw size, s64 offset ) | ||||
| { | ||||
| 	return file_write_at_check( f, buffer, size, offset, NULL ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 file_write_at_check( FileInfo* f, void const* buffer, sw size, s64 offset, sw* bytes_written ) | ||||
| { | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	return f->ops.write_at( f->fd, buffer, size, offset, bytes_written ); | ||||
| } | ||||
| b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written ); | ||||
|  | ||||
| enum FileStreamFlags : u32 | ||||
| { | ||||
| @@ -361,15 +282,103 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ); | ||||
| 	* @param  size     Buffer's size | ||||
| 	* @param  flags | ||||
| 	*/ | ||||
| b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags ); | ||||
| b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags ); | ||||
|  | ||||
| /** | ||||
| 	* Retrieves the stream's underlying buffer and buffer size. | ||||
| 	* @param file memory stream | ||||
| 	* @param size (Optional) buffer size | ||||
| 	*/ | ||||
| u8* file_stream_buf( FileInfo* file, sw* size ); | ||||
| u8* file_stream_buf( FileInfo* file, ssize* size ); | ||||
|  | ||||
| extern FileOperations const memory_file_operations; | ||||
|  | ||||
| inline | ||||
| s64 file_seek( FileInfo* f, s64 offset ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| inline | ||||
| s64 file_seek_to_end( FileInfo* f ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| inline | ||||
| s64 file_tell( FileInfo* f ) | ||||
| { | ||||
| 	s64 new_offset = 0; | ||||
|  | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset ); | ||||
|  | ||||
| 	return new_offset; | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_read( FileInfo* f, void* buffer, ssize size ) | ||||
| { | ||||
| 	s64 cur_offset = file_tell( f ); | ||||
| 	b32 result     = file_read_at( f, buffer, size, file_tell( f ) ); | ||||
| 	file_seek( f, cur_offset + size ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_read_at( FileInfo* f, void* buffer, ssize size, s64 offset ) | ||||
| { | ||||
| 	return file_read_at_check( f, buffer, size, offset, NULL ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_read_at_check( FileInfo* f, void* buffer, ssize size, s64 offset, ssize* bytes_read ) | ||||
| { | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
| 	return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_write( FileInfo* f, void const* buffer, ssize size ) | ||||
| { | ||||
| 	s64 cur_offset = file_tell( f ); | ||||
| 	b32 result     = file_write_at( f, buffer, size, file_tell( f ) ); | ||||
|  | ||||
| 	file_seek( f, cur_offset + size ); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_write_at( FileInfo* f, void const* buffer, ssize size, s64 offset ) | ||||
| { | ||||
| 	return file_write_at_check( f, buffer, size, offset, NULL ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| b32 file_write_at_check( FileInfo* f, void const* buffer, ssize size, s64 offset, ssize* bytes_written ) | ||||
| { | ||||
| 	if ( ! f->ops.read_at ) | ||||
| 		f->ops = default_file_operations; | ||||
|  | ||||
| 	return f->ops.write_at( f->fd, buffer, size, offset, bytes_written ); | ||||
| } | ||||
|  | ||||
| #pragma endregion File Handling | ||||
|   | ||||
| @@ -27,11 +27,11 @@ global u32 const _crc32_table[ 256 ] = { | ||||
| 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, | ||||
| }; | ||||
|  | ||||
| u32 crc32( void const* data, sw len ) | ||||
| u32 crc32( void const* data, ssize len ) | ||||
| { | ||||
| 	sw        remaining; | ||||
| 	u32       result = ~( zpl_cast( u32 ) 0 ); | ||||
| 	u8 const* c      = zpl_cast( u8 const* ) data; | ||||
| 	ssize        remaining; | ||||
| 	u32       result = ~( scast( u32, 0) ); | ||||
| 	u8 const* c      = rcast( u8 const*, data); | ||||
| 	for ( remaining = len; remaining--; c++ ) | ||||
| 		result = ( result >> 8 ) ^ ( _crc32_table[ ( result ^ *c ) & 0xff ] ); | ||||
| 	return ~result; | ||||
| @@ -77,11 +77,11 @@ global u64 const _crc64_table[ 256 ] = { | ||||
| 	0xa6df411fbfb21ca3ull, 0xdc0731d78f8795daull, 0x536fa08fdfd90e51ull, 0x29b7d047efec8728ull, | ||||
| }; | ||||
|  | ||||
| u64 crc64( void const* data, sw len ) | ||||
| u64 crc64( void const* data, ssize len ) | ||||
| { | ||||
| 	sw        remaining; | ||||
| 	u64       result = ( zpl_cast( u64 ) 0 ); | ||||
| 	u8 const* c      = zpl_cast( u8 const* ) data; | ||||
| 	ssize        remaining; | ||||
| 	u64       result = ( scast( u64, 0) ); | ||||
| 	u8 const* c      = rcast( u8 const*, data); | ||||
| 	for ( remaining = len; remaining--; c++ ) | ||||
| 		result = ( result >> 8 ) ^ ( _crc64_table[ ( result ^ *c ) & 0xff ] ); | ||||
| 	return result; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| #pragma region Hashing | ||||
|  | ||||
| u32 crc32( void const* data, sw len ); | ||||
| u64 crc64( void const* data, sw len ); | ||||
| u32 crc32( void const* data, ssize len ); | ||||
| u64 crc64( void const* data, ssize len ); | ||||
|  | ||||
| #pragma endregion Hashing | ||||
|   | ||||
| @@ -1,58 +1,77 @@ | ||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||
| #	pragma once | ||||
| #	include "header_start.hpp" | ||||
| #   pragma once | ||||
| #endif | ||||
|  | ||||
| #pragma region Macros | ||||
|  | ||||
| #define zpl_cast( Type ) ( Type ) | ||||
|  | ||||
| // Keywords | ||||
|  | ||||
| #ifndef global | ||||
| #define global        static    // Global variables | ||||
| #endif | ||||
| #ifndef internal | ||||
| #define internal      static    // Internal linkage | ||||
| #endif | ||||
| #ifndef local_persist | ||||
| #define local_persist static    // Local Persisting variables | ||||
|  | ||||
| #pragma region ForceInline Definition | ||||
| #ifdef GEN_COMPILER_MSVC | ||||
| #	define forceinline __forceinline | ||||
| #	define neverinline __declspec( noinline ) | ||||
| #elif defined(GEN_COMPILER_GCC) | ||||
| #	define forceinline inline __attribute__((__always_inline__)) | ||||
| #	define neverinline __attribute__( ( __noinline__ ) ) | ||||
| #elif defined(GEN_COMPILER_CLANG) | ||||
| #if __has_attribute(__always_inline__) | ||||
| #	define forceinline inline __attribute__((__always_inline__)) | ||||
| #	define neverinline __attribute__( ( __noinline__ ) ) | ||||
| #else | ||||
| #	define forceinline | ||||
| #	define neverinline | ||||
| #endif | ||||
| #else | ||||
| #	define forceinline | ||||
| #	define neverinline | ||||
| #endif | ||||
| #pragma endregion ForceInline Definition | ||||
|  | ||||
| // Bits | ||||
| #ifndef api_c | ||||
| #define api_c extern "C" | ||||
| #endif | ||||
|  | ||||
| #ifndef bit | ||||
| #define bit( Value )                             ( 1 << Value ) | ||||
| #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) | ||||
| #endif | ||||
|  | ||||
| // Casting | ||||
|  | ||||
| #ifndef ccast | ||||
| #define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) ) | ||||
| #define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) ) | ||||
| #define rcast( Type, Value ) reinterpret_cast< Type >( Value ) | ||||
| #define scast( Type, Value ) static_cast< Type >( Value ) | ||||
| #define ccast( type, value ) ( const_cast< type >( (value) ) ) | ||||
| #endif | ||||
| #ifndef pcast | ||||
| #define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) ) | ||||
| #endif | ||||
| #ifndef rcast | ||||
| #define rcast( type, value ) reinterpret_cast< type >( value ) | ||||
| #endif | ||||
| #ifndef scast | ||||
| #define scast( type, value ) static_cast< type >( value ) | ||||
| #endif | ||||
|  | ||||
| // Num Arguments (Varadics) | ||||
| // #if defined(__GNUC__) || defined(__clang__) | ||||
| // Supports 0-50 arguments | ||||
| #ifndef stringize | ||||
| #define stringize_va( ... ) #__VA_ARGS__ | ||||
| #define stringize( ... )    stringize_va( __VA_ARGS__ ) | ||||
| #endif | ||||
|  | ||||
| #ifndef do_once | ||||
| #define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) ) | ||||
|  | ||||
| #define do_once_start      \ | ||||
| 	do                     \ | ||||
| 	{                      \ | ||||
| 		local_persist      \ | ||||
| 		bool done = false; \ | ||||
| 		if ( done )        \ | ||||
| 			break;         \ | ||||
| 		done = true; | ||||
|  | ||||
| #define do_once_end        \ | ||||
| 	}                      \ | ||||
| 	while(0); | ||||
| #endif | ||||
|  | ||||
| #ifndef labeled_scope_start | ||||
| #define labeled_scope_start if ( false ) { | ||||
| #define labeled_scope_end   } | ||||
| #endif | ||||
|  | ||||
| #ifndef         compiler_decorated_func_name | ||||
| #   ifdef COMPILER_CLANG | ||||
| #       define  compiler_decorated_func_name __PRETTY_NAME__ | ||||
| #   elif defined(COMPILER_MSVC) | ||||
| #   	define compiler_decorated_func_name __FUNCDNAME__ | ||||
| #   endif | ||||
| #endif | ||||
|  | ||||
| #ifndef num_args_impl | ||||
| #define num_args_impl( _0,                                 \ | ||||
| 		_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10,   \ | ||||
| 		_11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \ | ||||
| @@ -67,7 +86,7 @@ | ||||
| 		N, ...                                             \ | ||||
| 	) N | ||||
|  | ||||
| 	// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang) | ||||
| // ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang) | ||||
| #define num_args(...)                            \ | ||||
| 	num_args_impl(_, ## __VA_ARGS__,             \ | ||||
| 		100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \ | ||||
| @@ -82,93 +101,53 @@ | ||||
| 		 10,  9,  8,  7,  6,  5,  4,  3,  2,  1, \ | ||||
| 		 0                                       \ | ||||
| 	) | ||||
| #endif | ||||
|  | ||||
| // #else | ||||
| // This doesn't work on latest msvc so I had to use /Zc:preprocessor flag. | ||||
|  | ||||
| // Supports 1-50 arguments | ||||
| // #define num_args_impl(                                  \ | ||||
| // 		_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10,   \ | ||||
| // 		_11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \ | ||||
| // 		_21, _22, _23, _24, _25, _26, _27, _28, _29, _30,  \ | ||||
| // 		_31, _32, _33, _34, _35, _36, _37, _38, _39, _40,  \ | ||||
| // 		_41, _42, _43, _44, _45, _46, _47, _48, _49, _50,  \ | ||||
| // 		_51, _52, _53, _54, _55, _56, _57, _58, _59, _60,  \ | ||||
| // 		_61, _62, _63, _64, _65, _66, _67, _68, _69, _70,  \ | ||||
| // 		_71, _72, _73, _74, _75, _76, _77, _78, _79, _80,  \ | ||||
| // 		_81, _82, _83, _84, _85, _86, _87, _88, _89, _90,  \ | ||||
| // 		_91, _92, _93, _94, _95, _96, _97, _98, _99, _100, \ | ||||
| // 		N, ...                                             \ | ||||
| // 	) N | ||||
|  | ||||
| // #define num_args(...)                         \ | ||||
| // 	num_args_impl( __VA_ARGS__,                  \ | ||||
| // 		100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \ | ||||
| // 		 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, \ | ||||
| // 		 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, \ | ||||
| // 		 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, \ | ||||
| // 		 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ | ||||
| // 		 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ | ||||
| // 		 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ | ||||
| // 		 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ | ||||
| // 		 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ | ||||
| // 		 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ | ||||
| // 		 10,  9,  8,  7,  6,  5,  4,  3,  2,  1  \ | ||||
| // 	) | ||||
| // #endif | ||||
|  | ||||
| // Stringizing | ||||
| #define stringize_va( ... ) #__VA_ARGS__ | ||||
| #define stringize( ... )    stringize_va( __VA_ARGS__ ) | ||||
|  | ||||
| // Function do once | ||||
|  | ||||
| #define do_once()          \ | ||||
| 	do                     \ | ||||
| 	{                      \ | ||||
| 		static             \ | ||||
| 		bool Done = false; \ | ||||
| 		if ( Done )        \ | ||||
| 			return;        \ | ||||
| 		Done = true;       \ | ||||
| 	}                      \ | ||||
| 	while(0) | ||||
|  | ||||
| #define do_once_start      \ | ||||
| 	do                     \ | ||||
| 	{                      \ | ||||
| 		static             \ | ||||
| 		bool Done = false; \ | ||||
| 		if ( Done )        \ | ||||
| 			break;         \ | ||||
| 		Done = true; | ||||
|  | ||||
| #define do_once_end        \ | ||||
| 	}                      \ | ||||
| 	while(0); | ||||
|  | ||||
| #define labeled_scope_start if ( false ) { | ||||
| #define labeled_scope_end   } | ||||
|  | ||||
| #ifndef clamp | ||||
| #define clamp( x, lower, upper )      min( max( ( x ), ( lower ) ), ( upper ) ) | ||||
| #define count_of( x )                 ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( sw )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) ) | ||||
| #endif | ||||
| #ifndef count_of | ||||
| #define count_of( x )                 ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( ssize )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) ) | ||||
| #endif | ||||
| #ifndef is_between | ||||
| #define is_between( x, lower, upper ) ( ( ( lower ) <= ( x ) ) && ( ( x ) <= ( upper ) ) ) | ||||
| #define max( a, b )                   ( ( a ) > ( b ) ? ( a ) : ( b ) ) | ||||
| #define min( a, b )                   ( ( a ) < ( b ) ? ( a ) : ( b ) ) | ||||
| #define size_of( x )                  ( sw )( sizeof( x ) ) | ||||
| #endif | ||||
| #ifndef size_of | ||||
| #define size_of( x )                  ( ssize )( sizeof( x ) ) | ||||
| #endif | ||||
|  | ||||
| #ifndef max | ||||
| #define max( a, b ) ( (a > b) ? (a) : (b) ) | ||||
| #endif | ||||
| #ifndef min | ||||
| #define min( a, b ) ( (a < b) ? (a) : (b) ) | ||||
| #endif | ||||
|  | ||||
| #if defined( _MSC_VER ) || defined( GEN_COMPILER_TINYC ) | ||||
| #	define offset_of( Type, element ) ( ( GEN_NS( gen_sw ) ) & ( ( ( Type* )0 )->element ) ) | ||||
| #	define offset_of( Type, element ) ( ( GEN_NS( ssize ) ) & ( ( ( Type* )0 )->element ) ) | ||||
| #else | ||||
| #	define offset_of( Type, element ) __builtin_offsetof( Type, element ) | ||||
| #endif | ||||
|  | ||||
| template< class Type > | ||||
| void swap( Type& a, Type& b ) | ||||
| { | ||||
| 	Type tmp = a; | ||||
| 	a = b; | ||||
| 	b = tmp; | ||||
| } | ||||
| #ifndef        forceinline | ||||
| #	ifdef GEN_COMPILER_MSVC | ||||
| #		define forceinline __forceinline | ||||
| #		define neverinline __declspec( noinline ) | ||||
| #	elif defined(GEN_COMPILER_GCC) | ||||
| #		define forceinline inline __attribute__((__always_inline__)) | ||||
| #		define neverinline __attribute__( ( __noinline__ ) ) | ||||
| #	elif defined(GEN_COMPILER_CLANG) | ||||
| #	if __has_attribute(__always_inline__) | ||||
| #		define forceinline inline __attribute__((__always_inline__)) | ||||
| #		define neverinline __attribute__( ( __noinline__ ) ) | ||||
| #	else | ||||
| #		define forceinline | ||||
| #		define neverinline | ||||
| #	endif | ||||
| #	else | ||||
| #		define forceinline | ||||
| #		define neverinline | ||||
| #	endif | ||||
| #endif | ||||
|  | ||||
| #pragma endregion Macros | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| #pragma region Memory | ||||
|  | ||||
| void* mem_copy( void* dest, void const* source, sw n ) | ||||
| void* mem_copy( void* dest, void const* source, ssize n ) | ||||
| { | ||||
| 	if ( dest == NULL ) | ||||
| 	{ | ||||
| @@ -15,25 +15,25 @@ void* mem_copy( void* dest, void const* source, sw n ) | ||||
| 	return memcpy( dest, source, n ); | ||||
| } | ||||
|  | ||||
| void const* mem_find( void const* data, u8 c, sw n ) | ||||
| void const* mem_find( void const* data, u8 c, ssize n ) | ||||
| { | ||||
| 	u8 const* s = zpl_cast( u8 const* ) data; | ||||
| 	while ( ( zpl_cast( uptr ) s & ( sizeof( uw ) - 1 ) ) && n && *s != c ) | ||||
| 	u8 const* s = rcast( u8 const*, data); | ||||
| 	while ( ( rcast( uptr, s) & ( sizeof( usize ) - 1 ) ) && n && *s != c ) | ||||
| 	{ | ||||
| 		s++; | ||||
| 		n--; | ||||
| 	} | ||||
| 	if ( n && *s != c ) | ||||
| 	{ | ||||
| 		sw const* w; | ||||
| 		sw        k = GEN__ONES * c; | ||||
| 		w           = zpl_cast( sw const* ) s; | ||||
| 		while ( n >= size_of( sw ) && ! GEN__HAS_ZERO( *w ^ k ) ) | ||||
| 		ssize const* w; | ||||
| 		ssize        k = GEN__ONES * c; | ||||
| 		w           = rcast( ssize const*, s); | ||||
| 		while ( n >= size_of( ssize ) && ! GEN__HAS_ZERO( *w ^ k ) ) | ||||
| 		{ | ||||
| 			w++; | ||||
| 			n -= size_of( sw ); | ||||
| 			n -= size_of( ssize ); | ||||
| 		} | ||||
| 		s = zpl_cast( u8 const* ) w; | ||||
| 		s = rcast( u8 const*, w); | ||||
| 		while ( n && *s != c ) | ||||
| 		{ | ||||
| 			s++; | ||||
| @@ -41,7 +41,7 @@ void const* mem_find( void const* data, u8 c, sw n ) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return n ? zpl_cast( void const* ) s : NULL; | ||||
| 	return n ? rcast( void const*, s ) : NULL; | ||||
| } | ||||
|  | ||||
| #define GEN_HEAP_STATS_MAGIC 0xDEADC0DE | ||||
| @@ -49,8 +49,8 @@ void const* mem_find( void const* data, u8 c, sw n ) | ||||
| struct _heap_stats | ||||
| { | ||||
| 	u32 magic; | ||||
| 	sw  used_memory; | ||||
| 	sw  alloc_count; | ||||
| 	ssize  used_memory; | ||||
| 	ssize  alloc_count; | ||||
| }; | ||||
|  | ||||
| global _heap_stats _heap_stats_info; | ||||
| @@ -61,13 +61,13 @@ void heap_stats_init( void ) | ||||
| 	_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC; | ||||
| } | ||||
|  | ||||
| sw heap_stats_used_memory( void ) | ||||
| ssize heap_stats_used_memory( void ) | ||||
| { | ||||
| 	GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" ); | ||||
| 	return _heap_stats_info.used_memory; | ||||
| } | ||||
|  | ||||
| sw heap_stats_alloc_count( void ) | ||||
| ssize heap_stats_alloc_count( void ) | ||||
| { | ||||
| 	GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" ); | ||||
| 	return _heap_stats_info.alloc_count; | ||||
| @@ -82,11 +82,11 @@ void heap_stats_check( void ) | ||||
|  | ||||
| struct _heap_alloc_info | ||||
| { | ||||
| 	sw    size; | ||||
| 	ssize    size; | ||||
| 	void* physical_start; | ||||
| }; | ||||
|  | ||||
| void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) | ||||
| void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | ||||
| { | ||||
| 	void* ptr = NULL; | ||||
| 	// unused( allocator_data ); | ||||
| @@ -95,16 +95,16 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali | ||||
| 		alignment = GEN_DEFAULT_MEMORY_ALIGNMENT; | ||||
|  | ||||
| #ifdef GEN_HEAP_ANALYSIS | ||||
| 	sw alloc_info_size      = size_of( _heap_alloc_info ); | ||||
| 	sw alloc_info_remainder = ( alloc_info_size % alignment ); | ||||
| 	sw track_size           = max( alloc_info_size, alignment ) + alloc_info_remainder; | ||||
| 	ssize alloc_info_size      = size_of( _heap_alloc_info ); | ||||
| 	ssize alloc_info_remainder = ( alloc_info_size % alignment ); | ||||
| 	ssize track_size           = max( alloc_info_size, alignment ) + alloc_info_remainder; | ||||
| 	switch ( type ) | ||||
| 	{ | ||||
| 		case EAllocation_FREE : | ||||
| 			{ | ||||
| 				if ( ! old_memory ) | ||||
| 					break; | ||||
| 				_heap_alloc_info* alloc_info  = zpl_cast( _heap_alloc_info* ) old_memory - 1; | ||||
| 				_heap_alloc_info* alloc_info  = rcast( _heap_alloc_info*, old_memory) - 1; | ||||
| 				_heap_stats_info.used_memory -= alloc_info->size; | ||||
| 				_heap_stats_info.alloc_count--; | ||||
| 				old_memory = alloc_info->physical_start; | ||||
| @@ -195,11 +195,11 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali | ||||
| #ifdef GEN_HEAP_ANALYSIS | ||||
| 	if ( type == EAllocation_ALLOC ) | ||||
| 	{ | ||||
| 		_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* )( zpl_cast( char* ) ptr + alloc_info_remainder ); | ||||
| 		_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder ); | ||||
| 		zero_item( alloc_info ); | ||||
| 		alloc_info->size              = size - track_size; | ||||
| 		alloc_info->physical_start    = ptr; | ||||
| 		ptr                           = zpl_cast( void* )( alloc_info + 1 ); | ||||
| 		ptr                           = rcast( void*, alloc_info + 1 ); | ||||
| 		_heap_stats_info.used_memory += alloc_info->size; | ||||
| 		_heap_stats_info.alloc_count++; | ||||
| 	} | ||||
| @@ -209,7 +209,7 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali | ||||
| } | ||||
|  | ||||
| #pragma region VirtualMemory | ||||
| VirtualMemory vm_from_memory( void* data, sw size ) | ||||
| VirtualMemory vm_from_memory( void* data, ssize size ) | ||||
| { | ||||
| 	VirtualMemory vm; | ||||
| 	vm.data = data; | ||||
| @@ -218,7 +218,7 @@ VirtualMemory vm_from_memory( void* data, sw size ) | ||||
| } | ||||
|  | ||||
| #if defined( GEN_SYSTEM_WINDOWS ) | ||||
| VirtualMemory vm_alloc( void* addr, sw size ) | ||||
| VirtualMemory vm_alloc( void* addr, ssize size ) | ||||
| { | ||||
| 	VirtualMemory vm; | ||||
| 	GEN_ASSERT( size > 0 ); | ||||
| @@ -234,7 +234,7 @@ b32 vm_free( VirtualMemory vm ) | ||||
| 	{ | ||||
| 		if ( VirtualQuery( vm.data, &info, size_of( info ) ) == 0 ) | ||||
| 			return false; | ||||
| 		if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > zpl_cast( uw ) vm.size ) | ||||
| 		if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > scast( usize, vm.size) ) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
| @@ -246,7 +246,7 @@ b32 vm_free( VirtualMemory vm ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size ) | ||||
| VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ) | ||||
| { | ||||
| 	VirtualMemory new_vm = { 0 }; | ||||
| 	void*             ptr; | ||||
| @@ -270,7 +270,7 @@ b32 vm_purge( VirtualMemory vm ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| sw virtual_memory_page_size( sw* alignment_out ) | ||||
| ssize virtual_memory_page_size( ssize* alignment_out ) | ||||
| { | ||||
| 	SYSTEM_INFO info; | ||||
| 	GetSystemInfo( &info ); | ||||
| @@ -285,7 +285,7 @@ sw virtual_memory_page_size( sw* alignment_out ) | ||||
| #	ifndef MAP_ANONYMOUS | ||||
| #		define MAP_ANONYMOUS MAP_ANON | ||||
| #	endif | ||||
| VirtualMemory vm_alloc( void* addr, sw size ) | ||||
| VirtualMemory vm_alloc( void* addr, ssize size ) | ||||
| { | ||||
| 	VirtualMemory vm; | ||||
| 	GEN_ASSERT( size > 0 ); | ||||
| @@ -300,10 +300,10 @@ b32 vm_free( VirtualMemory vm ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size ) | ||||
| VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ) | ||||
| { | ||||
| 	void*  ptr; | ||||
| 	sw trail_size; | ||||
| 	ssize trail_size; | ||||
| 	GEN_ASSERT( vm.size >= lead_size + size ); | ||||
|  | ||||
| 	ptr        = pointer_add( vm.data, lead_size ); | ||||
| @@ -322,10 +322,10 @@ b32 vm_purge( VirtualMemory vm ) | ||||
| 	return err != 0; | ||||
| } | ||||
|  | ||||
| sw virtual_memory_page_size( sw* alignment_out ) | ||||
| ssize virtual_memory_page_size( ssize* alignment_out ) | ||||
| { | ||||
| 	// TODO: Is this always true? | ||||
| 	sw result = zpl_cast( sw ) sysconf( _SC_PAGE_SIZE ); | ||||
| 	ssize result = scast( ssize, sysconf( _SC_PAGE_SIZE )); | ||||
| 	if ( alignment_out ) | ||||
| 		*alignment_out = result; | ||||
| 	return result; | ||||
| @@ -334,7 +334,7 @@ sw virtual_memory_page_size( sw* alignment_out ) | ||||
|  | ||||
| #pragma endregion VirtualMemory | ||||
|  | ||||
| void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) | ||||
| void* Arena::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | ||||
| { | ||||
| 	Arena* arena = rcast(Arena*, allocator_data); | ||||
| 	void*      ptr   = NULL; | ||||
| @@ -346,10 +346,10 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a | ||||
| 		case EAllocation_ALLOC : | ||||
| 			{ | ||||
| 				void* end        = pointer_add( arena->PhysicalStart, arena->TotalUsed ); | ||||
| 				sw    total_size = align_forward_i64( size, alignment ); | ||||
| 				ssize    total_size = align_forward_i64( size, alignment ); | ||||
|  | ||||
| 				// NOTE: Out of memory | ||||
| 				if ( arena->TotalUsed + total_size > (sw) arena->TotalSize ) | ||||
| 				if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize ) | ||||
| 				{ | ||||
| 					// zpl__printf_err("%s", "Arena out of memory\n"); | ||||
| 					GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)"); | ||||
| @@ -384,9 +384,9 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a | ||||
| 	return ptr; | ||||
| } | ||||
|  | ||||
| void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) | ||||
| void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | ||||
| { | ||||
| 	Pool* pool = zpl_cast( Pool* ) allocator_data; | ||||
| 	Pool* pool = rcast( Pool*, allocator_data); | ||||
| 	void* ptr  = NULL; | ||||
|  | ||||
| 	// unused( old_size ); | ||||
| @@ -401,9 +401,9 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al | ||||
| 				GEN_ASSERT( alignment == pool->BlockAlign ); | ||||
| 				GEN_ASSERT( pool->FreeList != NULL ); | ||||
|  | ||||
| 				next_free        = *zpl_cast( uptr* ) pool->FreeList; | ||||
| 				next_free        = * rcast( uptr*, pool->FreeList); | ||||
| 				ptr              = pool->FreeList; | ||||
| 				pool->FreeList   = zpl_cast( void* ) next_free; | ||||
| 				pool->FreeList   = rcast( void*, next_free); | ||||
| 				pool->TotalSize += pool->BlockSize; | ||||
|  | ||||
| 				if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO ) | ||||
| @@ -417,8 +417,8 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al | ||||
| 				if ( old_memory == NULL ) | ||||
| 					return NULL; | ||||
|  | ||||
| 				next             = zpl_cast( uptr* ) old_memory; | ||||
| 				*next            = zpl_cast( uptr ) pool->FreeList; | ||||
| 				next             = rcast( uptr*, old_memory); | ||||
| 				*next            = rcast( uptr, pool->FreeList); | ||||
| 				pool->FreeList   = old_memory; | ||||
| 				pool->TotalSize -= pool->BlockSize; | ||||
| 			} | ||||
| @@ -426,7 +426,7 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al | ||||
|  | ||||
| 		case EAllocation_FREE_ALL : | ||||
| 			{ | ||||
| 				sw    actual_block_size, block_index; | ||||
| 				ssize    actual_block_size, block_index; | ||||
| 				void* curr; | ||||
| 				uptr* end; | ||||
|  | ||||
| @@ -437,13 +437,13 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al | ||||
| 				curr = pool->PhysicalStart; | ||||
| 				for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ ) | ||||
| 				{ | ||||
| 					uptr* next = zpl_cast( uptr* ) curr; | ||||
| 					*next      = zpl_cast( uptr ) curr + actual_block_size; | ||||
| 					uptr* next = rcast( uptr*, curr); | ||||
| 					* next     = rcast( uptr, curr) + actual_block_size; | ||||
| 					curr       = pointer_add( curr, actual_block_size ); | ||||
| 				} | ||||
|  | ||||
| 				end            = zpl_cast( uptr* ) curr; | ||||
| 				*end           = zpl_cast( uptr ) NULL; | ||||
| 				end            = rcast( uptr*, curr); | ||||
| 				* end          = scast( uptr, NULL); | ||||
| 				pool->FreeList = pool->PhysicalStart; | ||||
| 			} | ||||
| 			break; | ||||
| @@ -457,11 +457,11 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al | ||||
| 	return ptr; | ||||
| } | ||||
|  | ||||
| Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align ) | ||||
| Pool Pool::init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align ) | ||||
| { | ||||
| 	Pool pool = {}; | ||||
|  | ||||
| 	sw    actual_block_size, pool_size, block_index; | ||||
| 	ssize    actual_block_size, pool_size, block_index; | ||||
| 	void *data, *curr; | ||||
| 	uptr* end; | ||||
|  | ||||
| @@ -497,7 +497,7 @@ Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw b | ||||
|  | ||||
| void Pool::clear() | ||||
| { | ||||
| 	sw    actual_block_size, block_index; | ||||
| 	ssize    actual_block_size, block_index; | ||||
| 	void* curr; | ||||
| 	uptr* end; | ||||
|  | ||||
|   | ||||
| @@ -10,43 +10,51 @@ | ||||
| #define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) ) | ||||
| #define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) ) | ||||
|  | ||||
| #define GEN__ONES          ( zpl_cast( uw ) - 1 / GEN_U8_MAX ) | ||||
| #define GEN__ONES          ( scast( GEN_NS usize, - 1) / GEN_U8_MAX ) | ||||
| #define GEN__HIGHS         ( GEN__ONES * ( GEN_U8_MAX / 2 + 1 ) ) | ||||
| #define GEN__HAS_ZERO( x ) ( ( ( x )-GEN__ONES ) & ~( x )&GEN__HIGHS ) | ||||
| #define GEN__HAS_ZERO( x ) ( ( ( x ) - GEN__ONES ) & ~( x ) & GEN__HIGHS ) | ||||
|  | ||||
| template< class Type > | ||||
| void swap( Type& a, Type& b ) | ||||
| { | ||||
| 	Type tmp = a; | ||||
| 	a = b; | ||||
| 	b = tmp; | ||||
| } | ||||
|  | ||||
| //! Checks if value is power of 2. | ||||
| GEN_DEF_INLINE b32 is_power_of_two( sw x ); | ||||
| b32 is_power_of_two( ssize x ); | ||||
|  | ||||
| //! Aligns address to specified alignment. | ||||
| GEN_DEF_INLINE void* align_forward( void* ptr, sw alignment ); | ||||
| void* align_forward( void* ptr, ssize alignment ); | ||||
|  | ||||
| //! Aligns value to a specified alignment. | ||||
| GEN_DEF_INLINE s64 align_forward_i64( s64 value, sw alignment ); | ||||
| s64 align_forward_i64( s64 value, ssize alignment ); | ||||
|  | ||||
| //! Moves pointer forward by bytes. | ||||
| GEN_DEF_INLINE void* pointer_add( void* ptr, sw bytes ); | ||||
| void* pointer_add( void* ptr, ssize bytes ); | ||||
|  | ||||
| //! Moves pointer forward by bytes. | ||||
| GEN_DEF_INLINE void const* pointer_add_const( void const* ptr, sw bytes ); | ||||
| void const* pointer_add_const( void const* ptr, ssize bytes ); | ||||
|  | ||||
| //! Calculates difference between two addresses. | ||||
| GEN_DEF_INLINE sw pointer_diff( void const* begin, void const* end ); | ||||
| ssize pointer_diff( void const* begin, void const* end ); | ||||
|  | ||||
| //! Copy non-overlapping memory from source to destination. | ||||
| void* mem_copy( void* dest, void const* source, sw size ); | ||||
| void* mem_copy( void* dest, void const* source, ssize size ); | ||||
|  | ||||
| //! Search for a constant value within the size limit at memory location. | ||||
| void const* mem_find( void const* data, u8 byte_value, sw size ); | ||||
| void const* mem_find( void const* data, u8 byte_value, ssize size ); | ||||
|  | ||||
| //! Copy memory from source to destination. | ||||
| GEN_DEF_INLINE void* mem_move( void* dest, void const* source, sw size ); | ||||
| void* mem_move( void* dest, void const* source, ssize size ); | ||||
|  | ||||
| //! Set constant value at memory location with specified size. | ||||
| GEN_DEF_INLINE void* mem_set( void* data, u8 byte_value, sw size ); | ||||
| void* mem_set( void* data, u8 byte_value, ssize size ); | ||||
|  | ||||
| //! @param ptr Memory location to clear up. | ||||
| //! @param size The size to clear up with. | ||||
| GEN_DEF_INLINE void zero_size( void* ptr, sw size ); | ||||
| void zero_size( void* ptr, ssize size ); | ||||
|  | ||||
| //! Clears up an item. | ||||
| #define zero_item( t ) zero_size( ( t ), size_of( *( t ) ) )    // NOTE: Pass pointer of struct | ||||
| @@ -63,8 +71,8 @@ enum AllocType : u8 | ||||
| }; | ||||
|  | ||||
| using AllocatorProc = void* ( void* allocator_data, AllocType type | ||||
| 	, sw size, sw alignment | ||||
| 	, void* old_memory, sw old_size | ||||
| 	, ssize size, ssize alignment | ||||
| 	, void* old_memory, ssize old_size | ||||
| 	, u64 flags ); | ||||
|  | ||||
| struct AllocatorInfo | ||||
| @@ -87,22 +95,22 @@ enum AllocFlag | ||||
| #endif | ||||
|  | ||||
| //! Allocate memory with default alignment. | ||||
| GEN_DEF_INLINE void* alloc( AllocatorInfo a, sw size ); | ||||
| void* alloc( AllocatorInfo a, ssize size ); | ||||
|  | ||||
| //! Allocate memory with specified alignment. | ||||
| GEN_DEF_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment ); | ||||
| void* alloc_align( AllocatorInfo a, ssize size, ssize alignment ); | ||||
|  | ||||
| //! Free allocated memory. | ||||
| GEN_DEF_INLINE void free( AllocatorInfo a, void* ptr ); | ||||
| void free( AllocatorInfo a, void* ptr ); | ||||
|  | ||||
| //! Free all memory allocated by an allocator. | ||||
| GEN_DEF_INLINE void free_all( AllocatorInfo a ); | ||||
| void free_all( AllocatorInfo a ); | ||||
|  | ||||
| //! Resize an allocated memory. | ||||
| GEN_DEF_INLINE void* resize( AllocatorInfo a, void* ptr, sw old_size, sw new_size ); | ||||
| void* resize( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size ); | ||||
|  | ||||
| //! Resize an allocated memory with specified alignment. | ||||
| GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment ); | ||||
| void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment ); | ||||
|  | ||||
| //! Allocate memory for an item. | ||||
| #define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) ) | ||||
| @@ -114,17 +122,17 @@ GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw n | ||||
| /* define GEN_HEAP_ANALYSIS to enable this feature */ | ||||
| /* call zpl_heap_stats_init at the beginning of the entry point */ | ||||
| /* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */ | ||||
| void heap_stats_init( void ); | ||||
| sw   heap_stats_used_memory( void ); | ||||
| sw   heap_stats_alloc_count( void ); | ||||
| void heap_stats_check( void ); | ||||
| void  heap_stats_init( void ); | ||||
| ssize heap_stats_used_memory( void ); | ||||
| ssize heap_stats_alloc_count( void ); | ||||
| void  heap_stats_check( void ); | ||||
|  | ||||
| //! Allocate/Resize memory using default options. | ||||
|  | ||||
| //! Use this if you don't need a "fancy" resize allocation | ||||
| GEN_DEF_INLINE void* default_resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment ); | ||||
| void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment ); | ||||
|  | ||||
| void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ); | ||||
| void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | ||||
|  | ||||
| //! The heap allocator backed by operating system's memory manager. | ||||
| constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; } | ||||
| @@ -135,270 +143,40 @@ constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; | ||||
| //! Helper to free memory allocated by heap allocator. | ||||
| #define mfree( ptr ) free( heap(), ptr ) | ||||
|  | ||||
| GEN_IMPL_INLINE b32 is_power_of_two( sw x ) | ||||
| { | ||||
| 	if ( x <= 0 ) | ||||
| 		return false; | ||||
| 	return ! ( x & ( x - 1 ) ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* align_forward( void* ptr, sw alignment ) | ||||
| { | ||||
| 	uptr p; | ||||
|  | ||||
| 	GEN_ASSERT( is_power_of_two( alignment ) ); | ||||
|  | ||||
| 	p = zpl_cast( uptr ) ptr; | ||||
| 	return zpl_cast( void* )( ( p + ( alignment - 1 ) ) & ~( alignment - 1 ) ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s64 align_forward_i64( s64 value, sw alignment ) | ||||
| { | ||||
| 	return value + ( alignment - value % alignment ) % alignment; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* pointer_add( void* ptr, sw bytes ) | ||||
| { | ||||
| 	return zpl_cast( void* )( zpl_cast( u8* ) ptr + bytes ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void const* pointer_add_const( void const* ptr, sw bytes ) | ||||
| { | ||||
| 	return zpl_cast( void const* )( zpl_cast( u8 const* ) ptr + bytes ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE sw pointer_diff( void const* begin, void const* end ) | ||||
| { | ||||
| 	return zpl_cast( sw )( zpl_cast( u8 const* ) end - zpl_cast( u8 const* ) begin ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* mem_move( void* dest, void const* source, sw n ) | ||||
| { | ||||
| 	if ( dest == NULL ) | ||||
| 	{ | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	u8*       d = zpl_cast( u8* ) dest; | ||||
| 	u8 const* s = zpl_cast( u8 const* ) source; | ||||
|  | ||||
| 	if ( d == s ) | ||||
| 		return d; | ||||
| 	if ( s + n <= d || d + n <= s )    // NOTE: Non-overlapping | ||||
| 		return mem_copy( d, s, n ); | ||||
|  | ||||
| 	if ( d < s ) | ||||
| 	{ | ||||
| 		if ( zpl_cast( uptr ) s % size_of( sw ) == zpl_cast( uptr ) d % size_of( sw ) ) | ||||
| 		{ | ||||
| 			while ( zpl_cast( uptr ) d % size_of( sw ) ) | ||||
| 			{ | ||||
| 				if ( ! n-- ) | ||||
| 					return dest; | ||||
| 				*d++ = *s++; | ||||
| 			} | ||||
| 			while ( n >= size_of( sw ) ) | ||||
| 			{ | ||||
| 				*zpl_cast( sw* ) d  = *zpl_cast( sw* ) s; | ||||
| 				n                  -= size_of( sw ); | ||||
| 				d                  += size_of( sw ); | ||||
| 				s                  += size_of( sw ); | ||||
| 			} | ||||
| 		} | ||||
| 		for ( ; n; n-- ) | ||||
| 			*d++ = *s++; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if ( ( zpl_cast( uptr ) s % size_of( sw ) ) == ( zpl_cast( uptr ) d % size_of( sw ) ) ) | ||||
| 		{ | ||||
| 			while ( zpl_cast( uptr )( d + n ) % size_of( sw ) ) | ||||
| 			{ | ||||
| 				if ( ! n-- ) | ||||
| 					return dest; | ||||
| 				d[ n ] = s[ n ]; | ||||
| 			} | ||||
| 			while ( n >= size_of( sw ) ) | ||||
| 			{ | ||||
| 				n                         -= size_of( sw ); | ||||
| 				*zpl_cast( sw* )( d + n )  = *zpl_cast( sw* )( s + n ); | ||||
| 			} | ||||
| 		} | ||||
| 		while ( n ) | ||||
| 			n--, d[ n ] = s[ n ]; | ||||
| 	} | ||||
|  | ||||
| 	return dest; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* mem_set( void* dest, u8 c, sw n ) | ||||
| { | ||||
| 	if ( dest == NULL ) | ||||
| 	{ | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	u8* s = zpl_cast( u8* ) dest; | ||||
| 	sw  k; | ||||
| 	u32 c32 = ( ( u32 )-1 ) / 255 * c; | ||||
|  | ||||
| 	if ( n == 0 ) | ||||
| 		return dest; | ||||
| 	s[ 0 ] = s[ n - 1 ] = c; | ||||
| 	if ( n < 3 ) | ||||
| 		return dest; | ||||
| 	s[ 1 ] = s[ n - 2 ] = c; | ||||
| 	s[ 2 ] = s[ n - 3 ] = c; | ||||
| 	if ( n < 7 ) | ||||
| 		return dest; | ||||
| 	s[ 3 ] = s[ n - 4 ] = c; | ||||
| 	if ( n < 9 ) | ||||
| 		return dest; | ||||
|  | ||||
| 	k  = -zpl_cast( sptr ) s & 3; | ||||
| 	s += k; | ||||
| 	n -= k; | ||||
| 	n &= -4; | ||||
|  | ||||
| 	*zpl_cast( u32* )( s + 0 )     = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 4 ) = c32; | ||||
| 	if ( n < 9 ) | ||||
| 		return dest; | ||||
| 	*zpl_cast( u32* )( s + 4 )      = c32; | ||||
| 	*zpl_cast( u32* )( s + 8 )      = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 12 ) = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 8 )  = c32; | ||||
| 	if ( n < 25 ) | ||||
| 		return dest; | ||||
| 	*zpl_cast( u32* )( s + 12 )     = c32; | ||||
| 	*zpl_cast( u32* )( s + 16 )     = c32; | ||||
| 	*zpl_cast( u32* )( s + 20 )     = c32; | ||||
| 	*zpl_cast( u32* )( s + 24 )     = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 28 ) = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 24 ) = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 20 ) = c32; | ||||
| 	*zpl_cast( u32* )( s + n - 16 ) = c32; | ||||
|  | ||||
| 	k  = 24 + ( zpl_cast( uptr ) s & 4 ); | ||||
| 	s += k; | ||||
| 	n -= k; | ||||
|  | ||||
| 	{ | ||||
| 		u64 c64 = ( zpl_cast( u64 ) c32 << 32 ) | c32; | ||||
| 		while ( n > 31 ) | ||||
| 		{ | ||||
| 			*zpl_cast( u64* )( s + 0 )  = c64; | ||||
| 			*zpl_cast( u64* )( s + 8 )  = c64; | ||||
| 			*zpl_cast( u64* )( s + 16 ) = c64; | ||||
| 			*zpl_cast( u64* )( s + 24 ) = c64; | ||||
|  | ||||
| 			n -= 32; | ||||
| 			s += 32; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return dest; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment ) | ||||
| { | ||||
| 	return a.Proc( a.Data, EAllocation_ALLOC, size, alignment, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* alloc( AllocatorInfo a, sw size ) | ||||
| { | ||||
| 	return alloc_align( a, size, GEN_DEFAULT_MEMORY_ALIGNMENT ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void free( AllocatorInfo a, void* ptr ) | ||||
| { | ||||
| 	if ( ptr != nullptr ) | ||||
| 		a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void free_all( AllocatorInfo a ) | ||||
| { | ||||
| 	a.Proc( a.Data, EAllocation_FREE_ALL, 0, 0, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* resize( AllocatorInfo a, void* ptr, sw old_size, sw new_size ) | ||||
| { | ||||
| 	return resize_align( a, ptr, old_size, new_size, GEN_DEFAULT_MEMORY_ALIGNMENT ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment ) | ||||
| { | ||||
| 	return a.Proc( a.Data, EAllocation_RESIZE, new_size, alignment, ptr, old_size, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void* default_resize_align( AllocatorInfo a, void* old_memory, sw old_size, sw new_size, sw alignment ) | ||||
| { | ||||
| 	if ( ! old_memory ) | ||||
| 		return alloc_align( a, new_size, alignment ); | ||||
|  | ||||
| 	if ( new_size == 0 ) | ||||
| 	{ | ||||
| 		free( a, old_memory ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	if ( new_size < old_size ) | ||||
| 		new_size = old_size; | ||||
|  | ||||
| 	if ( old_size == new_size ) | ||||
| 	{ | ||||
| 		return old_memory; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		void* new_memory = alloc_align( a, new_size, alignment ); | ||||
| 		if ( ! new_memory ) | ||||
| 			return nullptr; | ||||
| 		mem_move( new_memory, old_memory, min( new_size, old_size ) ); | ||||
| 		free( a, old_memory ); | ||||
| 		return new_memory; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void zero_size( void* ptr, sw size ) | ||||
| { | ||||
| 	mem_set( ptr, 0, size ); | ||||
| } | ||||
|  | ||||
| struct VirtualMemory | ||||
| { | ||||
| 	void*  data; | ||||
| 	sw size; | ||||
| 	ssize size; | ||||
| }; | ||||
|  | ||||
| //! Initialize virtual memory from existing data. | ||||
| VirtualMemory vm_from_memory( void* data, sw size ); | ||||
| VirtualMemory vm_from_memory( void* data, ssize size ); | ||||
|  | ||||
| //! Allocate virtual memory at address with size. | ||||
|  | ||||
| //! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it. | ||||
| //! @param size The size to serve. | ||||
| VirtualMemory vm_alloc( void* addr, sw size ); | ||||
| VirtualMemory vm_alloc( void* addr, ssize size ); | ||||
|  | ||||
| //! Release the virtual memory. | ||||
| b32 vm_free( VirtualMemory vm ); | ||||
|  | ||||
| //! Trim virtual memory. | ||||
| VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size ); | ||||
| VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ); | ||||
|  | ||||
| //! Purge virtual memory. | ||||
| b32 gen_vm_purge( VirtualMemory vm ); | ||||
|  | ||||
| //! Retrieve VM's page size and alignment. | ||||
| sw gen_virtual_memory_page_size( sw* alignment_out ); | ||||
| ssize gen_virtual_memory_page_size( ssize* alignment_out ); | ||||
|  | ||||
| struct Arena | ||||
| { | ||||
| 	static | ||||
| 	void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ); | ||||
| 	void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | ||||
|  | ||||
| 	static | ||||
| 	Arena init_from_memory( void* start, sw size ) | ||||
| 	Arena init_from_memory( void* start, ssize size ) | ||||
| 	{ | ||||
| 		return | ||||
| 		{ | ||||
| @@ -411,7 +189,7 @@ struct Arena | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	Arena init_from_allocator( AllocatorInfo backing, sw size ) | ||||
| 	Arena init_from_allocator( AllocatorInfo backing, ssize size ) | ||||
| 	{ | ||||
| 		Arena result = | ||||
| 		{ | ||||
| @@ -425,18 +203,18 @@ struct Arena | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	Arena init_sub( Arena& parent, sw size ) | ||||
| 	Arena init_sub( Arena& parent, ssize size ) | ||||
| 	{ | ||||
| 		return init_from_allocator( parent.Backing, size ); | ||||
| 	} | ||||
|  | ||||
| 	sw alignment_of( sw alignment ) | ||||
| 	ssize alignment_of( ssize alignment ) | ||||
| 	{ | ||||
| 		sw alignment_offset, result_pointer, mask; | ||||
| 		ssize alignment_offset, result_pointer, mask; | ||||
| 		GEN_ASSERT( is_power_of_two( alignment ) ); | ||||
|  | ||||
| 		alignment_offset = 0; | ||||
| 		result_pointer   = (sw) PhysicalStart + TotalUsed; | ||||
| 		result_pointer   = (ssize) PhysicalStart + TotalUsed; | ||||
| 		mask             = alignment - 1; | ||||
|  | ||||
| 		if ( result_pointer & mask ) | ||||
| @@ -463,17 +241,17 @@ struct Arena | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	sw size_remaining( sw alignment ) | ||||
| 	ssize size_remaining( ssize alignment ) | ||||
| 	{ | ||||
| 		sw result = TotalSize - ( TotalUsed + alignment_of( alignment ) ); | ||||
| 		ssize result = TotalSize - ( TotalUsed + alignment_of( alignment ) ); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	AllocatorInfo Backing; | ||||
| 	void*         PhysicalStart; | ||||
| 	sw            TotalSize; | ||||
| 	sw            TotalUsed; | ||||
| 	sw            TempCount; | ||||
| 	ssize            TotalSize; | ||||
| 	ssize            TotalUsed; | ||||
| 	ssize            TempCount; | ||||
|  | ||||
| 	operator AllocatorInfo() | ||||
| 	{ | ||||
| @@ -493,7 +271,7 @@ struct FixedArena | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	sw size_remaining( sw alignment ) | ||||
| 	ssize size_remaining( ssize alignment ) | ||||
| 	{ | ||||
| 		return arena.size_remaining( alignment ); | ||||
| 	} | ||||
| @@ -523,16 +301,16 @@ using Arena_4MB   = FixedArena< megabytes( 4 ) >; | ||||
| struct Pool | ||||
| { | ||||
| 	static | ||||
| 	void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ); | ||||
| 	void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | ||||
|  | ||||
| 	static | ||||
| 	Pool init( AllocatorInfo backing, sw num_blocks, sw block_size ) | ||||
| 	Pool init( AllocatorInfo backing, ssize num_blocks, ssize block_size ) | ||||
| 	{ | ||||
| 		return init_align( backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT ); | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	Pool init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align ); | ||||
| 	Pool init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align ); | ||||
|  | ||||
| 	void clear(); | ||||
|  | ||||
| @@ -547,10 +325,10 @@ struct Pool | ||||
| 	AllocatorInfo Backing; | ||||
| 	void*         PhysicalStart; | ||||
| 	void*         FreeList; | ||||
| 	sw            BlockSize; | ||||
| 	sw            BlockAlign; | ||||
| 	sw            TotalSize; | ||||
| 	sw            NumBlocks; | ||||
| 	ssize         BlockSize; | ||||
| 	ssize         BlockAlign; | ||||
| 	ssize         TotalSize; | ||||
| 	ssize         NumBlocks; | ||||
|  | ||||
| 	operator AllocatorInfo() | ||||
| 	{ | ||||
| @@ -558,4 +336,236 @@ struct Pool | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|  | ||||
| inline | ||||
| b32 is_power_of_two( ssize x ) { | ||||
| 	if ( x <= 0 ) | ||||
| 		return false; | ||||
| 	return ! ( x & ( x - 1 ) ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| mem_ptr align_forward( void* ptr, ssize alignment ) | ||||
| { | ||||
| 	GEN_ASSERT( is_power_of_two( alignment ) ); | ||||
| 	uptr p       = to_uptr(ptr); | ||||
| 	uptr forward = (p + ( alignment - 1 ) ) & ~( alignment - 1 ); | ||||
|  | ||||
| 	return to_mem_ptr(forward); | ||||
| } | ||||
|  | ||||
| inline s64 align_forward_i64( s64 value, ssize alignment ) { return value + ( alignment - value % alignment ) % alignment; } | ||||
|  | ||||
| inline void*       pointer_add      ( void*       ptr, ssize bytes ) { return rcast(void*,       rcast( u8*,        ptr) + bytes ); } | ||||
| inline void const* pointer_add_const( void const* ptr, ssize bytes ) { return rcast(void const*, rcast( u8 const*,  ptr) + bytes ); } | ||||
|  | ||||
| inline sptr pointer_diff( mem_ptr_const begin, mem_ptr_const end ) { | ||||
| 	return scast( ssize, rcast( u8 const*, end) - rcast(u8 const*, begin) ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* mem_move( void* destination, void const* source, ssize byte_count ) | ||||
| { | ||||
| 	if ( destination == NULL ) | ||||
| 	{ | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	u8*       dest_ptr = rcast( u8*, destination); | ||||
| 	u8 const* src_ptr  = rcast( u8 const*, source); | ||||
|  | ||||
| 	if ( dest_ptr == src_ptr ) | ||||
| 		return dest_ptr; | ||||
|  | ||||
| 	if ( src_ptr + byte_count <= dest_ptr || dest_ptr + byte_count <= src_ptr )    // NOTE: Non-overlapping | ||||
| 		return mem_copy( dest_ptr, src_ptr, byte_count ); | ||||
|  | ||||
| 	if ( dest_ptr < src_ptr ) | ||||
| 	{ | ||||
| 		if ( to_uptr(src_ptr) % size_of( ssize ) == to_uptr(dest_ptr) % size_of( ssize ) ) | ||||
| 		{ | ||||
| 			while ( pcast( uptr, dest_ptr) % size_of( ssize ) ) | ||||
| 			{ | ||||
| 				if ( ! byte_count-- ) | ||||
| 					return destination; | ||||
|  | ||||
| 				*dest_ptr++ = *src_ptr++; | ||||
| 			} | ||||
| 			while ( byte_count >= size_of( ssize ) ) | ||||
| 			{ | ||||
| 				* rcast(ssize*, dest_ptr)  = * rcast(ssize const*, src_ptr); | ||||
| 				byte_count -= size_of( ssize ); | ||||
| 				dest_ptr   += size_of( ssize ); | ||||
| 				src_ptr    += size_of( ssize ); | ||||
| 			} | ||||
| 		} | ||||
| 		for ( ; byte_count; byte_count-- ) | ||||
| 			*dest_ptr++ = *src_ptr++; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if ( ( to_uptr(src_ptr) % size_of( ssize ) ) == ( to_uptr(dest_ptr) % size_of( ssize ) ) ) | ||||
| 		{ | ||||
| 			while ( to_uptr( dest_ptr + byte_count ) % size_of( ssize ) ) | ||||
| 			{ | ||||
| 				if ( ! byte_count-- ) | ||||
| 					return destination; | ||||
|  | ||||
| 				dest_ptr[ byte_count ] = src_ptr[ byte_count ]; | ||||
| 			} | ||||
| 			while ( byte_count >= size_of( ssize ) ) | ||||
| 			{ | ||||
| 				byte_count                              -= size_of( ssize ); | ||||
| 				* rcast(ssize*, dest_ptr + byte_count )  = * rcast( ssize const*, src_ptr + byte_count ); | ||||
| 			} | ||||
| 		} | ||||
| 		while ( byte_count ) | ||||
| 			byte_count--, dest_ptr[ byte_count ] = src_ptr[ byte_count ]; | ||||
| 	} | ||||
|  | ||||
| 	return destination; | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* mem_set( void* destination, u8 fill_byte, ssize byte_count ) | ||||
| { | ||||
| 	if ( destination == NULL ) | ||||
| 	{ | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	ssize align_offset; | ||||
| 	u8*   dest_ptr  = rcast( u8*, destination); | ||||
| 	u32   fill_word = ( ( u32 )-1 ) / 255 * fill_byte; | ||||
|  | ||||
| 	if ( byte_count == 0 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	dest_ptr[ 0 ] = dest_ptr[ byte_count - 1 ] = fill_byte; | ||||
| 	if ( byte_count < 3 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	dest_ptr[ 1 ] = dest_ptr[ byte_count - 2 ] = fill_byte; | ||||
| 	dest_ptr[ 2 ] = dest_ptr[ byte_count - 3 ] = fill_byte; | ||||
| 	if ( byte_count < 7 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	dest_ptr[ 3 ] = dest_ptr[ byte_count - 4 ] = fill_byte; | ||||
| 	if ( byte_count < 9 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	align_offset  = -to_sptr( dest_ptr ) & 3; | ||||
| 	dest_ptr     += align_offset; | ||||
| 	byte_count   -= align_offset; | ||||
| 	byte_count   &= -4; | ||||
|  | ||||
| 	* rcast( u32*, ( dest_ptr + 0              ) ) = fill_word; | ||||
| 	* rcast( u32*, ( dest_ptr + byte_count - 4 ) ) = fill_word; | ||||
| 	if ( byte_count < 9 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	* rcast( u32*, dest_ptr + 4 )               = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + 8 )               = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 12 ) = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 8 )  = fill_word; | ||||
| 	if ( byte_count < 25 ) | ||||
| 		return destination; | ||||
|  | ||||
| 	* rcast( u32*, dest_ptr + 12 )              = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + 16 )              = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + 20 )              = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + 24 )              = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 28 ) = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 24 ) = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 20 ) = fill_word; | ||||
| 	* rcast( u32*, dest_ptr + byte_count - 16 ) = fill_word; | ||||
|  | ||||
| 	align_offset  = 24 + to_uptr( dest_ptr ) & 4; | ||||
| 	dest_ptr     += align_offset; | ||||
| 	byte_count   -= align_offset; | ||||
|  | ||||
| 	{ | ||||
| 		u64 fill_doubleword = ( scast( u64, fill_word) << 32 ) | fill_word; | ||||
| 		while ( byte_count > 31 ) | ||||
| 		{ | ||||
| 			* rcast( u64*, dest_ptr + 0 )  = fill_doubleword; | ||||
| 			* rcast( u64*, dest_ptr + 8 )  = fill_doubleword; | ||||
| 			* rcast( u64*, dest_ptr + 16 ) = fill_doubleword; | ||||
| 			* rcast( u64*, dest_ptr + 24 ) = fill_doubleword; | ||||
|  | ||||
| 			byte_count -= 32; | ||||
| 			dest_ptr += 32; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return destination; | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* alloc_align( AllocatorInfo a, ssize size, ssize alignment ) { | ||||
| 	return a.Proc( a.Data, EAllocation_ALLOC, size, alignment, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* alloc( AllocatorInfo a, ssize size ) { | ||||
| 	return alloc_align( a, size, GEN_DEFAULT_MEMORY_ALIGNMENT ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void free( AllocatorInfo a, void* ptr ) { | ||||
| 	if ( ptr != nullptr ) | ||||
| 		a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void free_all( AllocatorInfo a ) { | ||||
| 	a.Proc( a.Data, EAllocation_FREE_ALL, 0, 0, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* resize( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size ) { | ||||
| 	return resize_align( a, ptr, old_size, new_size, GEN_DEFAULT_MEMORY_ALIGNMENT ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment ) { | ||||
| 	return a.Proc( a.Data, EAllocation_RESIZE, new_size, alignment, ptr, old_size, GEN_DEFAULT_ALLOCATOR_FLAGS ); | ||||
| } | ||||
|  | ||||
| inline | ||||
| void* default_resize_align( AllocatorInfo a, void* old_memory, ssize old_size, ssize new_size, ssize alignment ) | ||||
| { | ||||
| 	if ( ! old_memory ) | ||||
| 		return alloc_align( a, new_size, alignment ); | ||||
|  | ||||
| 	if ( new_size == 0 ) | ||||
| 	{ | ||||
| 		free( a, old_memory ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	if ( new_size < old_size ) | ||||
| 		new_size = old_size; | ||||
|  | ||||
| 	if ( old_size == new_size ) | ||||
| 	{ | ||||
| 		return old_memory; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		void*  new_memory = alloc_align( a, new_size, alignment ); | ||||
| 		if ( ! new_memory ) | ||||
| 			return nullptr; | ||||
|  | ||||
| 		mem_move( new_memory, old_memory, min( new_size, old_size ) ); | ||||
| 		free( a, old_memory ); | ||||
| 		return new_memory; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| inline | ||||
| void zero_size( void* ptr, ssize size ) { | ||||
| 	mem_set( ptr, 0, size ); | ||||
| } | ||||
|  | ||||
| #pragma endregion Memory | ||||
|   | ||||
| @@ -36,7 +36,7 @@ u8 adt_destroy_branch( ADT_Node* node ) | ||||
| 	GEN_ASSERT_NOT_NULL( node ); | ||||
| 	if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes ) | ||||
| 	{ | ||||
| 		for ( sw i = 0; i < scast(sw, node->nodes.num()); ++i ) | ||||
| 		for ( ssize i = 0; i < scast(ssize, node->nodes.num()); ++i ) | ||||
| 		{ | ||||
| 			adt_destroy_branch( node->nodes + i ); | ||||
| 		} | ||||
| @@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) | ||||
| 	for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) | ||||
| 	{ | ||||
| 		if ( ! str_compare( node->nodes[ i ].name, name ) ) | ||||
| 		{ | ||||
| @@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) | ||||
|  | ||||
| 	if ( deep_search ) | ||||
| 	{ | ||||
| 		for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) | ||||
| 		for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) | ||||
| 		{ | ||||
| 			ADT_Node* res = adt_find( node->nodes + i, name, deep_search ); | ||||
|  | ||||
| @@ -111,7 +111,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) | ||||
| 				file_stream_open( &tmp, heap(), ( u8* )back, size_of( back ), EFileStream_WRITABLE ); | ||||
| 				adt_print_number( &tmp, node ); | ||||
|  | ||||
| 				sw  fsize = 0; | ||||
| 				ssize  fsize = 0; | ||||
| 				u8* buf   = file_stream_buf( &tmp, &fsize ); | ||||
|  | ||||
| 				if ( ! str_compare( ( char const* )buf, value ) ) | ||||
| @@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) | ||||
|  | ||||
| internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) | ||||
| { | ||||
| 	for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) | ||||
| 	for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) | ||||
| 	{ | ||||
| 		if ( ! str_compare( node->nodes[ i ].name, name ) ) | ||||
| 		{ | ||||
| @@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | ||||
| 			/* run a value comparison against any child that is an object node */ | ||||
| 			else if ( node->type == EADT_TYPE_ARRAY ) | ||||
| 			{ | ||||
| 				for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) | ||||
| 				for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) | ||||
| 				{ | ||||
| 					ADT_Node* child = &node->nodes[ i ]; | ||||
| 					if ( child->type != EADT_TYPE_OBJECT ) | ||||
| @@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | ||||
| 		/* [value] */ | ||||
| 		else | ||||
| 		{ | ||||
| 			for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) | ||||
| 			for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ ) | ||||
| 			{ | ||||
| 				ADT_Node* child = &node->nodes[ i ]; | ||||
| 				if ( _adt_get_value( child, l_b2 ) ) | ||||
| @@ -256,8 +256,8 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | ||||
| 	/* handle array index lookup */ | ||||
| 	else | ||||
| 	{ | ||||
| 		sw idx = ( sw )str_to_i64( buf, NULL, 10 ); | ||||
| 		if ( idx >= 0 && idx < scast(sw, node->nodes.num()) ) | ||||
| 		ssize idx = ( ssize )str_to_i64( buf, NULL, 10 ); | ||||
| 		if ( idx >= 0 && idx < scast(ssize, node->nodes.num()) ) | ||||
| 		{ | ||||
| 			found_node = &node->nodes[ idx ]; | ||||
|  | ||||
| @@ -272,7 +272,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | ||||
| 	return found_node; | ||||
| } | ||||
|  | ||||
| ADT_Node* adt_alloc_at( ADT_Node* parent, sw index ) | ||||
| ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ) | ||||
| { | ||||
| 	if ( ! parent || ( parent->type != EADT_TYPE_OBJECT && parent->type != EADT_TYPE_ARRAY ) ) | ||||
| 	{ | ||||
| @@ -282,7 +282,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index ) | ||||
| 	if ( ! parent->nodes ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if ( index < 0 || index > scast(sw, parent->nodes.num()) ) | ||||
| 	if ( index < 0 || index > scast(ssize, parent->nodes.num()) ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	ADT_Node o = { 0 }; | ||||
| @@ -337,7 +337,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value ) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index ) | ||||
| ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index ) | ||||
| { | ||||
| 	GEN_ASSERT_NOT_NULL( node ); | ||||
| 	GEN_ASSERT_NOT_NULL( new_parent ); | ||||
| @@ -366,8 +366,8 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node ) | ||||
| 	GEN_ASSERT_NOT_NULL( other_node ); | ||||
| 	ADT_Node* parent                     = node->parent; | ||||
| 	ADT_Node* other_parent               = other_node->parent; | ||||
| 	sw        index                      = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); | ||||
| 	sw        index2                     = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) ); | ||||
| 	ssize        index                      = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); | ||||
| 	ssize        index2                     = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) ); | ||||
| 	ADT_Node  temp                       = parent->nodes[ index ]; | ||||
| 	temp.parent                          = other_parent; | ||||
| 	other_parent->nodes[ index2 ].parent = parent; | ||||
| @@ -380,7 +380,7 @@ void adt_remove_node( ADT_Node* node ) | ||||
| 	GEN_ASSERT_NOT_NULL( node ); | ||||
| 	GEN_ASSERT_NOT_NULL( node->parent ); | ||||
| 	ADT_Node* parent = node->parent; | ||||
| 	sw        index  = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); | ||||
| 	ssize        index  = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); | ||||
| 	parent->nodes.remove_at( index ); | ||||
| } | ||||
|  | ||||
| @@ -484,7 +484,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | ||||
| 	node_type = EADT_TYPE_INTEGER; | ||||
| 	neg_zero  = false; | ||||
|  | ||||
| 	sw   ib        = 0; | ||||
| 	ssize   ib        = 0; | ||||
| 	char buf[ 48 ] = { 0 }; | ||||
|  | ||||
| 	if ( *e == '+' ) | ||||
| @@ -550,7 +550,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | ||||
|  | ||||
| 	f32  eb          = 10; | ||||
| 	char expbuf[ 6 ] = { 0 }; | ||||
| 	sw   expi        = 0; | ||||
| 	ssize   expi        = 0; | ||||
|  | ||||
| 	if ( *e && ! ! str_find( "eE", *e ) ) | ||||
| 	{ | ||||
| @@ -595,7 +595,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | ||||
|  | ||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||
| 		char *q = buf, *base_string = q, *base_string2 = q; | ||||
| 		base_string           = zpl_cast( char* ) str_skip( base_string, '.' ); | ||||
| 		base_string           = ccast( char*, str_skip( base_string, '.' )); | ||||
| 		*base_string          = '\0'; | ||||
| 		base_string2          = base_string + 1; | ||||
| 		char* base_string_off = base_string2; | ||||
| @@ -816,13 +816,13 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 	char* beginChar; | ||||
| 	char* endChar; | ||||
|  | ||||
| 	sw columnIndex       = 0; | ||||
| 	sw totalColumnIndex = 0; | ||||
| 	ssize columnIndex       = 0; | ||||
| 	ssize totalColumnIndex = 0; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		char delimiter = 0; | ||||
| 		currentChar = zpl_cast( char* ) str_trim( currentChar, false ); | ||||
| 		currentChar = ccast( char*, str_trim( currentChar, false )); | ||||
|  | ||||
| 		if ( *currentChar == 0 ) | ||||
| 			break; | ||||
| @@ -846,7 +846,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 		#endif | ||||
| 			do | ||||
| 			{ | ||||
| 				endChar = zpl_cast( char* ) str_skip( endChar, '"' ); | ||||
| 				endChar = ccast( char*, str_skip( endChar, '"' )); | ||||
|  | ||||
| 				if ( *endChar && *( endChar + 1 ) == '"' ) | ||||
| 				{ | ||||
| @@ -865,7 +865,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 			} | ||||
|  | ||||
| 			*endChar    = 0; | ||||
| 			currentChar = zpl_cast( char* ) str_trim( endChar + 1, true ); | ||||
| 			currentChar = ccast( char*, str_trim( endChar + 1, true )); | ||||
| 			delimiter   = * currentChar; | ||||
|  | ||||
| 			/* unescape escaped quotes (so that unescaped text escapes :) */ | ||||
| @@ -902,7 +902,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
|  | ||||
| 			if ( * endChar ) | ||||
| 			{ | ||||
| 				currentChar = zpl_cast( char* ) str_trim( endChar, true ); | ||||
| 				currentChar = ccast( char*, str_trim( endChar, true )); | ||||
|  | ||||
| 				while ( char_is_space( *( endChar - 1 ) ) ) | ||||
| 				{ | ||||
| @@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ( columnIndex >= scast(sw, root->nodes.num()) ) | ||||
| 		if ( columnIndex >= scast(ssize, root->nodes.num()) ) | ||||
| 		{ | ||||
| 			adt_append_arr( root, NULL ); | ||||
| 		} | ||||
| @@ -989,7 +989,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 	/* consider first row as a header. */ | ||||
| 	if ( has_header ) | ||||
| 	{ | ||||
| 		for ( sw i = 0; i < scast(sw, root->nodes.num()); i++ ) | ||||
| 		for ( ssize i = 0; i < scast(ssize, root->nodes.num()); i++ ) | ||||
| 		{ | ||||
| 			CSV_Object* col = root->nodes + i; | ||||
| 			CSV_Object* hdr = col->nodes; | ||||
| @@ -1057,11 +1057,11 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) | ||||
| 	GEN_ASSERT_NOT_NULL( file ); | ||||
| 	GEN_ASSERT_NOT_NULL( obj ); | ||||
| 	GEN_ASSERT( obj->nodes ); | ||||
| 	sw cols = obj->nodes.num(); | ||||
| 	ssize cols = obj->nodes.num(); | ||||
| 	if ( cols == 0 ) | ||||
| 		return; | ||||
|  | ||||
| 	sw rows = obj->nodes[ 0 ].nodes.num(); | ||||
| 	ssize rows = obj->nodes[ 0 ].nodes.num(); | ||||
| 	if ( rows == 0 ) | ||||
| 		return; | ||||
|  | ||||
| @@ -1069,7 +1069,7 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) | ||||
|  | ||||
| 	if ( has_headers ) | ||||
| 	{ | ||||
| 		for ( sw i = 0; i < cols; i++ ) | ||||
| 		for ( ssize i = 0; i < cols; i++ ) | ||||
| 		{ | ||||
| 			_csv_write_header( file, &obj->nodes[ i ] ); | ||||
| 			if ( i + 1 != cols ) | ||||
| @@ -1080,9 +1080,9 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) | ||||
| 		str_fmt_file( file, "\n" ); | ||||
| 	} | ||||
|  | ||||
| 	for ( sw r = 0; r < rows; r++ ) | ||||
| 	for ( ssize r = 0; r < rows; r++ ) | ||||
| 	{ | ||||
| 		for ( sw i = 0; i < cols; i++ ) | ||||
| 		for ( ssize i = 0; i < cols; i++ ) | ||||
| 		{ | ||||
| 			_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] ); | ||||
| 			if ( i + 1 != cols ) | ||||
| @@ -1099,7 +1099,8 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi | ||||
| 	FileInfo tmp; | ||||
| 	file_stream_new( &tmp, a ); | ||||
| 	csv_write_delimiter( &tmp, obj, delimiter ); | ||||
| 	sw     fsize; | ||||
| 	 | ||||
| 	ssize  fsize; | ||||
| 	u8*    buf    = file_stream_buf( &tmp, &fsize ); | ||||
| 	String output = String::make_length( a, ( char* )buf, fsize ); | ||||
| 	file_close( &tmp ); | ||||
|   | ||||
| @@ -178,7 +178,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ); | ||||
| 	* @param index | ||||
| 	* @return zpl_adt_node * node | ||||
| 	*/ | ||||
| ADT_Node* adt_alloc_at( ADT_Node* parent, sw index ); | ||||
| ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ); | ||||
|  | ||||
| /** | ||||
| 	* @brief Allocate an unitialised node within a container. | ||||
| @@ -196,7 +196,7 @@ ADT_Node* adt_alloc( ADT_Node* parent ); | ||||
| 	* @param index | ||||
| 	* @return zpl_adt_node * node | ||||
| 	*/ | ||||
| ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index ); | ||||
| ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index ); | ||||
|  | ||||
| /** | ||||
| 	* @brief Move an existing node to a new container. | ||||
| @@ -400,31 +400,33 @@ enum CSV_Error : u32 | ||||
|  | ||||
| typedef ADT_Node CSV_Object; | ||||
|  | ||||
| GEN_DEF_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header ); | ||||
| u8                csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ); | ||||
| void              csv_free( CSV_Object* obj ); | ||||
| u8   csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header ); | ||||
| u8   csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ); | ||||
| void csv_free( CSV_Object* obj ); | ||||
|  | ||||
| GEN_DEF_INLINE void   csv_write( FileInfo* file, CSV_Object* obj ); | ||||
| GEN_DEF_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj ); | ||||
| void                  csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); | ||||
| String                csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); | ||||
| void   csv_write( FileInfo* file, CSV_Object* obj ); | ||||
| String csv_write_string( AllocatorInfo a, CSV_Object* obj ); | ||||
| void   csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); | ||||
| String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); | ||||
|  | ||||
| /* inline */ | ||||
|  | ||||
| GEN_IMPL_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header ) | ||||
| inline | ||||
| u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header ) | ||||
| { | ||||
| 	return csv_parse_delimiter( root, text, allocator, has_header, ',' ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void csv_write( FileInfo* file, CSV_Object* obj ) | ||||
| inline | ||||
| void csv_write( FileInfo* file, CSV_Object* obj ) | ||||
| { | ||||
| 	csv_write_delimiter( file, obj, ',' ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj ) | ||||
| inline | ||||
| String csv_write_string( AllocatorInfo a, CSV_Object* obj ) | ||||
| { | ||||
| 	return csv_write_string_delimiter( a, obj, ',' ); | ||||
| } | ||||
|  | ||||
| #pragma endregion CSV | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,6 @@ | ||||
| #pragma once | ||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||
| #	pragma once | ||||
| #endif | ||||
| 
 | ||||
| #pragma region Platform Detection | ||||
| 
 | ||||
| @@ -99,9 +101,6 @@ | ||||
| #  define GEN_GCC_VERSION_CHECK(major,minor,patch) (0) | ||||
| #endif | ||||
| 
 | ||||
| #define GEN_DEF_INLINE  static | ||||
| #define GEN_IMPL_INLINE static inline | ||||
| 
 | ||||
| #pragma endregion Platform Detection | ||||
| 
 | ||||
| #pragma region Mandatory Includes | ||||
| @@ -41,10 +41,10 @@ struct _format_info | ||||
| 	s32 precision; | ||||
| }; | ||||
|  | ||||
| internal sw _print_string( char* text, sw max_len, _format_info* info, char const* str ) | ||||
| internal ssize _print_string( char* text, ssize max_len, _format_info* info, char const* str ) | ||||
| { | ||||
| 	sw    res = 0, len = 0; | ||||
| 	sw    remaining = max_len; | ||||
| 	ssize    res = 0, len = 0; | ||||
| 	ssize    remaining = max_len; | ||||
| 	char* begin     = text; | ||||
|  | ||||
| 	if ( str == NULL && max_len >= 6 ) | ||||
| @@ -75,7 +75,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons | ||||
|  | ||||
| 		if ( info->width > res ) | ||||
| 		{ | ||||
| 			sw padding = info->width - len; | ||||
| 			ssize padding = info->width - len; | ||||
|  | ||||
| 			char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' '; | ||||
| 			while ( padding-- > 0 && remaining-- > 0 ) | ||||
| @@ -86,7 +86,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons | ||||
| 	{ | ||||
| 		if ( info && ( info->width > res ) ) | ||||
| 		{ | ||||
| 			sw   padding = info->width - len; | ||||
| 			ssize   padding = info->width - len; | ||||
| 			char pad     = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' '; | ||||
| 			while ( padding-- > 0 && remaining-- > 0 ) | ||||
| 				*text++ = pad, res++; | ||||
| @@ -108,16 +108,16 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| internal sw _print_char( char* text, sw max_len, _format_info* info, char arg ) | ||||
| internal ssize _print_char( char* text, ssize max_len, _format_info* info, char arg ) | ||||
| { | ||||
| 	char str[ 2 ] = ""; | ||||
| 	str[ 0 ]      = arg; | ||||
| 	return _print_string( text, max_len, info, str ); | ||||
| } | ||||
|  | ||||
| internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, char arg ) | ||||
| internal ssize _print_repeated_char( char* text, ssize max_len, _format_info* info, char arg ) | ||||
| { | ||||
| 	sw  res = 0; | ||||
| 	ssize  res = 0; | ||||
| 	s32 rem = ( info ) ? ( info->width > 0 ) ? info->width : 1 : 1; | ||||
| 	res     = rem; | ||||
| 	while ( rem-- > 0 ) | ||||
| @@ -126,24 +126,24 @@ internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, ch | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| internal sw _print_i64( char* text, sw max_len, _format_info* info, s64 value ) | ||||
| internal ssize _print_i64( char* text, ssize max_len, _format_info* info, s64 value ) | ||||
| { | ||||
| 	char num[ 130 ]; | ||||
| 	i64_to_str( value, num, info ? info->base : 10 ); | ||||
| 	return _print_string( text, max_len, info, num ); | ||||
| } | ||||
|  | ||||
| internal sw _print_u64( char* text, sw max_len, _format_info* info, u64 value ) | ||||
| internal ssize _print_u64( char* text, ssize max_len, _format_info* info, u64 value ) | ||||
| { | ||||
| 	char num[ 130 ]; | ||||
| 	u64_to_str( value, num, info ? info->base : 10 ); | ||||
| 	return _print_string( text, max_len, info, num ); | ||||
| } | ||||
|  | ||||
| internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexadecimal, f64 arg ) | ||||
| internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is_hexadecimal, f64 arg ) | ||||
| { | ||||
| 	// TODO: Handle exponent notation | ||||
| 	sw    width, len, remaining = max_len; | ||||
| 	ssize    width, len, remaining = max_len; | ||||
| 	char* text_begin = text; | ||||
|  | ||||
| 	if ( arg ) | ||||
| @@ -163,7 +163,7 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad | ||||
| 			text++; | ||||
| 		} | ||||
|  | ||||
| 		value  = zpl_cast( u64 ) arg; | ||||
| 		value  = scast( u64, arg); | ||||
| 		len    = _print_u64( text, remaining, NULL, value ); | ||||
| 		text  += len; | ||||
|  | ||||
| @@ -184,14 +184,14 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad | ||||
| 			text++; | ||||
| 			while ( info->precision-- > 0 ) | ||||
| 			{ | ||||
| 				value  = zpl_cast( u64 )( arg * mult ); | ||||
| 				value  = scast( u64, arg * mult ); | ||||
| 				len    = _print_u64( text, remaining, NULL, value ); | ||||
| 				text  += len; | ||||
| 				if ( len >= remaining ) | ||||
| 					remaining = min( remaining, 1 ); | ||||
| 				else | ||||
| 					remaining -= len; | ||||
| 				arg  -= zpl_cast( f64 ) value / mult; | ||||
| 				arg  -= scast( f64, value / mult); | ||||
| 				mult *= 10; | ||||
| 			} | ||||
| 		} | ||||
| @@ -239,15 +239,15 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad | ||||
| 	return ( text - text_begin ); | ||||
| } | ||||
|  | ||||
| neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va ) | ||||
| { | ||||
| 	char const* text_begin = text; | ||||
| 	sw          remaining  = max_len, res; | ||||
| 	ssize          remaining  = max_len, res; | ||||
|  | ||||
| 	while ( *fmt ) | ||||
| 	{ | ||||
| 		_format_info info = { 0 }; | ||||
| 		sw           len  = 0; | ||||
| 		ssize           len  = 0; | ||||
| 		info.precision    = -1; | ||||
|  | ||||
| 		while ( *fmt && *fmt != '%' && remaining ) | ||||
| @@ -311,7 +311,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			info.width = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 ); | ||||
| 			info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); | ||||
| 			if ( info.width != 0 ) | ||||
| 			{ | ||||
| 				info.flags |= GEN_FMT_WIDTH; | ||||
| @@ -329,7 +329,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				info.precision = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 ); | ||||
| 				info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); | ||||
| 			} | ||||
| 			info.flags &= ~GEN_FMT_ZERO; | ||||
| 		} | ||||
| @@ -411,7 +411,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| 				break; | ||||
|  | ||||
| 			case 'c' : | ||||
| 				len = _print_char( text, remaining, &info, zpl_cast( char ) va_arg( va, int ) ); | ||||
| 				len = _print_char( text, remaining, &info, scast( char, va_arg( va, int ) )); | ||||
| 				break; | ||||
|  | ||||
| 			case 's' : | ||||
| @@ -455,25 +455,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| 				switch ( info.flags & GEN_FMT_INTS ) | ||||
| 				{ | ||||
| 					case GEN_FMT_CHAR : | ||||
| 						value = zpl_cast( u64 ) zpl_cast( u8 ) va_arg( va, int ); | ||||
| 						value = scast( u64, scast( u8, va_arg( va, int ))); | ||||
| 						break; | ||||
| 					case GEN_FMT_SHORT : | ||||
| 						value = zpl_cast( u64 ) zpl_cast( u16 ) va_arg( va, int ); | ||||
| 						value = scast( u64, scast( u16, va_arg( va, int ))); | ||||
| 						break; | ||||
| 					case GEN_FMT_LONG : | ||||
| 						value = zpl_cast( u64 ) va_arg( va, unsigned long ); | ||||
| 					case GEN_FMT_LONG: | ||||
| 						value = scast( u64, va_arg( va, unsigned long )); | ||||
| 						break; | ||||
| 					case GEN_FMT_LLONG : | ||||
| 						value = zpl_cast( u64 ) va_arg( va, unsigned long long ); | ||||
| 						value = scast( u64, va_arg( va, unsigned long long )); | ||||
| 						break; | ||||
| 					case GEN_FMT_SIZE : | ||||
| 						value = zpl_cast( u64 ) va_arg( va, uw ); | ||||
| 						value = scast( u64, va_arg( va, usize )); | ||||
| 						break; | ||||
| 					case GEN_FMT_INTPTR : | ||||
| 						value = zpl_cast( u64 ) va_arg( va, uptr ); | ||||
| 						value = scast( u64, va_arg( va, uptr )); | ||||
| 						break; | ||||
| 					default : | ||||
| 						value = zpl_cast( u64 ) va_arg( va, unsigned int ); | ||||
| 						value = scast( u64, va_arg( va, unsigned int )); | ||||
| 						break; | ||||
| 				} | ||||
|  | ||||
| @@ -485,25 +485,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va ) | ||||
| 				switch ( info.flags & GEN_FMT_INTS ) | ||||
| 				{ | ||||
| 					case GEN_FMT_CHAR : | ||||
| 						value = zpl_cast( s64 ) zpl_cast( s8 ) va_arg( va, int ); | ||||
| 						value = scast( s64, scast( s8, va_arg( va, int ))); | ||||
| 						break; | ||||
| 					case GEN_FMT_SHORT : | ||||
| 						value = zpl_cast( s64 ) zpl_cast( s16 ) va_arg( va, int ); | ||||
| 						value = scast( s64, scast( s16, va_arg( va, int ))); | ||||
| 						break; | ||||
| 					case GEN_FMT_LONG : | ||||
| 						value = zpl_cast( s64 ) va_arg( va, long ); | ||||
| 						value = scast( s64, va_arg( va, long )); | ||||
| 						break; | ||||
| 					case GEN_FMT_LLONG : | ||||
| 						value = zpl_cast( s64 ) va_arg( va, long long ); | ||||
| 						value = scast( s64, va_arg( va, long long )); | ||||
| 						break; | ||||
| 					case GEN_FMT_SIZE : | ||||
| 						value = zpl_cast( s64 ) va_arg( va, uw ); | ||||
| 						value = scast( s64, va_arg( va, usize )); | ||||
| 						break; | ||||
| 					case GEN_FMT_INTPTR : | ||||
| 						value = zpl_cast( s64 ) va_arg( va, uptr ); | ||||
| 						value = scast( s64, va_arg( va, uptr )); | ||||
| 						break; | ||||
| 					default : | ||||
| 						value = zpl_cast( s64 ) va_arg( va, int ); | ||||
| 						value = scast( s64, va_arg( va, int )); | ||||
| 						break; | ||||
| 				} | ||||
|  | ||||
| @@ -540,17 +540,17 @@ char* str_fmt_buf( char const* fmt, ... ) | ||||
| 	return str; | ||||
| } | ||||
|  | ||||
| sw str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va ) | ||||
| ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va ) | ||||
| { | ||||
| 	local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ]; | ||||
| 	sw                              len = str_fmt_va( buf, size_of( buf ), fmt, va ); | ||||
| 	ssize                              len = str_fmt_va( buf, size_of( buf ), fmt, va ); | ||||
| 	b32                             res = file_write( f, buf, len - 1 );    // NOTE: prevent extra whitespace | ||||
| 	return res ? len : -1; | ||||
| } | ||||
|  | ||||
| sw str_fmt_file( struct FileInfo* f, char const* fmt, ... ) | ||||
| ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... ) | ||||
| { | ||||
| 	sw      res; | ||||
| 	ssize      res; | ||||
| 	va_list va; | ||||
| 	va_start( va, fmt ); | ||||
| 	res = str_fmt_file_va( f, fmt, va ); | ||||
| @@ -558,9 +558,9 @@ sw str_fmt_file( struct FileInfo* f, char const* fmt, ... ) | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| sw str_fmt( char* str, sw n, char const* fmt, ... ) | ||||
| ssize str_fmt( char* str, ssize n, char const* fmt, ... ) | ||||
| { | ||||
| 	sw      res; | ||||
| 	ssize      res; | ||||
| 	va_list va; | ||||
| 	va_start( va, fmt ); | ||||
| 	res = str_fmt_va( str, n, fmt, va ); | ||||
| @@ -568,19 +568,19 @@ sw str_fmt( char* str, sw n, char const* fmt, ... ) | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| sw str_fmt_out_va( char const* fmt, va_list va ) | ||||
| ssize str_fmt_out_va( char const* fmt, va_list va ) | ||||
| { | ||||
| 	return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va ); | ||||
| } | ||||
|  | ||||
| sw str_fmt_out_err_va( char const* fmt, va_list va ) | ||||
| ssize str_fmt_out_err_va( char const* fmt, va_list va ) | ||||
| { | ||||
| 	return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va ); | ||||
| } | ||||
|  | ||||
| sw str_fmt_out_err( char const* fmt, ... ) | ||||
| ssize str_fmt_out_err( char const* fmt, ... ) | ||||
| { | ||||
| 	sw      res; | ||||
| 	ssize      res; | ||||
| 	va_list va; | ||||
| 	va_start( va, fmt ); | ||||
| 	res = str_fmt_out_err_va( fmt, va ); | ||||
|   | ||||
| @@ -12,23 +12,23 @@ struct FileInfo; | ||||
| #endif | ||||
|  | ||||
| // NOTE: A locally persisting buffer is used internally | ||||
| char* str_fmt_buf       ( char const* fmt, ... ); | ||||
| char* str_fmt_buf_va    ( char const* fmt, va_list va ); | ||||
| sw    str_fmt           ( char* str, sw n, char const* fmt, ... ); | ||||
| sw    str_fmt_va        ( char* str, sw n, char const* fmt, va_list va ); | ||||
| sw    str_fmt_out_va    ( char const* fmt, va_list va ); | ||||
| sw    str_fmt_out_err   ( char const* fmt, ... ); | ||||
| sw    str_fmt_out_err_va( char const* fmt, va_list va ); | ||||
| sw    str_fmt_file      ( FileInfo* f, char const* fmt, ... ); | ||||
| sw    str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va ); | ||||
| char*  str_fmt_buf       ( char const* fmt, ... ); | ||||
| char*  str_fmt_buf_va    ( char const* fmt, va_list va ); | ||||
| ssize  str_fmt           ( char* str, ssize n, char const* fmt, ... ); | ||||
| ssize  str_fmt_va        ( char* str, ssize n, char const* fmt, va_list va ); | ||||
| ssize  str_fmt_out_va    ( char const* fmt, va_list va ); | ||||
| ssize  str_fmt_out_err   ( char const* fmt, ... ); | ||||
| ssize  str_fmt_out_err_va( char const* fmt, va_list va ); | ||||
| ssize  str_fmt_file      ( FileInfo* f, char const* fmt, ... ); | ||||
| ssize  str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va ); | ||||
|  | ||||
| constexpr | ||||
| char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | ||||
|  | ||||
| inline | ||||
| sw log_fmt(char const* fmt, ...) | ||||
| ssize log_fmt(char const* fmt, ...) | ||||
| { | ||||
| 	sw res; | ||||
| 	ssize res; | ||||
| 	va_list va; | ||||
|  | ||||
| 	va_start(va, fmt); | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| #pragma region String Ops | ||||
|  | ||||
| internal | ||||
| sw _scan_zpl_i64( const char* text, s32 base, s64* value ) | ||||
| ssize _scan_zpl_i64( const char* text, s32 base, s64* value ) | ||||
| { | ||||
| 	const char* text_begin = text; | ||||
| 	s64         result     = 0; | ||||
| @@ -56,7 +56,7 @@ global const char _num_to_char_table[] = | ||||
|  | ||||
| s64 str_to_i64( const char* str, char** end_ptr, s32 base ) | ||||
| { | ||||
| 	sw  len; | ||||
| 	ssize  len; | ||||
| 	s64 value; | ||||
|  | ||||
| 	if ( ! base ) | ||||
| @@ -85,7 +85,7 @@ void i64_to_str( s64 value, char* string, s32 base ) | ||||
| 		value    = -value; | ||||
| 	} | ||||
|  | ||||
| 	v = zpl_cast( u64 ) value; | ||||
| 	v = scast( u64, value); | ||||
| 	if ( v != 0 ) | ||||
| 	{ | ||||
| 		while ( v > 0 ) | ||||
| @@ -207,7 +207,7 @@ f64 str_to_f64( const char* str, char** end_ptr ) | ||||
| 	result = sign * ( frac ? ( value / scale ) : ( value * scale ) ); | ||||
|  | ||||
| 	if ( end_ptr ) | ||||
| 		*end_ptr = zpl_cast( char* ) str; | ||||
| 		* end_ptr = rcast( char*, ccast(char*, str) ); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|   | ||||
| @@ -5,41 +5,42 @@ | ||||
|  | ||||
| #pragma region String Ops | ||||
|  | ||||
| GEN_DEF_INLINE const char* char_first_occurence( const char* str, char c ); | ||||
| const char* char_first_occurence( const char* str, char c ); | ||||
| constexpr auto str_find = &char_first_occurence; | ||||
|  | ||||
| GEN_DEF_INLINE b32   char_is_alpha( char c ); | ||||
| GEN_DEF_INLINE b32   char_is_alphanumeric( char c ); | ||||
| GEN_DEF_INLINE b32   char_is_digit( char c ); | ||||
| GEN_DEF_INLINE b32   char_is_hex_digit( char c ); | ||||
| GEN_DEF_INLINE b32   char_is_space( char c ); | ||||
| GEN_DEF_INLINE char  char_to_lower( char c ); | ||||
| GEN_DEF_INLINE char  char_to_upper( char c ); | ||||
| b32   char_is_alpha( char c ); | ||||
| b32   char_is_alphanumeric( char c ); | ||||
| b32   char_is_digit( char c ); | ||||
| b32   char_is_hex_digit( char c ); | ||||
| b32   char_is_space( char c ); | ||||
| char  char_to_lower( char c ); | ||||
| char  char_to_upper( char c ); | ||||
|  | ||||
| GEN_DEF_INLINE s32  digit_to_int( char c ); | ||||
| GEN_DEF_INLINE s32  hex_digit_to_int( char c ); | ||||
| s32  digit_to_int( char c ); | ||||
| s32  hex_digit_to_int( char c ); | ||||
|  | ||||
| GEN_DEF_INLINE s32         str_compare( const char* s1, const char* s2 ); | ||||
| GEN_DEF_INLINE s32         str_compare( const char* s1, const char* s2, sw len ); | ||||
| GEN_DEF_INLINE char*       str_copy( char* dest, const char* source, sw len ); | ||||
| GEN_DEF_INLINE sw          str_copy_nulpad( char* dest, const char* source, sw len ); | ||||
| GEN_DEF_INLINE sw          str_len( const char* str ); | ||||
| GEN_DEF_INLINE sw          str_len( const char* str, sw max_len ); | ||||
| GEN_DEF_INLINE char*       str_reverse( char* str );    // NOTE: ASCII only | ||||
| GEN_DEF_INLINE char const* str_skip( char const* str, char c ); | ||||
| GEN_DEF_INLINE char const* str_skip_any( char const* str, char const* char_list ); | ||||
| GEN_DEF_INLINE char const* str_trim( char const* str, b32 catch_newline ); | ||||
| s32         str_compare( const char* s1, const char* s2 ); | ||||
| s32         str_compare( const char* s1, const char* s2, ssize len ); | ||||
| char*       str_copy( char* dest, const char* source, ssize len ); | ||||
| ssize       str_copy_nulpad( char* dest, const char* source, ssize len ); | ||||
| ssize       str_len( const char* str ); | ||||
| ssize       str_len( const char* str, ssize max_len ); | ||||
| char*       str_reverse( char* str );    // NOTE: ASCII only | ||||
| char const* str_skip( char const* str, char c ); | ||||
| char const* str_skip_any( char const* str, char const* char_list ); | ||||
| char const* str_trim( char const* str, b32 catch_newline ); | ||||
|  | ||||
| // NOTE: ASCII only | ||||
| GEN_DEF_INLINE void str_to_lower( char* str ); | ||||
| GEN_DEF_INLINE void str_to_upper( char* str ); | ||||
| void str_to_lower( char* str ); | ||||
| void str_to_upper( char* str ); | ||||
|  | ||||
| s64  str_to_i64( const char* str, char** end_ptr, s32 base ); | ||||
| void i64_to_str( s64 value, char* string, s32 base ); | ||||
| void u64_to_str( u64 value, char* string, s32 base ); | ||||
| f64  str_to_f64( const char* str, char** end_ptr ); | ||||
|  | ||||
| GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c ) | ||||
| inline | ||||
| const char* char_first_occurence( const char* s, char c ) | ||||
| { | ||||
| 	char ch = c; | ||||
| 	for ( ; *s != ch; s++ ) | ||||
| @@ -50,59 +51,67 @@ GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c ) | ||||
| 	return s; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 char_is_alpha( char c ) | ||||
| inline | ||||
| b32 char_is_alpha( char c ) | ||||
| { | ||||
| 	if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) ) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 char_is_alphanumeric( char c ) | ||||
| inline | ||||
| b32 char_is_alphanumeric( char c ) | ||||
| { | ||||
| 	return char_is_alpha( c ) || char_is_digit( c ); | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 char_is_digit( char c ) | ||||
| inline | ||||
| b32 char_is_digit( char c ) | ||||
| { | ||||
| 	if ( c >= '0' && c <= '9' ) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 char_is_hex_digit( char c ) | ||||
| inline | ||||
| b32 char_is_hex_digit( char c ) | ||||
| { | ||||
| 	if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) ) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE b32 char_is_space( char c ) | ||||
| inline | ||||
| b32 char_is_space( char c ) | ||||
| { | ||||
| 	if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' ) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char char_to_lower( char c ) | ||||
| inline | ||||
| char char_to_lower( char c ) | ||||
| { | ||||
| 	if ( c >= 'A' && c <= 'Z' ) | ||||
| 		return 'a' + ( c - 'A' ); | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char char_to_upper( char c ) | ||||
| inline char char_to_upper( char c ) | ||||
| { | ||||
| 	if ( c >= 'a' && c <= 'z' ) | ||||
| 		return 'A' + ( c - 'a' ); | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s32 digit_to_int( char c ) | ||||
| inline | ||||
| s32 digit_to_int( char c ) | ||||
| { | ||||
| 	return char_is_digit( c ) ? c - '0' : c - 'W'; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s32 hex_digit_to_int( char c ) | ||||
| inline | ||||
| s32 hex_digit_to_int( char c ) | ||||
| { | ||||
| 	if ( char_is_digit( c ) ) | ||||
| 		return digit_to_int( c ); | ||||
| @@ -113,7 +122,8 @@ GEN_IMPL_INLINE s32 hex_digit_to_int( char c ) | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 ) | ||||
| inline | ||||
| s32 str_compare( const char* s1, const char* s2 ) | ||||
| { | ||||
| 	while ( *s1 && ( *s1 == *s2 ) ) | ||||
| 	{ | ||||
| @@ -122,7 +132,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 ) | ||||
| 	return *( u8* )s1 - *( u8* )s2; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len ) | ||||
| inline | ||||
| s32 str_compare( const char* s1, const char* s2, ssize len ) | ||||
| { | ||||
| 	for ( ; len > 0; s1++, s2++, len-- ) | ||||
| 	{ | ||||
| @@ -134,7 +145,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len ) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len ) | ||||
| inline | ||||
| char* str_copy( char* dest, const char* source, ssize len ) | ||||
| { | ||||
| 	GEN_ASSERT_NOT_NULL( dest ); | ||||
| 	if ( source ) | ||||
| @@ -154,9 +166,10 @@ GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len ) | ||||
| 	return dest; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len ) | ||||
| inline | ||||
| ssize str_copy_nulpad( char* dest, const char* source, ssize len ) | ||||
| { | ||||
| 	sw result = 0; | ||||
| 	ssize result = 0; | ||||
| 	GEN_ASSERT_NOT_NULL( dest ); | ||||
| 	if ( source ) | ||||
| 	{ | ||||
| @@ -178,7 +191,8 @@ GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE sw str_len( const char* str ) | ||||
| inline | ||||
| ssize str_len( const char* str ) | ||||
| { | ||||
| 	if ( str == NULL ) | ||||
| 	{ | ||||
| @@ -190,17 +204,19 @@ GEN_IMPL_INLINE sw str_len( const char* str ) | ||||
| 	return str - p; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE sw str_len( const char* str, sw max_len ) | ||||
| inline | ||||
| ssize str_len( const char* str, ssize max_len ) | ||||
| { | ||||
| 	const char* end = zpl_cast( const char* ) mem_find( str, 0, max_len ); | ||||
| 	const char* end = rcast(const char*, mem_find( str, 0, max_len )); | ||||
| 	if ( end ) | ||||
| 		return end - str; | ||||
| 	return max_len; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char* str_reverse( char* str ) | ||||
| inline | ||||
| char* str_reverse( char* str ) | ||||
| { | ||||
| 	sw    len  = str_len( str ); | ||||
| 	ssize    len  = str_len( str ); | ||||
| 	char* a    = str + 0; | ||||
| 	char* b    = str + len - 1; | ||||
| 	len       /= 2; | ||||
| @@ -212,7 +228,8 @@ GEN_IMPL_INLINE char* str_reverse( char* str ) | ||||
| 	return str; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char const* str_skip( char const* str, char c ) | ||||
| inline | ||||
| char const* str_skip( char const* str, char c ) | ||||
| { | ||||
| 	while ( *str && *str != c ) | ||||
| 	{ | ||||
| @@ -221,11 +238,12 @@ GEN_IMPL_INLINE char const* str_skip( char const* str, char c ) | ||||
| 	return str; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list ) | ||||
| inline | ||||
| char const* str_skip_any( char const* str, char const* char_list ) | ||||
| { | ||||
| 	char const* closest_ptr     = zpl_cast( char const* ) pointer_add( ( void* )str, str_len( str ) ); | ||||
| 	sw          char_list_count = str_len( char_list ); | ||||
| 	for ( sw i = 0; i < char_list_count; i++ ) | ||||
| 	char const* closest_ptr     = rcast( char const*, pointer_add_const( rcast(void const*, str), str_len( str ) )); | ||||
| 	ssize       char_list_count = str_len( char_list ); | ||||
| 	for ( ssize i = 0; i < char_list_count; i++ ) | ||||
| 	{ | ||||
| 		char const* p = str_skip( str, char_list[ i ] ); | ||||
| 		closest_ptr   = min( closest_ptr, p ); | ||||
| @@ -233,7 +251,8 @@ GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list | ||||
| 	return closest_ptr; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline ) | ||||
| inline | ||||
| char const* str_trim( char const* str, b32 catch_newline ) | ||||
| { | ||||
| 	while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) ) | ||||
| 	{ | ||||
| @@ -242,7 +261,8 @@ GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline ) | ||||
| 	return str; | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void str_to_lower( char* str ) | ||||
| inline | ||||
| void str_to_lower( char* str ) | ||||
| { | ||||
| 	if ( ! str ) | ||||
| 		return; | ||||
| @@ -253,7 +273,8 @@ GEN_IMPL_INLINE void str_to_lower( char* str ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| GEN_IMPL_INLINE void str_to_upper( char* str ) | ||||
| inline | ||||
| void str_to_upper( char* str ) | ||||
| { | ||||
| 	if ( ! str ) | ||||
| 		return; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| #pragma region String | ||||
|  | ||||
| String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... ) | ||||
| String String::fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... ) | ||||
| { | ||||
| 	va_list va; | ||||
| 	va_start( va, fmt ); | ||||
| @@ -15,9 +15,9 @@ String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* | ||||
| 	return make( allocator, buf ); | ||||
| } | ||||
|  | ||||
| String String::make_length( AllocatorInfo allocator, char const* str, sw length ) | ||||
| String String::make_length( AllocatorInfo allocator, char const* str, ssize length ) | ||||
| { | ||||
| 	constexpr sw header_size = sizeof( Header ); | ||||
| 	constexpr ssize header_size = sizeof( Header ); | ||||
|  | ||||
| 	s32   alloc_size = header_size + length + 1; | ||||
| 	void* allocation = alloc( allocator, alloc_size ); | ||||
| @@ -41,9 +41,9 @@ String String::make_length( AllocatorInfo allocator, char const* str, sw length | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| String String::make_reserve( AllocatorInfo allocator, sw capacity ) | ||||
| String String::make_reserve( AllocatorInfo allocator, ssize capacity ) | ||||
| { | ||||
| 	constexpr sw header_size = sizeof( Header ); | ||||
| 	constexpr ssize header_size = sizeof( Header ); | ||||
|  | ||||
| 	s32   alloc_size = header_size + capacity + 1; | ||||
| 	void* allocation = alloc( allocator, alloc_size ); | ||||
| @@ -78,7 +78,7 @@ String String::fmt_buf( AllocatorInfo allocator, char const* fmt, ... ) | ||||
|  | ||||
| bool String::append_fmt( char const* fmt, ... ) | ||||
| { | ||||
| 	sw   res; | ||||
| 	ssize   res; | ||||
| 	char buf[ GEN_PRINTF_MAXLEN ] = { 0 }; | ||||
|  | ||||
| 	va_list va; | ||||
| @@ -89,9 +89,9 @@ bool String::append_fmt( char const* fmt, ... ) | ||||
| 	return append( buf, res ); | ||||
| } | ||||
|  | ||||
| bool String::make_space_for( char const* str, sw add_len ) | ||||
| bool String::make_space_for( char const* str, ssize add_len ) | ||||
| { | ||||
| 	sw available = avail_space(); | ||||
| 	ssize available = avail_space(); | ||||
|  | ||||
| 	// NOTE: Return if there is enough space left | ||||
| 	if ( available >= add_len ) | ||||
| @@ -100,7 +100,7 @@ bool String::make_space_for( char const* str, sw add_len ) | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		sw new_len, old_size, new_size; | ||||
| 		ssize new_len, old_size, new_size; | ||||
|  | ||||
| 		void* ptr; | ||||
| 		void* new_ptr; | ||||
| @@ -118,7 +118,7 @@ bool String::make_space_for( char const* str, sw add_len ) | ||||
| 		if ( new_ptr == nullptr ) | ||||
| 			return false; | ||||
|  | ||||
| 		header            = zpl_cast( Header* ) new_ptr; | ||||
| 		header            = rcast( Header*, new_ptr); | ||||
| 		header->Allocator = allocator; | ||||
| 		header->Capacity  = new_len; | ||||
|  | ||||
|   | ||||
| @@ -8,15 +8,15 @@ | ||||
| // Constant string with length. | ||||
| struct StrC | ||||
| { | ||||
| 	sw          Len; | ||||
| 	ssize          Len; | ||||
| 	char const* Ptr; | ||||
|  | ||||
| 	operator char const* ()            const { return Ptr; } | ||||
| 	char const& operator[]( sw index ) const { return Ptr[index]; } | ||||
| 	operator char const* ()               const { return Ptr; } | ||||
| 	char const& operator[]( ssize index ) const { return Ptr[index]; } | ||||
| }; | ||||
|  | ||||
| #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) ) | ||||
| #define txt( text ) StrC { sizeof( text ) - 1, ( text ) } | ||||
| #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) | ||||
| #define txt( text )         StrC { sizeof( text ) - 1, ( text ) } | ||||
|  | ||||
| inline | ||||
| StrC to_str( char const* str ) | ||||
| @@ -33,12 +33,12 @@ struct String | ||||
| 	struct Header | ||||
| 	{ | ||||
| 		AllocatorInfo Allocator; | ||||
| 		sw            Capacity; | ||||
| 		sw            Length; | ||||
| 		ssize            Capacity; | ||||
| 		ssize            Length; | ||||
| 	}; | ||||
|  | ||||
| 	static | ||||
| 	uw grow_formula( uw value ) | ||||
| 	usize grow_formula( usize value ) | ||||
| 	{ | ||||
| 		// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library. | ||||
| 		return 4 * value + 8; | ||||
| @@ -47,7 +47,7 @@ struct String | ||||
| 	static | ||||
| 	String make( AllocatorInfo allocator, char const* str ) | ||||
| 	{ | ||||
| 		sw length = str ? str_len( str ) : 0; | ||||
| 		ssize length = str ? str_len( str ) : 0; | ||||
| 		return make_length( allocator, str, length ); | ||||
| 	} | ||||
|  | ||||
| @@ -58,23 +58,23 @@ struct String | ||||
| 	} | ||||
|  | ||||
| 	static | ||||
| 	String make_reserve( AllocatorInfo allocator, sw capacity ); | ||||
| 	String make_reserve( AllocatorInfo allocator, ssize capacity ); | ||||
|  | ||||
| 	static | ||||
| 	String make_length( AllocatorInfo allocator, char const* str, sw length ); | ||||
| 	String make_length( AllocatorInfo allocator, char const* str, ssize length ); | ||||
|  | ||||
| 	static | ||||
| 	String fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... ); | ||||
| 	String fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... ); | ||||
|  | ||||
| 	static | ||||
| 	String fmt_buf( AllocatorInfo allocator, char const* fmt, ... ); | ||||
|  | ||||
| 	static | ||||
| 	String join( AllocatorInfo allocator, char const** parts, sw num_parts, char const* glue ) | ||||
| 	String join( AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue ) | ||||
| 	{ | ||||
| 		String result = make( allocator, "" ); | ||||
|  | ||||
| 		for ( sw idx = 0; idx < num_parts; ++idx ) | ||||
| 		for ( ssize idx = 0; idx < num_parts; ++idx ) | ||||
| 		{ | ||||
| 			result.append( parts[ idx ] ); | ||||
|  | ||||
| @@ -91,7 +91,7 @@ struct String | ||||
| 		if ( lhs.length() != rhs.length() ) | ||||
| 			return false; | ||||
|  | ||||
| 		for ( sw idx = 0; idx < lhs.length(); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < lhs.length(); ++idx ) | ||||
| 			if ( lhs[ idx ] != rhs[ idx ] ) | ||||
| 				return false; | ||||
|  | ||||
| @@ -104,14 +104,14 @@ struct String | ||||
| 		if ( lhs.length() != (rhs.Len) ) | ||||
| 			return false; | ||||
|  | ||||
| 		for ( sw idx = 0; idx < lhs.length(); ++idx ) | ||||
| 		for ( ssize idx = 0; idx < lhs.length(); ++idx ) | ||||
| 			if ( lhs[idx] != rhs[idx] ) | ||||
| 				return false; | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	bool make_space_for( char const* str, sw add_len ); | ||||
| 	bool make_space_for( char const* str, ssize add_len ); | ||||
|  | ||||
| 	bool append( char c ) | ||||
| 	{ | ||||
| @@ -123,11 +123,11 @@ struct String | ||||
| 		return append( str, str_len( str ) ); | ||||
| 	} | ||||
|  | ||||
| 	bool append( char const* str, sw length ) | ||||
| 	bool append( char const* str, ssize length ) | ||||
| 	{ | ||||
| 		if ( sptr(str) > 0 ) | ||||
| 		{ | ||||
| 			sw curr_len = this->length(); | ||||
| 			ssize curr_len = this->length(); | ||||
|  | ||||
| 			if ( ! make_space_for( str, length ) ) | ||||
| 				return false; | ||||
| @@ -155,7 +155,7 @@ struct String | ||||
|  | ||||
| 	bool append_fmt( char const* fmt, ... ); | ||||
|  | ||||
| 	sw avail_space() const | ||||
| 	ssize avail_space() const | ||||
| 	{ | ||||
| 		Header const& | ||||
| 		header = * rcast( Header const*, Data - sizeof( Header )); | ||||
| @@ -168,7 +168,7 @@ struct String | ||||
| 		return Data[ length() - 1 ]; | ||||
| 	} | ||||
|  | ||||
| 	sw capacity() const | ||||
| 	ssize capacity() const | ||||
| 	{ | ||||
| 		Header const& | ||||
| 		header = * rcast( Header const*, Data - sizeof( Header )); | ||||
| @@ -201,7 +201,7 @@ struct String | ||||
| 		return *(Header*)(Data - sizeof(Header)); | ||||
| 	} | ||||
|  | ||||
| 	sw length() const | ||||
| 	ssize length() const | ||||
| 	{ | ||||
| 		Header const& | ||||
| 		header = * rcast( Header const*, Data - sizeof( Header )); | ||||
| @@ -273,7 +273,7 @@ struct String | ||||
|  | ||||
| 	void trim( char const* cut_set ) | ||||
| 	{ | ||||
| 		sw len = 0; | ||||
| 		ssize len = 0; | ||||
|  | ||||
| 		char* start_pos = Data; | ||||
| 		char* end_pos   = Data + length() - 1; | ||||
| @@ -284,7 +284,7 @@ struct String | ||||
| 		while ( end_pos > start_pos && char_first_occurence( cut_set, *end_pos ) ) | ||||
| 			end_pos--; | ||||
|  | ||||
| 		len = scast( sw, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) ); | ||||
| 		len = scast( ssize, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) ); | ||||
|  | ||||
| 		if ( Data != start_pos ) | ||||
| 			mem_move( Data, start_pos, len ); | ||||
| @@ -379,19 +379,19 @@ struct String | ||||
| 		if ( this == & other ) | ||||
| 			return *this; | ||||
|  | ||||
| 		String& this_ = ccast( String, *this ); | ||||
| 		String* | ||||
| 		this_ = ccast(String*, this); | ||||
| 		this_->Data = other.Data; | ||||
|  | ||||
| 		this_.Data = other.Data; | ||||
|  | ||||
| 		return this_; | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	char& operator [] ( sw index ) | ||||
| 	char& operator [] ( ssize index ) | ||||
| 	{ | ||||
| 		return Data[ index ]; | ||||
| 	} | ||||
|  | ||||
| 	char const& operator [] ( sw index ) const | ||||
| 	char const& operator [] ( ssize index ) const | ||||
| 	{ | ||||
| 		return Data[ index ]; | ||||
| 	} | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
| 	{ | ||||
| 		u32 hi, lo; | ||||
| 		__asm__ __volatile__( "rdtsc" : "=a"( lo ), "=d"( hi ) ); | ||||
| 		return ( zpl_cast( u64 ) lo ) | ( ( zpl_cast( u64 ) hi ) << 32 ); | ||||
| 		return ( scast( u64, lo ) | ( ( scast( u64, hi ) << 32 ); | ||||
| 	} | ||||
| 	#elif defined( __powerpc__ ) | ||||
| 	u64 read_cpu_time_stamp_counter( void ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user