mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 14:30:53 -07:00 
			
		
		
		
	Array done
This commit is contained in:
		| @@ -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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user