mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Array done
This commit is contained in:
parent
4137ebfbd8
commit
34eec66f35
@ -133,7 +133,7 @@ internal
|
|||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
Tokens = Array<Token>::init_reserve( LexArena
|
Tokens = Array<Token>::init_reserve( LexArena
|
||||||
, ( LexAllocator_Size - sizeof( Array<Token>::Header ) ) / sizeof(Token)
|
, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token)
|
||||||
);
|
);
|
||||||
|
|
||||||
defines_map_arena = Arena_256KB::init();
|
defines_map_arena = Arena_256KB::init();
|
||||||
|
@ -13,26 +13,85 @@ template<class TType, usize Size> struct RemoveConst<const TType[Size]> { typede
|
|||||||
template<class TType>
|
template<class TType>
|
||||||
using TRemoveConst = typename RemoveConst<TType>::Type;
|
using TRemoveConst = typename RemoveConst<TType>::Type;
|
||||||
|
|
||||||
template<class Type>
|
#pragma region Array
|
||||||
struct Array
|
struct ArrayHeader;
|
||||||
{
|
template<class Type> struct Array;
|
||||||
struct Header
|
|
||||||
|
template<class Type> Array<Type> array_init(AllocatorInfo allocator);
|
||||||
|
template<class Type> Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity);
|
||||||
|
template<class Type> usize array_grow_formula(ssize value);
|
||||||
|
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);
|
||||||
|
|
||||||
|
struct ArrayHeader
|
||||||
{
|
{
|
||||||
AllocatorInfo Allocator;
|
AllocatorInfo Allocator;
|
||||||
usize Capacity;
|
usize Capacity;
|
||||||
usize Num;
|
usize Num;
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
template<class Type>
|
||||||
Array init( AllocatorInfo allocator )
|
struct Array
|
||||||
{
|
{
|
||||||
return init_reserve( allocator, grow_formula(0) );
|
Type* Data;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#pragma region Member Mapping
|
||||||
|
forceinline static Array init(AllocatorInfo allocator) { return GEN_NS array_init<Type>(allocator); }
|
||||||
|
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 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 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 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 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
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Type> inline
|
||||||
|
Array<Type> array_init(AllocatorInfo allocator)
|
||||||
|
{
|
||||||
|
return array_init_reserve<Type>(allocator, array_grow_formula<Type>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
template<class Type> inline
|
||||||
Array init_reserve( AllocatorInfo allocator, ssize capacity )
|
Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
|
||||||
{
|
{
|
||||||
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) * capacity ));
|
ArrayHeader* header = rcast(ArrayHeader*, alloc(allocator, sizeof(ArrayHeader) + sizeof(Type) * capacity));
|
||||||
|
|
||||||
if (header == nullptr)
|
if (header == nullptr)
|
||||||
return {nullptr};
|
return {nullptr};
|
||||||
@ -44,56 +103,60 @@ struct Array
|
|||||||
return {rcast(Type*, header + 1)};
|
return {rcast(Type*, header + 1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
template<class Type> inline
|
||||||
usize grow_formula( usize value )
|
usize array_grow_formula(ssize value)
|
||||||
{
|
{
|
||||||
return 2 * value + 8;
|
return 2 * value + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append( Array other )
|
template<class Type> inline
|
||||||
|
bool append(Array<Type>& array, Array<Type> other)
|
||||||
{
|
{
|
||||||
return append( other, other.num() );
|
return append(array, other, num(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append( Type value )
|
template<class Type> inline
|
||||||
|
bool append(Array<Type>& array, Type value)
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if (header->Num == header->Capacity)
|
if (header->Num == header->Capacity)
|
||||||
{
|
{
|
||||||
if ( ! grow( header->Capacity ))
|
if (!grow(array, header->Capacity))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header();
|
header = get_header(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data[ header->Num ] = value;
|
array.Data[header->Num] = value;
|
||||||
header->Num++;
|
header->Num++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append( Type* items, usize item_num )
|
template<class Type> inline
|
||||||
|
bool append(Array<Type>& array, Type* items, usize item_num)
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if (header->Num + item_num > header->Capacity)
|
if (header->Num + item_num > header->Capacity)
|
||||||
{
|
{
|
||||||
if ( ! grow( header->Capacity + item_num ))
|
if (!grow(array, header->Capacity + item_num))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header();
|
header = get_header(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_copy( Data + header->Num, items, item_num * sizeof(Type) );
|
mem_copy(array.Data + header->Num, items, item_num * sizeof(Type));
|
||||||
header->Num += item_num;
|
header->Num += item_num;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append_at( Type item, usize idx )
|
template<class Type> inline
|
||||||
|
bool append_at(Array<Type>& array, Type item, usize idx)
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if (idx >= header->Num)
|
if (idx >= header->Num)
|
||||||
idx = header->Num - 1;
|
idx = header->Num - 1;
|
||||||
@ -103,13 +166,13 @@ struct Array
|
|||||||
|
|
||||||
if (header->Capacity < header->Num + 1)
|
if (header->Capacity < header->Num + 1)
|
||||||
{
|
{
|
||||||
if ( ! grow( header->Capacity + 1 ))
|
if (!grow(array, header->Capacity + 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header();
|
header = get_header(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* target = Data + idx;
|
Type* target = array.Data + idx;
|
||||||
|
|
||||||
mem_move(target + 1, target, (header->Num - idx) * sizeof(Type));
|
mem_move(target + 1, target, (header->Num - idx) * sizeof(Type));
|
||||||
header->Num++;
|
header->Num++;
|
||||||
@ -117,25 +180,26 @@ struct Array
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append_at( Type* items, usize item_num, usize idx )
|
template<class Type> inline
|
||||||
|
bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx)
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if (idx >= header->Num)
|
if (idx >= header->Num)
|
||||||
{
|
{
|
||||||
return append( items, item_num );
|
return append(array, items, item_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item_num > header->Capacity)
|
if (item_num > header->Capacity)
|
||||||
{
|
{
|
||||||
if ( ! grow( header->Capacity + item_num ) )
|
if (!grow(array, header->Capacity + item_num))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header();
|
header = get_header(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* target = Data + idx + item_num;
|
Type* target = array.Data + idx + item_num;
|
||||||
Type* src = Data + idx;
|
Type* src = array.Data + idx;
|
||||||
|
|
||||||
mem_move(target, src, (header->Num - idx) * sizeof(Type));
|
mem_move(target, src, (header->Num - idx) * sizeof(Type));
|
||||||
mem_copy(src, items, item_num * sizeof(Type));
|
mem_copy(src, items, item_num * sizeof(Type));
|
||||||
@ -144,159 +208,145 @@ struct Array
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type& back( void )
|
template<class Type> inline
|
||||||
|
Type& back(Array<Type>& array)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
return Data[ header.Num - 1 ];
|
return array.Data[header->Num - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear( void )
|
template<class Type> inline
|
||||||
|
void clear(Array<Type>& array)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
header.Num = 0;
|
header->Num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fill( usize begin, usize end, Type value )
|
template<class Type> inline
|
||||||
|
bool fill(Array<Type>& array, usize begin, usize end, Type value)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if ( begin < 0 || end > header.Num )
|
if (begin < 0 || end > header->Num)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (ssize idx = ssize(begin); idx < ssize(end); idx++)
|
for (ssize idx = ssize(begin); idx < ssize(end); idx++)
|
||||||
{
|
{
|
||||||
Data[ idx ] = value;
|
array.Data[idx] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free( void )
|
template<class Type> inline
|
||||||
|
void free(Array<Type>& array)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
gen::free( header.Allocator, &header );
|
gen::free(header->Allocator, header);
|
||||||
Data = nullptr;
|
array.Data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Header* get_header( void )
|
template<class Type> inline
|
||||||
|
ArrayHeader* get_header(Array<Type>& array)
|
||||||
{
|
{
|
||||||
using NonConstType = TRemoveConst<Type>;
|
using NonConstType = TRemoveConst<Type>;
|
||||||
return rcast( Header*, const_cast<NonConstType*>(Data) ) - 1 ;
|
return rcast(ArrayHeader*, const_cast<NonConstType*>(array.Data)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grow( usize min_capacity )
|
template<class Type> inline
|
||||||
|
bool grow(Array<Type>& array, usize min_capacity)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
usize new_capacity = grow_formula( header.Capacity );
|
usize new_capacity = array_grow_formula<Type>(header->Capacity);
|
||||||
|
|
||||||
if (new_capacity < min_capacity)
|
if (new_capacity < min_capacity)
|
||||||
new_capacity = min_capacity;
|
new_capacity = min_capacity;
|
||||||
|
|
||||||
return set_capacity( new_capacity );
|
return set_capacity(array, new_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
usize num( void )
|
template<class Type> inline
|
||||||
|
usize num(Array<Type>& array)
|
||||||
{
|
{
|
||||||
return get_header()->Num;
|
return get_header(array)->Num;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop( void )
|
template<class Type> inline
|
||||||
|
void pop(Array<Type>& array)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
GEN_ASSERT(header->Num > 0);
|
||||||
GEN_ASSERT( header.Num > 0 );
|
|
||||||
header.Num--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_at( usize idx )
|
|
||||||
{
|
|
||||||
Header* header = get_header();
|
|
||||||
GEN_ASSERT( idx < header->Num );
|
|
||||||
|
|
||||||
mem_move( header + idx, header + idx + 1, sizeof( Type ) * ( header->Num - idx - 1 ) );
|
|
||||||
header->Num--;
|
header->Num--;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reserve( usize new_capacity )
|
template<class Type> inline
|
||||||
|
void remove_at(Array<Type>& array, usize idx)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
GEN_ASSERT(idx < header->Num);
|
||||||
|
|
||||||
if ( header.Capacity < new_capacity )
|
mem_move(array.Data + idx, array.Data + idx + 1, sizeof(Type) * (header->Num - idx - 1));
|
||||||
return set_capacity( new_capacity );
|
header->Num--;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type> inline
|
||||||
|
bool reserve(Array<Type>& array, usize new_capacity)
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
|
if (header->Capacity < new_capacity)
|
||||||
|
return set_capacity(array, new_capacity);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool resize( usize num )
|
template<class Type> inline
|
||||||
|
bool resize(Array<Type>& array, usize num)
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if (header->Capacity < num)
|
if (header->Capacity < num)
|
||||||
{
|
{
|
||||||
if ( ! grow( num ) )
|
if (!grow(array, num))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header();
|
header = get_header(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
header->Num = num;
|
header->Num = num;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_capacity( usize new_capacity )
|
template<class Type> inline
|
||||||
|
bool set_capacity(Array<Type>& array, usize new_capacity)
|
||||||
{
|
{
|
||||||
Header& header = * get_header();
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
if ( new_capacity == header.Capacity )
|
if (new_capacity == header->Capacity)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( new_capacity < header.Num )
|
if (new_capacity < header->Num)
|
||||||
{
|
{
|
||||||
// Already have the memory, mine as well keep it.
|
header->Num = new_capacity;
|
||||||
header.Num = new_capacity;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize size = sizeof( Header ) + sizeof( Type ) * new_capacity;
|
ssize size = sizeof(ArrayHeader) + sizeof(Type) * new_capacity;
|
||||||
Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
|
ArrayHeader* new_header = rcast(ArrayHeader*, alloc(header->Allocator, size));
|
||||||
|
|
||||||
if (new_header == nullptr)
|
if (new_header == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mem_move( new_header, &header, sizeof( Header ) + sizeof( Type ) * header.Num );
|
mem_move(new_header, header, sizeof(ArrayHeader) + sizeof(Type) * header->Num);
|
||||||
|
|
||||||
new_header->Capacity = new_capacity;
|
new_header->Capacity = new_capacity;
|
||||||
|
|
||||||
gen::free( header.Allocator, &header );
|
gen::free(header->Allocator, header);
|
||||||
|
|
||||||
Data = rcast( Type*, new_header + 1);
|
array.Data = rcast(Type*, new_header + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#pragma endregion Array
|
||||||
Type* Data;
|
|
||||||
|
|
||||||
operator Type*()
|
|
||||||
{
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator Type const*() const
|
|
||||||
{
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For-range based support
|
|
||||||
|
|
||||||
Type* begin()
|
|
||||||
{
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type* end()
|
|
||||||
{
|
|
||||||
return Data + get_header()->Num;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(Ed) : This thing needs ALOT of work.
|
// TODO(Ed) : This thing needs ALOT of work.
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ struct FixedArena
|
|||||||
template<s32 Size> inline
|
template<s32 Size> inline
|
||||||
AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; }
|
AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; }
|
||||||
|
|
||||||
template<s32 Size>
|
template<s32 Size> inline
|
||||||
void fixed_arena_init(FixedArena<Size>& result) {
|
void fixed_arena_init(FixedArena<Size>& result) {
|
||||||
zero_size(& result.memory[0], Size);
|
zero_size(& result.memory[0], Size);
|
||||||
result.arena = init_from_memory(& result.memory[0], Size);
|
result.arena = init_from_memory(& result.memory[0], Size);
|
||||||
|
Loading…
Reference in New Issue
Block a user