commit c222136b1d57b5e919ccc274f976275ee1ea46b1 parent c1d981120da9b67cfd007ff348203c4f7d4cf380 Author: Michael Savage <mikejsavage@gmail.com> Date: Mon May 8 02:52:40 +0300 Add DynamicArray Diffstat:
array.h | | | 113 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
intrinsics.h | | | 14 | ++++++++++++++ |
diff --git a/array.h b/array.h @@ -3,6 +3,7 @@ #include <stdlib.h> #include "intrinsics.h" +#include "log.h" template< typename T > class array { @@ -166,6 +167,118 @@ private: T elems_memory[ N ]; }; +// TODO: pluggable allocators +template< typename T > +class DynamicArray { +public: + NONCOPYABLE( DynamicArray ); + + DynamicArray( size_t initial_capacity = 0 ) { + n = 0; + capacity = initial_capacity; + elems = NULL; + if( initial_capacity > 0 ) { + elems = realloc_array( elems, capacity ); + } + } + + ~DynamicArray() { + free( elems ); + } + + void append( const T & x ) { + if( n == capacity ) { + size_t new_capacity = max( size_t( 64 ), capacity * 2 ); + T * new_elems = realloc_array( elems, new_capacity ); + if( new_elems == NULL ) { + FATAL( "couldn't allocate for DynamicArray" ); + } + elems = new_elems; + capacity = new_capacity; + } + + elems[ n ] = x; + n++; + } + + T & operator[]( size_t i ) { + ASSERT( i < n ); + return elems[ i ]; + } + + const T & operator[]( size_t i ) const { + ASSERT( i < n ); + return elems[ i ]; + } + + array< T > operator+( size_t i ) { + ASSERT( i <= n ); + return array< T >( elems + i, n - i ); + } + + const array< T > operator+( size_t i ) const { + ASSERT( i <= n ); + return array< T >( elems + i, n - i ); + } + + bool in_range( size_t i ) const { + return i < n; + } + + T * ptr() { + return elems; + } + + const T * ptr() const { + return elems; + } + + size_t size() const { + return n; + } + + size_t num_bytes() const { + return sizeof( T ) * n; + } + + T * begin() { + return elems; + } + + T * end() { + return elems + n; + } + + const T * begin() const { + return elems; + } + + const T * end() const { + return elems + n; + } + + array< T > slice( size_t start, size_t one_past_end ) { + ASSERT( start <= one_past_end ); + ASSERT( one_past_end <= n ); + return array< T >( elems + start, one_past_end - start ); + } + + const array< T > slice( size_t start, size_t one_past_end ) const { + ASSERT( start <= one_past_end ); + ASSERT( one_past_end <= n ); + return array< T >( elems + start, one_past_end - start ); + } + + operator const array< T >() const { + return array< T >( elems, n ); + } + +private: + size_t n; + size_t capacity; + T * elems; +}; + template< typename T, typename F > inline void visit( array< T > & a, F f ) { f( a.n ); diff --git a/intrinsics.h b/intrinsics.h @@ -224,3 +224,17 @@ DEF_VISIT( float ) DEF_VISIT( double ) #undef DEF_VISIT + +#if !PLATFORM_RELACY +template< typename T > +inline T * malloc_array( size_t count ) { + ASSERT( SIZE_MAX / count >= sizeof( T ) ); + return ( T * ) malloc( count * sizeof( T ) ); +} + +template< typename T > +inline T * realloc_array( T * old, size_t count ) { + ASSERT( SIZE_MAX / count >= sizeof( T ) ); + return ( T * ) realloc( old, count * sizeof( T ) ); +} +#endif