2023-04-02 09:35:14 -07:00
|
|
|
/*
|
|
|
|
This is based of the array container implementation in the zpl.h library.
|
2023-04-03 23:04:19 -07:00
|
|
|
|
|
|
|
This specific header has two implementations of the array generator;
|
|
|
|
One showing use of the gen api directly, the other using it's DSL.
|
2023-04-02 09:35:14 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "Bloat.hpp"
|
|
|
|
#include "gen.hpp"
|
|
|
|
|
|
|
|
#ifdef gen_time
|
|
|
|
Code gen__array_base()
|
|
|
|
{
|
2023-04-03 00:55:28 -07:00
|
|
|
#ifndef GEN_DEFINE_DSL
|
2023-04-03 23:04:19 -07:00
|
|
|
using namespace gen;
|
|
|
|
|
|
|
|
Code t_allocator = def_type( txt(allocator) );
|
|
|
|
|
2023-04-02 09:35:14 -07:00
|
|
|
Code header;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code num = def_variable( t_uw, "Num" );
|
|
|
|
Code capacity = def_variable( t_uw, "Capacity" );
|
|
|
|
Code allocator_var = def_variable( t_allocator, "Allocator" );
|
2023-04-02 09:35:14 -07:00
|
|
|
Code header_body = def_struct_body( 3, num, capacity, allocator_var );
|
|
|
|
|
|
|
|
header = def_struct( "ArrayHeader", header_body );
|
|
|
|
}
|
|
|
|
|
|
|
|
Code grow_formula;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code spec = def_specifiers(1, ESpecifier::Inline);
|
|
|
|
Code params = def_params(1, t_uw, "value" );
|
|
|
|
Code body = untyped_str( txt( return 2 * value * 8; ) );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
grow_formula = def_proc( "grow_formula", spec, params, t_sw, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = def_struct_body(2, header, grow_formula);
|
2023-04-03 00:55:28 -07:00
|
|
|
Code ArrayBase = def_struct( "ArrayBase", body );
|
|
|
|
|
|
|
|
#else
|
2023-04-03 23:04:19 -07:00
|
|
|
typename( allocator, allocator );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code Header;
|
|
|
|
{
|
|
|
|
variable( uw, Num, );
|
|
|
|
variable( uw, Capacity );
|
|
|
|
variable( allocator, Allocator );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = struct_body( Num, Capacity, Allocator );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
struct( Header, __, __, body );
|
|
|
|
}
|
|
|
|
|
|
|
|
Code proc( grow_formula, spec_inline, t_uw, params( t_uw, "value" ),
|
|
|
|
untyped( return 2 * value * 8 )
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code struct( ArrayBase, __, __, struct_body( Header, grow_formula ) );
|
2023-04-03 00:55:28 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return ArrayBase;
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#define gen_array( Type_ ) gen__array( #Type_, sizeof(Type_), a_base )
|
|
|
|
Code gen__array( char const* type_str, s32 type_size, Code parent )
|
|
|
|
{
|
2023-04-03 00:55:28 -07:00
|
|
|
#ifndef GEN_DEFINE_DSL
|
2023-04-02 09:35:14 -07:00
|
|
|
// Make these global consts to be accessed anywhere...
|
|
|
|
Code t_allocator = def_type( txt(allocator) );
|
|
|
|
|
2023-04-03 00:55:28 -07:00
|
|
|
Code v_nullptr = untyped_str( "nullptr" );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code spec_ct = def_specifiers(1, ESpecifier::Constexpr );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
|
|
|
Code type = def_type( type_str );
|
2023-04-03 00:55:28 -07:00
|
|
|
Code ptr_type = def_type( bprintf( "%s*", type_str ) );
|
|
|
|
Code ref_type = def_type( bprintf( "%s&", type_str ) );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
|
|
|
// From ArrayBase
|
|
|
|
Code t_header = def_type( "Header" );
|
|
|
|
Code ptr_header = def_type( "Header*" );
|
|
|
|
Code ref_header = def_type( "Header&" );
|
|
|
|
|
|
|
|
Code array_def;
|
|
|
|
{
|
2023-04-03 00:55:28 -07:00
|
|
|
Code using_type = def_using( "Type", type );
|
2023-04-03 23:04:19 -07:00
|
|
|
Code data = def_variable( ptr_type, "Data" );
|
|
|
|
|
|
|
|
// This getter is used often in all the member procedures
|
|
|
|
Code header = def_variable( ref_header, "header", untyped_str( txt( get_header() )));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
|
|
|
Code init;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code params = def_params( 1, t_allocator, "mem_handler" );
|
|
|
|
Code body = untyped_str( txt( return init_reserve( mem_handler, grow_formula(0) ); ) );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
init = def_proc( "init", UnusedCode, params, t_bool, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code init_reserve;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code params = def_params( 2, t_allocator, "mem_handler", t_sw, "capacity" );
|
2023-04-02 09:35:14 -07:00
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code header_value = untyped_str( txt(
|
|
|
|
rcast( Header*, alloc( mem_handler, sizeof( Header ) + sizeof(Type) + capacity ))
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code header = def_variable( ptr_header, "header", header_value );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code null_check = untyped_str( txt(
|
|
|
|
if (header == nullptr)
|
|
|
|
return false;
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code header_init = untyped_str( txt(
|
|
|
|
header->Num = 0;
|
|
|
|
header->Capacity = capacity;
|
|
|
|
header->Allocator = mem_handler;
|
|
|
|
));
|
|
|
|
|
|
|
|
Code assign_data = untyped_fmt(
|
2023-04-03 00:55:28 -07:00
|
|
|
"Data = rcast( %s, header + 1 );", ptr_type
|
2023-04-02 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code ret_true = untyped_str( txt(
|
|
|
|
return true
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 5
|
2023-04-02 09:35:14 -07:00
|
|
|
, header
|
|
|
|
, null_check
|
|
|
|
, header_init
|
|
|
|
, assign_data
|
|
|
|
, ret_true
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
init_reserve = def_proc( "init_reserve", UnusedCode, params, t_bool, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code free;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = untyped_str( txt(
|
|
|
|
Header& header = get_header();
|
|
|
|
::free( header.Allocator, & get_header() );
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
free = def_proc( "free", UnusedCode, UnusedCode, t_void, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code append = make_proc( "append" );
|
2023-04-02 09:35:14 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
append->add( def_params( 1, type, "value") );
|
|
|
|
|
|
|
|
Code
|
|
|
|
body = append.body();
|
|
|
|
body->add(
|
|
|
|
untyped_str( txt(
|
|
|
|
if ( header.Capacity < header.Num + 1 )
|
|
|
|
if ( ! grow(0) )
|
|
|
|
return false;
|
|
|
|
))
|
|
|
|
);
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body->add( untyped_str( txt(
|
|
|
|
Data[ header.Num ] = value;
|
|
|
|
header.Num++;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
)));
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code back;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = untyped_str( txt(
|
|
|
|
Header& header = get_header();
|
|
|
|
|
|
|
|
return data[ header.Num - 1 ];
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
back = def_proc( "back", UnusedCode, UnusedCode, type, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code clear;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = untyped_str( txt( get_header().Num = 0; ));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
clear = def_proc( "clear", UnusedCode, UnusedCode, t_void, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code fill;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code params = def_params( 3, t_uw, "begin", t_uw, "end", type, "value" );
|
2023-04-02 09:35:14 -07:00
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code check = untyped_str( txt(
|
|
|
|
if ( begin < 0 || end >= header.Num )
|
|
|
|
fatal( "Range out of bounds" );
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code iter = untyped_str( txt(
|
|
|
|
for ( sw index = begin; index < end; index++ )
|
|
|
|
Data[index] = vallue;
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 3, header, check, iter );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
fill = def_proc( "fill", UnusedCode, params, t_void, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code get_header;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = untyped_str( txt( return pcast( Header, Data - 1 ); ));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
get_header = def_proc( "get_header", spec_inline, UnusedCode, ref_header, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code grow;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code param = def_params( 1, t_uw, "min_capacity" );
|
2023-04-02 09:35:14 -07:00
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code new_capacity = def_variable( t_uw, "new_capacity", untyped_str("grow_formula( header.Capacity )") );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code check_n_set = untyped_str( txt(
|
|
|
|
if ( new_capacity < min_capacity )
|
|
|
|
new_capacity = min_capacity;
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 00:55:28 -07:00
|
|
|
Code ret = untyped_str( "return set_capacity( new_capacity );" );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 4, header, new_capacity, check_n_set, ret );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
grow = def_proc( "grow", UnusedCode, param, t_bool, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code pop;
|
|
|
|
{
|
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 00:55:28 -07:00
|
|
|
Code assertion = untyped_str( "assert( header.Num > 0 );" );
|
|
|
|
Code decrement = untyped_str( "header.Num--; " );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 3, header, assertion, decrement );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
pop = def_proc( "pop", UnusedCode, UnusedCode, t_void, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code reserve;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code params = def_params( 1, t_uw, "new_capacity" );
|
2023-04-02 09:35:14 -07:00
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 00:55:28 -07:00
|
|
|
Code check_n_set = untyped_str(
|
|
|
|
"if ( header.Capacity < new_capacity )"
|
|
|
|
"\n" "return set_capacity( new_capacity );"
|
2023-04-02 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 00:55:28 -07:00
|
|
|
Code ret = untyped_str( "\t" "return true" );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 3, header, check_n_set, ret );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
reserve = def_proc( "reserve", UnusedCode, params, t_bool, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Code resize;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code param = def_params( 1, t_uw, "new_num" );
|
2023-04-02 09:35:14 -07:00
|
|
|
|
|
|
|
Code body;
|
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code check_n_grow = untyped_str( txt(
|
|
|
|
if ( header.Capacity < new_num )
|
|
|
|
if ( ! grow( new_num) )
|
|
|
|
return false;
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 00:55:28 -07:00
|
|
|
Code set_n_ret = untyped_str(
|
|
|
|
"header.Count = new_num;"
|
|
|
|
"\n""return true;"
|
2023-04-02 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = def_proc_body( 3, header, check_n_grow, set_n_ret );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
resize = def_proc( "resize", UnusedCode, param, t_bool, body );
|
2023-04-02 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code set_capacity = parse_proc( txt_with_length(
|
|
|
|
bool set_capacity( new_capacity )
|
2023-04-02 09:35:14 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Header& header = get_header();
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( capacity == header.Capacity )
|
|
|
|
return true;
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( capacity < header.Num )
|
|
|
|
header.Num = capacity;
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
uw size = sizeof(Header) + sizeof(Type) * capacity;
|
|
|
|
Header* new_header = rcast( Header* alloc( header.Allocator, size ));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( new_header == nullptr )
|
|
|
|
return false;
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
memmove( new_header, & header, sizeof( Header ) + sizeof(Type) * header.Num );
|
|
|
|
|
|
|
|
new_header->Allocator = header.Allocator;
|
|
|
|
new_header->Num = header.Num;
|
|
|
|
new_header->Capacity = header.Capacity;
|
|
|
|
|
|
|
|
free( header );
|
|
|
|
|
|
|
|
*Data = new_header + 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
));
|
2023-04-02 09:35:14 -07:00
|
|
|
|
2023-04-03 00:55:28 -07:00
|
|
|
string name = bprintf( "Array_%s", type_str );
|
|
|
|
|
2023-04-02 09:35:14 -07:00
|
|
|
Code body = def_struct_body( 15
|
|
|
|
, using_type
|
|
|
|
, data
|
|
|
|
|
|
|
|
, init
|
|
|
|
, init_reserve
|
|
|
|
, append
|
|
|
|
, back
|
|
|
|
, clear
|
|
|
|
, fill
|
|
|
|
, free
|
|
|
|
, get_header
|
|
|
|
, grow
|
|
|
|
, pop
|
|
|
|
, reserve
|
|
|
|
, resize
|
|
|
|
, set_capacity
|
|
|
|
);
|
|
|
|
|
|
|
|
array_def = def_struct( name, body, parent );
|
|
|
|
}
|
2023-04-03 00:55:28 -07:00
|
|
|
#else
|
2023-04-03 23:04:19 -07:00
|
|
|
typename( allocator, allocator );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
untyped( v_nullptr, nullptr );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
typename( elem_type, type_str );
|
|
|
|
typename_fmt( ptr_type, "%s*", type_str );
|
|
|
|
typename_fmt( ref_type, "%&", type_str );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
|
|
|
|
|
|
|
// From ArrayBase
|
2023-04-03 23:04:19 -07:00
|
|
|
typename( header, Header );
|
|
|
|
typename( ptr_header, Header* );
|
|
|
|
typename( ref_header, Header& );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code array_def;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
using_type( Type, elem_type );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
variable( ptr_type, Data );
|
|
|
|
variable( ref_header, header, untyped_str("get_header()") );
|
|
|
|
|
|
|
|
Code init;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = proc_body( untyped(
|
|
|
|
return init_reserve( mem_handler, grow_formula(0) );
|
|
|
|
));
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( init, __, t_bool, params( t_allocator, "mem_handler" ), body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
make( proc, init_reserve, __, params( t_ref_type, "mem_handler" ), t_bool);
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code
|
|
|
|
body = init_reserve.body();
|
|
|
|
body->add_var( ptr_header, header, untyped(
|
|
|
|
value_str( rcast( Header*, alloc( mem_handler, sizeof(Header) + sizeof(Type) + capacity)) )
|
|
|
|
) );
|
|
|
|
|
|
|
|
body->add_untyped(
|
|
|
|
if (header == nullptr)
|
|
|
|
return false;
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body->add_untyped(
|
|
|
|
header->Num = 0;
|
|
|
|
header->Capacity = capacity;
|
|
|
|
header->Allocator = mem_handler;
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body->add_untyped(
|
|
|
|
Data = rcast( Type*, header + 1 );
|
|
|
|
return true;
|
|
|
|
);
|
|
|
|
}
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code free;
|
|
|
|
{
|
|
|
|
proc( free, __, t_void, __, untyped(
|
|
|
|
Header& header = get_header();
|
|
|
|
|
|
|
|
free( header.Allocator, & get_header() );
|
|
|
|
));
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
make( proc, append )
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
append->add_params( t_elem_value, "value" );
|
|
|
|
append->add_ret_type( void );
|
|
|
|
|
|
|
|
Code
|
|
|
|
body = append.body();
|
|
|
|
body->add_untyped(
|
|
|
|
if ( header.Capacity < header.Num + 1 )
|
|
|
|
if ( ! grow(0) )
|
|
|
|
return false;
|
2023-04-03 00:55:28 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body->add_untyped( assign,
|
|
|
|
Data[ header.Num ] = value;
|
|
|
|
header.Num++;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code back;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = untyped(
|
|
|
|
Header& header = get_header();
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
return data[ header.Num - 1 ];
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( back, __, t_elem_type, __, body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code clear;
|
|
|
|
proc( clear, __, t_void, __, untyped_str("get_header().Num = 0;") );
|
|
|
|
|
|
|
|
Code fill;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code check = untyped(
|
|
|
|
if ( begin < 0 || end >= header.Num )
|
|
|
|
fatal( "Range out of bounds" );
|
|
|
|
);
|
|
|
|
|
|
|
|
Code iter = untyped(
|
|
|
|
for ( sw index = begin; index < end; index++ )
|
|
|
|
Data[index] = vallue;
|
2023-04-03 00:55:28 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = proc_body( header, check, iter );
|
|
|
|
|
|
|
|
proc( fill, __, t_void, params( t_uw, "begin", t_uw, "end", t_elem_type, "value" ), body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code get_header;
|
|
|
|
proc( get_header, spec_inline, t_ref_header, __, untyped_str("return pcast( Header, Data - 1);") );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code grow;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
variable( uw, new_capacity, untyped( grow_formula( header.Capacity) ));
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code check_n_set = untyped(
|
|
|
|
if ( new_capacity < min_capacity )
|
|
|
|
new_capacity = min_capacity;
|
2023-04-03 00:55:28 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code ret = untyped( return set_capacity( new_capacity ); );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = proc_body( header, new_capacity, check_n_set, ret );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( grow, __, t_bool, params( t_uw, "min_capacity" ), body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code pop;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
untyped_code( assertion, assert( header.Num > 0 ); );
|
|
|
|
untyped_code( decrement, header.Num--; );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = proc_body( header, assertion, decrement );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( pop, __, t_void, __, body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code reserve;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
untyped_code( check_n_set,
|
|
|
|
if ( header.Capacity < new_capacity )
|
|
|
|
return set_capacity( new_capacity );
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code ret = untyped_str("return true");
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body = proc_body( header, check_n_set, ret );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( reserve, __, t_bool, params( t_uw, "new_capacity" ), body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code resize;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Code body;
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
untyped_code( check_n_grow,
|
|
|
|
if ( header.Capacity < new_num )
|
|
|
|
if ( ! grow( new_num) )
|
|
|
|
return false;
|
2023-04-03 00:55:28 -07:00
|
|
|
);
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
untyped_code( set_n_ret,
|
|
|
|
header.Count = new_num;
|
|
|
|
return true;
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
body = proc_body( header, check_n_grow, set_n_ret );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
proc( resize, __, t_bool, params( t_uw, "new_num" ), body );
|
2023-04-03 00:55:28 -07:00
|
|
|
}
|
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
Code set_capacity = proc_code(
|
|
|
|
bool set_capacity( new_capacity )
|
2023-04-03 00:55:28 -07:00
|
|
|
{
|
2023-04-03 23:04:19 -07:00
|
|
|
Header& header = get_header();
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( capacity == header.Capacity )
|
|
|
|
return true;
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( capacity < header.Num )
|
|
|
|
header.Num = capacity;
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
uw size = sizeof(Header) + sizeof(Type) * capacity;
|
|
|
|
Header* new_header = rcast( Header* alloc( header.Allocator, size ));
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
if ( new_header == nullptr )
|
|
|
|
return false;
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
memmove( new_header, & header, sizeof( Header ) + sizeof(Type) * header.Num );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
new_header->Allocator = header.Allocator;
|
|
|
|
new_header->Num = header.Num;
|
|
|
|
new_header->Capacity = header.Capacity;
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
free( header );
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
*Data = new_header + 1;
|
2023-04-03 00:55:28 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
);
|
2023-04-03 00:55:28 -07:00
|
|
|
|
|
|
|
char const* name = bprintf( "Array_%s", type_str );
|
|
|
|
|
|
|
|
Code body = struct_body(
|
|
|
|
Type
|
|
|
|
, Data
|
|
|
|
|
|
|
|
, init
|
|
|
|
, init_reserve
|
|
|
|
, append
|
|
|
|
, back
|
|
|
|
, clear
|
|
|
|
, fill
|
|
|
|
, free
|
|
|
|
, get_header
|
|
|
|
, grow
|
|
|
|
, pop
|
|
|
|
, reserve
|
|
|
|
, resize
|
|
|
|
, set_capacity
|
|
|
|
);
|
|
|
|
|
|
|
|
array_def = def_struct( name, body, parent );
|
|
|
|
}
|
|
|
|
#endif
|
2023-04-02 09:35:14 -07:00
|
|
|
|
|
|
|
return array_def;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 gen_array_file()
|
|
|
|
{
|
|
|
|
Code a_base = gen__array_base();
|
|
|
|
|
|
|
|
Code a_u32 = gen_array( u32 );
|
|
|
|
Code a_cstr = gen_array( char const* );
|
|
|
|
|
|
|
|
Builder
|
|
|
|
arraygen;
|
|
|
|
arraygen.open( "Array.gen.hpp" );
|
|
|
|
arraygen.print( a_u32 );
|
|
|
|
arraygen.print( a_cstr );
|
|
|
|
arraygen.write();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef gen_time
|
|
|
|
# include "Array.gen.hpp"
|
|
|
|
|
|
|
|
# define array( Type_ ) array_##Type_
|
|
|
|
#endif
|