mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 15:00:53 -07:00 
			
		
		
		
	Progresss
This commit is contained in:
		| @@ -25,6 +25,8 @@ This library was written in a subset of C++ where the following are not used at | ||||
| * Exceptions | ||||
|  | ||||
| Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.   | ||||
| The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP). | ||||
|  | ||||
| There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`) | ||||
|  | ||||
| Two generic templated containers are used throughout the library: | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #define GEN_ENFORCE_STRONG_CODE_TYPES | ||||
| #define GEN_EXPOSE_BACKEND | ||||
| #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 | ||||
| #define GEN_SUPPORT_CPP_REFERENCES      1 | ||||
| #include "../project/gen.cpp" | ||||
|  | ||||
| #include "helpers/push_ignores.inline.hpp" | ||||
| @@ -135,26 +136,40 @@ int gen_main() | ||||
| 				case ECode::Using: | ||||
| 				{ | ||||
| 					log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); | ||||
| 					CodeUsing   using_ver   = entry.cast<CodeUsing>(); | ||||
| 					CodeUsing   using_ver   = entry.code_cast<CodeUsing>(); | ||||
| 					CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | ||||
|  | ||||
| 					memory.append(typedef_ver); | ||||
| 				} | ||||
| 				break; | ||||
| 				case ECode::Function_Fwd: | ||||
| 				{ | ||||
| 					CodeFn fn = entry.code_cast<CodeFn>(); | ||||
| 					if ( fn->Name.is_equal(txt("free")) ) | ||||
| 					{ | ||||
| 						fn->Name = get_cached_string(txt("gen_free_ptr")); | ||||
| 					} | ||||
| 					memory.append(entry); | ||||
| 				} | ||||
| 				break; | ||||
| 				case ECode::Function: | ||||
| 				{ | ||||
| 					CodeFn fn = entry.cast<CodeFn>(); | ||||
| 					CodeFn fn = entry.code_cast<CodeFn>(); | ||||
| 					s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr ); | ||||
| 					if (constexpr_found > -1) { | ||||
| 						log_fmt("Found constexpr: %S\n", entry->to_string()); | ||||
| 						fn->Specs.append(ESpecifier::Inline); | ||||
| 					} | ||||
| 					if ( fn->Name.is_equal(txt("free")) ) | ||||
| 					{ | ||||
| 						fn->Name = get_cached_string(txt("gen_free_ptr")); | ||||
| 					} | ||||
| 					memory.append(entry); | ||||
| 				} | ||||
| 				break; | ||||
| 				case ECode::Template: | ||||
| 				{ | ||||
| 					CodeTemplate tmpl = entry.cast<CodeTemplate>(); | ||||
| 					CodeTemplate tmpl = entry.code_cast<CodeTemplate>(); | ||||
| 					if ( tmpl->Declaration->Name.contains(txt("swap"))) | ||||
| 					{ | ||||
| 						CodeBody macro_swap = parse_global_body( txt(R"( | ||||
| @@ -297,7 +312,7 @@ int gen_main() | ||||
| 				{ | ||||
| 					if ( entry->Name.is_equal(txt("String")) ) | ||||
| 					{ | ||||
| 						CodeTypedef c_def = parse_typedef(code( typedef Type* String; )); | ||||
| 						CodeTypedef c_def = parse_typedef(code( typedef char* String; )); | ||||
| 						strings.append(c_def); | ||||
| 						strings.append(fmt_newline); | ||||
| 						++ entry; | ||||
| @@ -307,6 +322,29 @@ int gen_main() | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 				case ECode::Struct: | ||||
| 				{ | ||||
| 					CodeBody body     = entry->Body->operator CodeBody(); | ||||
| 					CodeBody new_body = def_body( entry->Body->Type ); | ||||
| 					for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch | ||||
| 					(body_entry->Type) { | ||||
| 						case ECode::Preprocess_If: | ||||
| 						{ | ||||
| 							b32 found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), body_entry, body ); | ||||
| 							if (found) break; | ||||
|  | ||||
| 							new_body.append(body_entry); | ||||
| 						} | ||||
| 						break; | ||||
| 						default: | ||||
| 							new_body.append(body_entry); | ||||
| 						break; | ||||
| 					} | ||||
| 					entry->Body = rcast(AST*, new_body.ast); | ||||
| 					strings.append(entry); | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 				default: | ||||
| 					strings.append(entry); | ||||
| 				break; | ||||
| @@ -316,8 +354,8 @@ int gen_main() | ||||
|  | ||||
| 		Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" ); | ||||
| 		Code timing = scan_file( project_dir "dependencies/timing.hpp" ); | ||||
| 		header.print( filesystem ); | ||||
| 		header.print( timing ); | ||||
| 		// header.print( filesystem ); | ||||
| 		// header.print( timing ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||
| @@ -335,6 +373,7 @@ int gen_main() | ||||
| 		CodeBody especifier  = gen_especifier( project_dir "enums/ESpecifier.csv" ); | ||||
| 		CodeBody ast_inlines = gen_ast_inlines(); | ||||
|  | ||||
| #if 0 | ||||
| 		header.print_fmt("#pragma region Types\n"); | ||||
| 		header.print( types ); | ||||
| 		header.print( fmt_newline ); | ||||
| @@ -345,6 +384,7 @@ int gen_main() | ||||
| 		header.print( dump_to_scratch_and_retireve( especifier )); | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print_fmt("#pragma endregion Types\n\n"); | ||||
| 	#endif | ||||
| 	} | ||||
|  | ||||
| 	header.print( pop_ignores ); | ||||
|   | ||||
| @@ -20,7 +20,7 @@ CodeBody gen_fixed_arenas() | ||||
| 		inline | ||||
| 		void fixed_arena_init_<Name>(FixedArena_<Name>* result) { | ||||
| 			zero_size(& result->memory[0], <Size>); | ||||
| 			result.arena = arena_init_from_memory(& result->memory[0], <Size>); | ||||
| 			result->arena = arena_init_from_memory(& result->memory[0], <Size>); | ||||
| 		} | ||||
|  | ||||
| 		inline | ||||
|   | ||||
| @@ -8,7 +8,7 @@ using SwapContentProc = CodeBody(void); | ||||
| b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) | ||||
| { | ||||
| 	b32 found = false; | ||||
| 	CodePreprocessCond cond = entry_iter.cast<CodePreprocessCond>(); | ||||
| 	CodePreprocessCond cond = entry_iter.code_cast<CodePreprocessCond>(); | ||||
| 	if ( cond->Content.contains(cond_sig) ) | ||||
| 	{ | ||||
| 		log_fmt("Preprocess cond found: %S\n", cond->Content); | ||||
| @@ -44,7 +44,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod | ||||
| bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) | ||||
| { | ||||
| 	bool found = false; | ||||
| 	CodePragma possible_region = entry_iter.cast<CodePragma>(); | ||||
| 	CodePragma possible_region = entry_iter.code_cast<CodePragma>(); | ||||
|  | ||||
| 	String region_sig    = string_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr); | ||||
| 	String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); | ||||
| @@ -58,7 +58,7 @@ bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_ | ||||
| 		(entry_iter->Type) { | ||||
| 			case ECode::Preprocess_Pragma: | ||||
| 			{ | ||||
| 				CodePragma possible_end_region = entry_iter.cast<CodePragma>(); | ||||
| 				CodePragma possible_end_region = entry_iter.code_cast<CodePragma>(); | ||||
| 				if ( possible_end_region->Content.contains(endregion_sig) ) { | ||||
| 					// body.append(possible_end_region); | ||||
| 					continue_for = false; | ||||
|   | ||||
							
								
								
									
										7
									
								
								gen_c_library/gen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								gen_c_library/gen.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #define GEN_IMPLEMENTATION | ||||
| #include "gen/gen.h" | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	// init(); | ||||
| } | ||||
| @@ -30,6 +30,13 @@ Feature Macros: | ||||
| * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. | ||||
| * `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. | ||||
|  | ||||
| By default the base library implementation strictly uses a C-like interface. This is to allow for the generation of a C-variant of the library using [gen_c_library](../gen_c_library/). However, the library was written in C++ and supports some of its features: | ||||
|  | ||||
| * `GEN_SUPPORT_CPP_REFERENCES` : Will enable support for reference interface on some definitions | ||||
| * `GEN_SUPPORT_CPP_MEMBER_FEATURES` : Will enable support for definitions to have their interface as members. | ||||
|  | ||||
| *Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)* | ||||
|  | ||||
| ## On multi-threading | ||||
|  | ||||
| Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. | ||||
|   | ||||
| @@ -11,7 +11,7 @@ internal void deinit(); | ||||
| internal | ||||
| void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | ||||
| { | ||||
| 	Arena* last = & back(Global_AllocatorBuckets); | ||||
| 	Arena* last = back(& Global_AllocatorBuckets); | ||||
|  | ||||
| 	switch ( type ) | ||||
| 	{ | ||||
| @@ -24,10 +24,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s | ||||
| 				if ( bucket.PhysicalStart == nullptr ) | ||||
| 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | ||||
|  | ||||
| 				if ( ! append( Global_AllocatorBuckets, bucket ) ) | ||||
| 				if ( ! append( & Global_AllocatorBuckets, bucket ) ) | ||||
| 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | ||||
|  | ||||
| 				last = & back(Global_AllocatorBuckets); | ||||
| 				last = back(& Global_AllocatorBuckets); | ||||
| 			} | ||||
|  | ||||
| 			return alloc_align( allocator_info(last), size, alignment ); | ||||
| @@ -51,10 +51,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s | ||||
| 				if ( bucket.PhysicalStart == nullptr ) | ||||
| 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | ||||
|  | ||||
| 				if ( ! append( Global_AllocatorBuckets, bucket ) ) | ||||
| 				if ( ! append( & Global_AllocatorBuckets, bucket ) ) | ||||
| 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | ||||
|  | ||||
| 				last = & back(Global_AllocatorBuckets); | ||||
| 				last = back(& Global_AllocatorBuckets); | ||||
| 			} | ||||
|  | ||||
| 			void* result = alloc_align( last->Backing, size, alignment ); | ||||
| @@ -249,7 +249,7 @@ void init() | ||||
| 		if ( bucket.PhysicalStart == nullptr ) | ||||
| 			GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets"); | ||||
|  | ||||
| 		append( Global_AllocatorBuckets, bucket ); | ||||
| 		append( & Global_AllocatorBuckets, bucket ); | ||||
| 	} | ||||
|  | ||||
| 	// Setup the arrays | ||||
| @@ -272,7 +272,7 @@ void init() | ||||
| 		if ( code_pool.PhysicalStart == nullptr ) | ||||
| 			GEN_FATAL( "gen::init: Failed to initialize the code pool" ); | ||||
|  | ||||
| 		append(CodePools, code_pool ); | ||||
| 		append( & CodePools, code_pool ); | ||||
|  | ||||
| 		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); | ||||
|  | ||||
| @@ -281,7 +281,7 @@ void init() | ||||
| 		if ( string_arena.PhysicalStart == nullptr ) | ||||
| 			GEN_FATAL( "gen::init: Failed to initialize the string arena" ); | ||||
|  | ||||
| 		append(StringArenas, string_arena ); | ||||
| 		append( & StringArenas, string_arena ); | ||||
| 	} | ||||
|  | ||||
| 	// Setup the hash tables | ||||
| @@ -323,12 +323,12 @@ void deinit() | ||||
|  | ||||
| 	destroy(StringCache); | ||||
|  | ||||
| 	free(CodePools); | ||||
| 	free(StringArenas); | ||||
| 	free( & CodePools); | ||||
| 	free( & StringArenas); | ||||
|  | ||||
| 	free(& LexArena); | ||||
|  | ||||
| 	free(PreprocessorDefines); | ||||
| 	free(& PreprocessorDefines); | ||||
|  | ||||
| 	index = 0; | ||||
| 	left  = num(Global_AllocatorBuckets); | ||||
| @@ -373,7 +373,7 @@ void reset() | ||||
|  | ||||
| AllocatorInfo get_string_allocator( s32 str_length ) | ||||
| { | ||||
| 	Arena* last = & back(StringArenas); | ||||
| 	Arena* last = back(& StringArenas); | ||||
|  | ||||
| 	usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); | ||||
|  | ||||
| @@ -381,10 +381,10 @@ AllocatorInfo get_string_allocator( s32 str_length ) | ||||
| 	{ | ||||
| 		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | ||||
|  | ||||
| 		if ( ! append(StringArenas, new_arena ) ) | ||||
| 		if ( ! append( & StringArenas, new_arena ) ) | ||||
| 			GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); | ||||
|  | ||||
| 		last = & back(StringArenas); | ||||
| 		last = back(& StringArenas); | ||||
| 	} | ||||
|  | ||||
| 	return allocator_info(last); | ||||
| @@ -411,7 +411,7 @@ StringCached get_cached_string( StrC str ) | ||||
| // Used internally to retireve a Code object form the CodePool. | ||||
| Code make_code() | ||||
| { | ||||
| 	Pool* allocator = & back(CodePools); | ||||
| 	Pool* allocator = back( & CodePools); | ||||
| 	if ( allocator->FreeList == nullptr ) | ||||
| 	{ | ||||
| 		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) ); | ||||
| @@ -419,10 +419,10 @@ Code make_code() | ||||
| 		if ( code_pool.PhysicalStart == nullptr ) | ||||
| 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." ); | ||||
|  | ||||
| 		if ( ! append( CodePools, code_pool ) ) | ||||
| 		if ( ! append( & CodePools, code_pool ) ) | ||||
| 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." ); | ||||
|  | ||||
| 		allocator = & back(CodePools); | ||||
| 		allocator = back( & CodePools); | ||||
| 	} | ||||
|  | ||||
| 	Code result { rcast( AST*, alloc( allocator_info(allocator), sizeof(AST) )) }; | ||||
|   | ||||
| @@ -222,7 +222,7 @@ s32 lex_preprocessor_directive( | ||||
| 	, Token&           token ) | ||||
| { | ||||
| 	char const* hash = scanner; | ||||
| 	append(Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); | ||||
| 	append( & Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); | ||||
|  | ||||
| 	move_forward(); | ||||
| 	SkipWhitespace(); | ||||
| @@ -298,14 +298,14 @@ s32 lex_preprocessor_directive( | ||||
|  | ||||
| 		token.Length = token.Length + token.Text - hash; | ||||
| 		token.Text   = hash; | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| 	if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf ) | ||||
| 	{ | ||||
| 		token.Flags |= TF_Preprocess_Cond; | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		end_line(); | ||||
| 		return Lex_Continue; | ||||
| 	} | ||||
| @@ -314,7 +314,7 @@ s32 lex_preprocessor_directive( | ||||
| 		token.Flags |= TF_Preprocess_Cond; | ||||
| 	} | ||||
|  | ||||
| 	append(Tokens, token ); | ||||
| 	append( & Tokens, token ); | ||||
|  | ||||
| 	SkipWhitespace(); | ||||
|  | ||||
| @@ -338,7 +338,7 @@ s32 lex_preprocessor_directive( | ||||
| 			name.Length++; | ||||
| 		} | ||||
|  | ||||
| 		append(Tokens, name ); | ||||
| 		append( & Tokens, name ); | ||||
|  | ||||
| 		u64 key = crc32( name.Text, name.Length ); | ||||
| 		set<StrC>(defines, key, name ); | ||||
| @@ -384,7 +384,7 @@ s32 lex_preprocessor_directive( | ||||
| 			move_forward(); | ||||
| 		} | ||||
|  | ||||
| 		append(Tokens, preprocess_content ); | ||||
| 		append( & Tokens, preprocess_content ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| @@ -446,7 +446,7 @@ s32 lex_preprocessor_directive( | ||||
| 		preprocess_content.Length++; | ||||
| 	} | ||||
|  | ||||
| 	append(Tokens, preprocess_content ); | ||||
| 	append( & Tokens, preprocess_content ); | ||||
| 	return Lex_Continue; // Skip found token, its all handled here. | ||||
| } | ||||
|  | ||||
| @@ -461,7 +461,7 @@ void lex_found_token( StrC& content | ||||
| { | ||||
| 	if ( token.Type != TokType::Invalid ) | ||||
| 	{ | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -488,7 +488,7 @@ void lex_found_token( StrC& content | ||||
| 		} | ||||
|  | ||||
| 		token.Type = type; | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -498,7 +498,7 @@ void lex_found_token( StrC& content | ||||
| 	{ | ||||
| 		token.Type   = type; | ||||
| 		token.Flags |= TF_Specifier; | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -506,7 +506,7 @@ void lex_found_token( StrC& content | ||||
| 	if ( type != TokType::Invalid ) | ||||
| 	{ | ||||
| 		token.Type = type; | ||||
| 		append(Tokens, token ); | ||||
| 		append( & Tokens, token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -558,7 +558,7 @@ void lex_found_token( StrC& content | ||||
| 		token.Type = TokType::Identifier; | ||||
| 	} | ||||
|  | ||||
| 	append(Tokens, token ); | ||||
| 	append( & Tokens, token ); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -630,7 +630,7 @@ TokArray lex( StrC content ) | ||||
| 				token.Type = TokType::NewLine; | ||||
| 				token.Length++; | ||||
|  | ||||
| 				append(Tokens, token ); | ||||
| 				append( & Tokens, token ); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| @@ -1099,7 +1099,7 @@ TokArray lex( StrC content ) | ||||
| 							move_forward(); | ||||
| 							token.Length++; | ||||
| 						} | ||||
| 						append(Tokens, token ); | ||||
| 						append( & Tokens, token ); | ||||
| 						continue; | ||||
| 					} | ||||
| 					else if ( current == '*' ) | ||||
| @@ -1135,7 +1135,7 @@ TokArray lex( StrC content ) | ||||
| 							move_forward(); | ||||
| 							token.Length++; | ||||
| 						} | ||||
| 						append(Tokens, token ); | ||||
| 						append( & Tokens, token ); | ||||
| 						// end_line(); | ||||
| 						continue; | ||||
| 					} | ||||
|   | ||||
| @@ -52,7 +52,7 @@ struct ParseContext | ||||
|  | ||||
| 		sptr        length  = scope_start.Length; | ||||
| 		char const* current = scope_start.Text + length; | ||||
| 		while ( current <= back(Tokens.Arr).Text && *current != '\n' && length < 74 ) | ||||
| 		while ( current <= back( & Tokens.Arr)->Text && *current != '\n' && length < 74 ) | ||||
| 		{ | ||||
| 			current++; | ||||
| 			length++; | ||||
| @@ -745,7 +745,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | ||||
| 			} | ||||
| 			Token interface_tok = parse_identifier(); | ||||
|  | ||||
| 			append(interfaces, def_type( interface_tok ) ); | ||||
| 			append( & interfaces, def_type( interface_tok ) ); | ||||
| 			// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... | ||||
| 		} | ||||
| 	} | ||||
| @@ -777,7 +777,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | ||||
| 	if ( inline_cmt ) | ||||
| 		result->InlineCmt = inline_cmt; | ||||
|  | ||||
| 	free(interfaces); | ||||
| 	free(& interfaces); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -29,29 +29,29 @@ struct ArrayHeader; | ||||
|  | ||||
| usize array_grow_formula(ssize value); | ||||
|  | ||||
| template<class Type> Array<Type>  array_init(AllocatorInfo allocator); | ||||
| template<class Type> Array<Type>  array_init_reserve(AllocatorInfo allocator, ssize capacity); | ||||
| template<class Type> bool         append(Array<Type>& array, Array<Type> other); | ||||
| template<class Type> bool         append(Array<Type>& array, Type value); | ||||
| template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num); | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx); | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx); | ||||
| template<class Type> Type&        back(Array<Type>& array); | ||||
| template<class Type> void         clear(Array<Type>& array); | ||||
| template<class Type> bool         fill(Array<Type>& array, usize begin, usize end, Type value); | ||||
| template<class Type> void         free(Array<Type>& array); | ||||
| template<class Type> bool         grow(Array<Type>& array, usize min_capacity); | ||||
| template<class Type> usize        num(Array<Type>& array); | ||||
| template<class Type> void         pop(Array<Type>& array); | ||||
| template<class Type> void         remove_at(Array<Type>& array, usize idx); | ||||
| template<class Type> bool         reserve(Array<Type>& array, usize new_capacity); | ||||
| template<class Type> bool         resize(Array<Type>& array, usize num); | ||||
| template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity); | ||||
| template<class Type> ArrayHeader* get_header(Array<Type>& array); | ||||
| template<class Type> Array(Type)  array_init        (AllocatorInfo allocator); | ||||
| template<class Type> Array(Type)  array_init_reserve(AllocatorInfo allocator, ssize capacity); | ||||
| template<class Type> bool         append            (Array(Type)* array, Array(Type) other); | ||||
| template<class Type> bool         append            (Array(Type)* array, Type value); | ||||
| template<class Type> bool         append            (Array(Type)* array, Type* items, usize item_num); | ||||
| template<class Type> bool         append_at         (Array(Type)* array, Type item, usize idx); | ||||
| template<class Type> bool         append_at         (Array(Type)* array, Type* items, usize item_num, usize idx); | ||||
| template<class Type> Type*        back              (Array(Type)  array); | ||||
| template<class Type> void         clear             (Array(Type)  array); | ||||
| template<class Type> bool         fill              (Array(Type)  array, usize begin, usize end, Type value); | ||||
| template<class Type> void         free              (Array(Type)* array); | ||||
| template<class Type> bool         grow              (Array(Type)* array, usize min_capacity); | ||||
| template<class Type> usize        num               (Array(Type)  array); | ||||
| template<class Type> void         pop               (Array(Type)  array); | ||||
| template<class Type> void         remove_at         (Array(Type)  array, usize idx); | ||||
| template<class Type> bool         reserve           (Array(Type)* array, usize new_capacity); | ||||
| template<class Type> bool         resize            (Array(Type)* array, usize num); | ||||
| template<class Type> bool         set_capacity      (Array(Type)* array, usize new_capacity); | ||||
| template<class Type> ArrayHeader* get_header        (Array(Type)  array); | ||||
|  | ||||
| template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | ||||
| template<class Type> forceinline Type* end(Array<Type>& array)               { return array + get_header(array)->Num; } | ||||
| template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; } | ||||
| // template<class Type> forceinline Type* begin(Array<Type> array)             { return array;      } | ||||
| // template<class Type> forceinline Type* end(Array<Type> array)               { return array + get_header(array)->Num; } | ||||
| // template<class Type> forceinline Type* next(Array<Type> array, Type* entry) { return entry + 1; } | ||||
|  | ||||
| struct ArrayHeader { | ||||
| 	AllocatorInfo Allocator; | ||||
| @@ -70,32 +70,52 @@ struct Array | ||||
| 	forceinline static Array  init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); } | ||||
| 	forceinline static usize  grow_formula(ssize value)                             { return GEN_NS array_grow_formula<Type>(value); } | ||||
|  | ||||
| 	forceinline bool         append(Array other)                               { return GEN_NS append<Type>(*this, other); } | ||||
| 	forceinline bool         append(Type value)                                { return GEN_NS append<Type>(*this, value); } | ||||
| 	forceinline bool         append(Type* items, usize item_num)               { return GEN_NS append<Type>(*this, items, item_num); } | ||||
| 	forceinline bool         append_at(Type item, usize idx)                   { return GEN_NS append_at<Type>(*this, item, idx); } | ||||
| 	forceinline bool         append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(*this, items, item_num, idx); } | ||||
| 	forceinline Type&        back()                                            { return GEN_NS back<Type>(*this); } | ||||
| 	forceinline bool         append(Array other)                               { return GEN_NS append<Type>(this, other); } | ||||
| 	forceinline bool         append(Type value)                                { return GEN_NS append<Type>(this, value); } | ||||
| 	forceinline bool         append(Type* items, usize item_num)               { return GEN_NS append<Type>(this, items, item_num); } | ||||
| 	forceinline bool         append_at(Type item, usize idx)                   { return GEN_NS append_at<Type>(this, item, idx); } | ||||
| 	forceinline bool         append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(this, items, item_num, idx); } | ||||
| 	forceinline Type*        back()                                            { return GEN_NS back<Type>(* this); } | ||||
| 	forceinline void         clear()                                           { GEN_NS clear<Type>(* this); } | ||||
| 	forceinline bool         fill(usize begin, usize end, Type value)          { return GEN_NS fill<Type>(* this, begin, end, value); } | ||||
| 	forceinline void         free()                                            { GEN_NS free<Type>(*this); } | ||||
| 	forceinline void         free()                                            { GEN_NS free<Type>(this); } | ||||
| 	forceinline ArrayHeader* get_header()                                      { return GEN_NS get_header<Type>(* this); } | ||||
| 	forceinline bool         grow(usize min_capacity)                          { return GEN_NS grow<Type>(*this, min_capacity); } | ||||
| 	forceinline bool         grow(usize min_capacity)                          { return GEN_NS grow<Type>(this, min_capacity); } | ||||
| 	forceinline usize        num()                                             { return GEN_NS num<Type>(*this); } | ||||
| 	forceinline void         pop()                                             { GEN_NS pop<Type>(* this); } | ||||
| 	forceinline void         remove_at(usize idx)                              { GEN_NS remove_at<Type>(* this, idx); } | ||||
| 	forceinline bool         reserve(usize new_capacity)                       { return GEN_NS reserve<Type>(*this, new_capacity); } | ||||
| 	forceinline bool         resize(usize num)                                 { return GEN_NS resize<Type>(*this, num); } | ||||
| 	forceinline bool         set_capacity(usize new_capacity)                  { return GEN_NS set_capacity<Type>(*this, new_capacity); } | ||||
| 	forceinline bool         reserve(usize new_capacity)                       { return GEN_NS reserve<Type>(this, new_capacity); } | ||||
| 	forceinline bool         resize(usize num)                                 { return GEN_NS resize<Type>(this, num); } | ||||
| 	forceinline bool         set_capacity(usize new_capacity)                  { return GEN_NS set_capacity<Type>(this, new_capacity); } | ||||
| #pragma endregion Member Mapping | ||||
|  | ||||
| 	forceinline operator Type*()             { return Data; } | ||||
| 	forceinline operator Type const*() const { return Data; } | ||||
| 	forceinline Type* begin()                { return Data; } | ||||
| 	forceinline Type* end()                  { return Data + get_header()->Num; } | ||||
| #pragma endregion Member Mapping | ||||
|  | ||||
| 	forceinline Type&       operator[](ssize index)       { return Data[index]; } | ||||
| 	forceinline Type const& operator[](ssize index) const { return Data[index]; } | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if GEN_SUPPORT_CPP_REFERENCES | ||||
| template<class Type> bool         append(Array<Type>& array, Array<Type> other)                         { return GEN_NS append( & array, other ); } | ||||
| template<class Type> bool         append(Array<Type>& array, Type value)                                { return GEN_NS append( & array, value ); } | ||||
| template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num)               { return GEN_NS append( & array, items, item_num ); } | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx)                   { return GEN_NS append_at( & array, item, idx ); } | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return GEN_NS append_at( & array, items, item_num, idx ); } | ||||
| template<class Type> void         free(Array<Type>& array)                                              { return GEN_NS free( & array ); } | ||||
| template<class Type> bool         grow(Array<Type>& array, usize min_capacity)                          { return GEN_NS grow( & array, min_capacity); } | ||||
| template<class Type> bool         reserve(Array<Type>& array, usize new_capacity)                       { return GEN_NS reserve( & array, new_capacity); } | ||||
| template<class Type> bool         resize(Array<Type>& array, usize num)                                 { return GEN_NS resize( & array, num); } | ||||
| template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity)                  { return GEN_NS set_capacity( & array, new_capacity); } | ||||
|  | ||||
| template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | ||||
| template<class Type> forceinline Type* end(Array<Type>& array)               { return array + get_header(array)->Num; } | ||||
| template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; } | ||||
| #endif | ||||
|  | ||||
| template<class Type> inline | ||||
| Array<Type> array_init(AllocatorInfo allocator) { | ||||
| 	return array_init_reserve<Type>(allocator, array_grow_formula(0)); | ||||
| @@ -121,30 +141,30 @@ usize array_grow_formula(ssize value) { | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool append(Array<Type>& array, Array<Type> other) { | ||||
| bool append(Array<Type>* array, Array<Type> other) { | ||||
| 	return append(array, other, num(other)); | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool append(Array<Type>& array, Type value) | ||||
| bool append(Array<Type>* array, Type value) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
|  | ||||
| 	if (header->Num == header->Capacity) | ||||
| 	{ | ||||
| 		if (!grow(array, header->Capacity)) | ||||
| 			return false; | ||||
| 		header = get_header(array); | ||||
| 		header = get_header(* array); | ||||
| 	} | ||||
|  | ||||
| 	array[header->Num] = value; | ||||
| 	(*array)[ header->Num] = value; | ||||
| 	header->Num++; | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool append(Array<Type>& array, Type* items, usize item_num) | ||||
| bool append(Array<Type>* array, Type* items, usize item_num) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
|  | ||||
| @@ -162,34 +182,37 @@ bool append(Array<Type>& array, Type* items, usize item_num) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool append_at(Array<Type>& array, Type item, usize idx) | ||||
| bool append_at(Array<Type>* array, Type item, usize idx) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
|  | ||||
| 	if (idx >= header->Num) | ||||
| 	 	idx = header->Num - 1; | ||||
| 	ssize slot = idx; | ||||
| 	if (slot >= header->Num) | ||||
| 	 	slot = header->Num - 1; | ||||
|  | ||||
| 	if (idx < 0) | ||||
|  		idx = 0; | ||||
| 	if (slot < 0) | ||||
|  		slot = 0; | ||||
|  | ||||
| 	if (header->Capacity < header->Num + 1) | ||||
| 	{ | ||||
| 		if ( ! grow(array, header->Capacity + 1)) | ||||
| 			return false; | ||||
|  | ||||
| 		header = get_header(array); | ||||
| 		header = get_header(* array); | ||||
| 	} | ||||
|  | ||||
| 	Type* target = array + idx; | ||||
| 	Type* target = array->Data + slot; | ||||
|  | ||||
| 	mem_move(target + 1, target, (header->Num - idx) * sizeof(Type)); | ||||
| 	mem_move(target + 1, target, (header->Num - slot) * sizeof(Type)); | ||||
| 	header->Num++; | ||||
|  | ||||
| 	header = get_header(* array); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) | ||||
| bool append_at(Array<Type>* array, Type* items, usize item_num, usize idx) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
|  | ||||
| @@ -217,19 +240,25 @@ bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| Type& back(Array<Type>& array) { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	return array[header->Num - 1]; | ||||
| Type* back(Array<Type>* array) | ||||
| { | ||||
| 	GEN_ASSERT(array != nullptr); | ||||
|  | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
| 	if (header->Num <= 0) | ||||
| 		return nullptr; | ||||
|  | ||||
| 	return & (*array)[header->Num - 1]; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| void clear(Array<Type>& array) { | ||||
| void clear(Array<Type> array) { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	header->Num = 0; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool fill(Array<Type>& array, usize begin, usize end, Type value) | ||||
| bool fill(Array<Type> array, usize begin, usize end, Type value) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
|  | ||||
| @@ -245,24 +274,24 @@ bool fill(Array<Type>& array, usize begin, usize end, Type value) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| void free(Array<Type>& array) { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| void free(Array<Type>* array) { | ||||
| 	GEN_ASSERT(array != nullptr); | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
| 	GEN_NS free(header->Allocator, header); | ||||
| 	Type*& Data = rcast(Type*&, array); | ||||
| 	Data = nullptr; | ||||
| 	array->Data = nullptr; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| ArrayHeader* get_header(Array<Type>& array) { | ||||
| template<class Type> forceinline | ||||
| ArrayHeader* get_header(Array<Type> array) { | ||||
|     Type* Data = array; | ||||
|  | ||||
| 	using NonConstType = TRemoveConst<Type>; | ||||
| 	Type* Data = array; // This should do nothing in C but in C++ gets member Data struct. | ||||
|     return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool grow(Array<Type>& array, usize min_capacity) | ||||
| bool grow(Array<Type>* array, usize min_capacity) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	ArrayHeader* header       = get_header(* array); | ||||
| 	usize        new_capacity = array_grow_formula(header->Capacity); | ||||
|  | ||||
| 	if (new_capacity < min_capacity) | ||||
| @@ -272,19 +301,19 @@ bool grow(Array<Type>& array, usize min_capacity) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| usize num(Array<Type>& array) { | ||||
| usize num(Array<Type> array) { | ||||
| 	return get_header(array)->Num; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| void pop(Array<Type>& array) { | ||||
| void pop(Array<Type> array) { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	GEN_ASSERT(header->Num > 0); | ||||
| 	header->Num--; | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| void remove_at(Array<Type>& array, usize idx) | ||||
| void remove_at(Array<Type> array, usize idx) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	GEN_ASSERT(idx < header->Num); | ||||
| @@ -294,7 +323,7 @@ void remove_at(Array<Type>& array, usize idx) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool reserve(Array<Type>& array, usize new_capacity) | ||||
| bool reserve(Array<Type>* array, usize new_capacity) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
|  | ||||
| @@ -305,14 +334,14 @@ bool reserve(Array<Type>& array, usize new_capacity) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool resize(Array<Type>& array, usize num) | ||||
| bool resize(Array<Type>* array, usize num) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
|  | ||||
| 	if (header->Capacity < num) { | ||||
| 		if (! grow( array, num)) | ||||
| 			return false; | ||||
| 		header = get_header(array); | ||||
| 		header = get_header(* array); | ||||
| 	} | ||||
|  | ||||
| 	header->Num = num; | ||||
| @@ -320,9 +349,9 @@ bool resize(Array<Type>& array, usize num) | ||||
| } | ||||
|  | ||||
| template<class Type> inline | ||||
| bool set_capacity(Array<Type>& array, usize new_capacity) | ||||
| bool set_capacity(Array<Type>* array, usize new_capacity) | ||||
| { | ||||
| 	ArrayHeader* header = get_header(array); | ||||
| 	ArrayHeader* header = get_header(* array); | ||||
|  | ||||
| 	if (new_capacity == header->Capacity) | ||||
| 	return true; | ||||
| @@ -345,32 +374,10 @@ bool set_capacity(Array<Type>& array, usize new_capacity) | ||||
|  | ||||
| 	GEN_NS free(header->Allocator, header); | ||||
|  | ||||
| 	Type*& Data = rcast(Type*&, array); | ||||
| 	Data = rcast(Type*, new_header + 1); | ||||
| 	array->Data = rcast(Type*, new_header + 1); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| #define array_init(Type, allocator)                            array_init<Type>(allocator) | ||||
| #define array_init(Type, allocator)                            array_init<Type>(allocator) | ||||
| #define array_init_reserve(Type, allocator, capacity)          array_init_reserve<Type>(allocator, capacity) | ||||
| #define array_append(Type, array, other)                       append<Type>(array, other) | ||||
| #define array_append_value(Type, array, value)                 append<Type>(array, value) | ||||
| #define array_append_items(Type, array, items, item_num)       append<Type>(array, items, item_num) | ||||
| #define array_append_at(Type, array, item, idx)                append_at<Type>(array, item, idx) | ||||
| #define array_append_items_at(Type, array, items, num, idx)    append_at<Type>(array, items, num, idx) | ||||
| #define array_back(Type, array)                                back<Type>(array) | ||||
| #define array_clear(Type, array)                               clear<Type>(array) | ||||
| #define array_fill(Type, array, begin, end, value)             fill<Type>(array, begin, end, value) | ||||
| #define array_free(Type, array)                                free<Type>(array) | ||||
| #define array_grow(Type, array, min_capacity)                  grow<Type>(array, min_capacity) | ||||
| #define array_num(Type, array)                                 num<Type>(array) | ||||
| #define array_pop(Type, array)                                 pop<Type>(array) | ||||
| #define array_remove_at(Type, array, idx)                      remove_at<Type>(array, idx) | ||||
| #define array_reserve(Type, array, new_capacity)               reserve<Type>(array, new_capacity) | ||||
| #define array_resize(Type, array, num)                         resize<Type>(array, num) | ||||
| #define array_set_capacity(Type, array, new_capacity)          set_capacity<Type>(array, new_capacity) | ||||
| #define array_get_header(array)                                get_header(array) | ||||
|  | ||||
| #pragma endregion Array | ||||
|  | ||||
| // TODO(Ed) : This thing needs ALOT of work. | ||||
| @@ -453,7 +460,7 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num) | ||||
|  | ||||
| 	result.Hashes = array_init_reserve<ssize>(allocator, num); | ||||
| 	get_header(result.Hashes)->Num = num; | ||||
| 	resize(result.Hashes, num); | ||||
| 	resize(& result.Hashes, num); | ||||
| 	fill<ssize>(result.Hashes, 0, num, -1); | ||||
|  | ||||
| 	result.Entries = array_init_reserve<HashTableEntry<Type>>(allocator, num); | ||||
| @@ -469,8 +476,8 @@ void clear(HashTable<Type>& table) { | ||||
| template<typename Type> inline | ||||
| void destroy(HashTable<Type>& table) { | ||||
| 	if (table.Hashes && get_header(table.Hashes)->Capacity) { | ||||
| 		free(table.Hashes); | ||||
| 		free(table.Entries); | ||||
| 		free(& table.Hashes); | ||||
| 		free(& table.Entries); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -621,7 +628,7 @@ ssize add_entry(HashTable<Type>& table, u64 key) { | ||||
| 	HashTableEntry<Type> entry = { key, -1 }; | ||||
|  | ||||
| 	idx = num(table.Entries); | ||||
| 	append(table.Entries, entry); | ||||
| 	append( & table.Entries, entry); | ||||
| 	return idx; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -612,7 +612,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
|  | ||||
| 		if ( get_header(arr)->Capacity < usize(new_cap) ) | ||||
| 		{ | ||||
| 			if ( ! grow( arr, ( s64 )( new_cap ) ) ) | ||||
| 			if ( ! grow( & arr, ( s64 )( new_cap ) ) ) | ||||
| 				return false; | ||||
| 			d->buf = arr; | ||||
| 		} | ||||
| @@ -647,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close ) | ||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||
| 	{ | ||||
| 		Array<u8> arr = { d->buf }; | ||||
| 		free(arr); | ||||
| 		free(& arr); | ||||
| 	} | ||||
|  | ||||
| 	free( allocator, d ); | ||||
|   | ||||
| @@ -41,7 +41,7 @@ u8 adt_destroy_branch( ADT_Node* node ) | ||||
| 			adt_destroy_branch( node->nodes + i ); | ||||
| 		} | ||||
|  | ||||
| 		free(node->nodes); | ||||
| 		free(& node->nodes); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| @@ -287,10 +287,11 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ) | ||||
|  | ||||
| 	ADT_Node o = { 0 }; | ||||
| 	o.parent   = parent; | ||||
| 	if ( ! append_at( parent->nodes, o, index ) ) | ||||
| 	if ( ! append_at( & parent->nodes, o, index ) ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	return parent->nodes + index; | ||||
| 	ADT_Node* node = & parent->nodes[index]; | ||||
| 	return node; | ||||
| } | ||||
|  | ||||
| ADT_Node* adt_alloc( ADT_Node* parent ) | ||||
| @@ -402,7 +403,9 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name ) | ||||
| 	ADT_Node* o = adt_alloc( parent ); | ||||
| 	if ( ! o ) | ||||
| 		return NULL; | ||||
| 	if ( adt_set_arr( o, name, get_header(parent->nodes)->Allocator ) ) | ||||
|  | ||||
| 	ArrayHeader* node_header = get_header(parent->nodes); | ||||
| 	if ( adt_set_arr( o, name, node_header->Allocator ) ) | ||||
| 	{ | ||||
| 		adt_remove_node( o ); | ||||
| 		return NULL; | ||||
| @@ -951,7 +954,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 			adt_append_arr( root, NULL ); | ||||
| 		} | ||||
|  | ||||
| 		append(root->nodes[ columnIndex ].nodes, rowItem ); | ||||
| 		append( & root->nodes[ columnIndex ].nodes, rowItem ); | ||||
|  | ||||
| 		if ( delimiter == delim ) | ||||
| 		{ | ||||
|   | ||||
| @@ -83,7 +83,7 @@ struct ADT_Node | ||||
| 	union | ||||
| 	{ | ||||
| 		char const*     string; | ||||
| 		Array<ADT_Node> nodes;    ///< zpl_array | ||||
| 		Array(ADT_Node) nodes;    ///< zpl_array | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
|   | ||||
| @@ -23,9 +23,10 @@ CodeBody gen_ecode( char const* path ) | ||||
| 	String enum_entries   = string_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
|  | ||||
| 	for ( ADT_Node node : enum_strs ) | ||||
| 	for ( ADT_Node& node : enum_strs ) | ||||
| 	{ | ||||
| 		char const* code = node.string; | ||||
|  | ||||
| 		append_fmt( enum_entries, "%s,\n", code ); | ||||
| 		append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user