diff options
Diffstat (limited to 'src/util/allocator.h')
| -rw-r--r-- | src/util/allocator.h | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/src/util/allocator.h b/src/util/allocator.h index 64bad23..8b159da 100644 --- a/src/util/allocator.h +++ b/src/util/allocator.h @@ -93,9 +93,15 @@ struct LIST { } data = (T*)malloc( sizeof( T ) * other.capacity ); - memcpy( data, other.data, other.size * sizeof( T ) ); size = other.size; capacity = other.capacity; + if constexpr( __is_trivially_copyable(T) ) + memcpy( data, other.data, other.size * sizeof(T) ); + else { + memset( data, 0, other.capacity * sizeof(T) ); + for( U32 i = 0; i < other.size; i++ ) + data[i] = other.data[i]; + } } LIST<T>& operator=( const LIST<T>& other ) { @@ -107,7 +113,7 @@ struct LIST { data = 0; - if( !other.capacity || !other.size ) { + if( !other.capacity || !other.size || !other.data ) { capacity = 1; size = 0; data = (T*)malloc( sizeof( T ) ); @@ -116,15 +122,26 @@ struct LIST { } data = (T*)malloc( other.capacity * sizeof( T ) ); - memcpy( data, other.data, other.size * sizeof( T ) ); size = other.size; capacity = other.capacity; + if constexpr( __is_trivially_copyable(T) ) + memcpy( data, other.data, other.size * sizeof(T) ); + else { + memset( data, 0, other.capacity * sizeof(T) ); + for( U32 i = 0; i < other.size; i++ ) + data[i] = other.data[i]; + } return *this; } ~LIST() { - free( data ); + if constexpr( !__is_trivially_destructible(T) ) { + for( U32 i = 0; i < size; i++ ) + data[i].~T(); + } + if( data ) + free( data ); } T at( U32 index ) { @@ -136,7 +153,7 @@ struct LIST { return; T* newblock = (T*)malloc( count * sizeof( T ) ); - memset( newblock, 0, capacity * sizeof( T ) ); + memset( newblock, 0, count * sizeof( T ) ); if( data ) { memcpy( newblock, data, size * sizeof( T ) ); free( data ); @@ -221,9 +238,14 @@ struct LIST { // slow - pushes every item individually, calls copy constructors void push_list( LIST<T>& list ) { - list.each( fn( T* item ) { - push( *item ); - } ); + if constexpr( __is_trivially_copyable(T) ) { + emplace_list( list ); + } else { + reserve( list.capacity ); + list.each( fn( T* item ) { + push( *item ); + } ); + } } T pop() { @@ -241,7 +263,7 @@ struct LIST { } T pop_front() { - if( size == 0 ) { + if( size == 0 ) { dlog( "LIST::pop_front() : called on empty list\n" ); abort(); return {}; @@ -256,6 +278,11 @@ struct LIST { if( idx >= size ) return; + if constexpr( !__is_trivially_destructible(T) ) { + data[idx].~T(); + memset( &data[idx], 0, sizeof(T) ); + } + for( U32 i = idx; i < size - 1; i++ ) data[i] = data[i + 1]; @@ -268,6 +295,11 @@ struct LIST { } void clear() { + if constexpr( !__is_trivially_destructible(T) ) { + for( U32 i = 0; i < size; ++i ) + data[i].~T(); + } + size = 0; free( data ); data = (T*)malloc( sizeof( T ) ); |
