#if GEN_TIME #define GEN_FEATURE_PARSING #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_EXPOSE_BACKEND #define GEN_BENCHMARK #include "gen.hpp" using namespace gen; Code gen_SOA( CodeStruct struct_def, s32 num_entries = 0 ) { StringCached name = get_cached_string( token_fmt( "name", (StrC)struct_def->Name, stringize( SOA_ ) )); Code soa_entry = { struct_def.duplicate() }; soa_entry->Name = get_cached_string( name(Entry) ); constexpr s32 Num_Vars_Cap = 128; local_persist Code var_memory[Num_Vars_Cap]; local_persist Arena var_arena; do_once_start var_arena = Arena::init_from_memory( var_memory, kilobytes(Num_Vars_Cap) ); do_once_end Array vars = Array::init( var_arena );; CodeStruct soa = def_struct( name, def_struct_body( args( soa_entry ) )); { for ( Code struct_mem : struct_def->Body ) { if ( struct_mem->Type == ECode::Variable ) { CodeType var_type = struct_mem.cast()->ValueType; StrC num_entries_str = to_StrC( str_fmt_buf( "%d", num_entries ) ); CodeVar entry_arr = { nullptr }; if ( ! num_entries) { entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name, stringize( Array<> ; ) )); } else { entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name, "num", num_entries_str, stringize( []; ) )); } vars.append( entry_arr ); soa->Body.append( entry_arr ); } } } CodeFn make; { make = parse_function( token_fmt("SOA_Type", (StrC)name, stringize( static make( AllocatorInfo allocator ) { soa = {}; } ) )); if ( ! num_entries ) { for ( CodeVar member : vars ) { Code arr_init = def_execution( token_fmt( "var_name", (StrC)member->Name, "var_type", (StrC)member->ValueType->Name, stringize( soa. = ::init( allocator ); ) )); make->Body.append( arr_init ); } } make->Body.append( def_execution( code( return soa; ) )); } CodeFn get; { get = parse_function( code( Entry get( s32 idx ) { } )); String content = String::make( GlobalAllocator, "return\n{\n" ); for ( CodeVar member : vars ) { content.append_fmt( token_fmt( "var_name", (StrC)member->Name, "[idx]," )); } content.append( "};" ); CodeExec ret = def_execution( content ); get->Body.append( ret ); } soa->Body.append( make ); soa->Body.append( get ); soa->Body.raw()->validate_body(); vars.free(); return soa; } void check_SOA() { gen::init(); Builder soa_test; soa_test.open( "SOA.gen.hpp" ); soa_test.print( parse_using( code( using u16 = unsigned short; ))); soa_test.print( def_include( txt_StrC("gen.hpp"))); soa_test.print( def_using_namespace( name(gen) ) ); soa_test.print( gen_SOA( parse_struct( code( struct TestStruct { u8 A; u16 B; u32 C; u64 D; }; )) )); soa_test.write(); gen::deinit(); } #endif