commit ff172aba950dbe4e25ef505295d2d0c6580123e0 parent 5d324a83ba73bfaf5fb5f64ff5268a696cb692c4 Author: Michael Savage <mikejsavage@gmail.com> Date: Sat Sep 9 13:57:32 +0300 Add DynamicString Diffstat:
array.h | | | 45 | +++++++++++++++++++++++++++++++++------------ |
dynstr.h | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
diff --git a/array.h b/array.h @@ -298,24 +298,45 @@ public: } 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++; + size_t idx = extend( 1 ); + elems[ idx ] = x; } void clear() { n = 0; } + void resize( size_t new_size ) { + if( new_size < n ) { + n = new_size; + return; + } + + if( new_size <= capacity ) { + n = new_size; + return; + } + + size_t new_capacity = max( size_t( 64 ), capacity ); + while( new_capacity < new_size ) { + new_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; + n = new_size; + } + + size_t extend( size_t by ) { + size_t old_size = n; + resize( n + by ); + return old_size; + } + T & operator[]( size_t i ) { ASSERT( i < n ); return elems[ i ]; diff --git a/dynstr.h b/dynstr.h @@ -0,0 +1,49 @@ +#pragma once + +#include "array.h" +#include "ggformat.h" + +class DynamicString { +public: + DynamicString() { } + + template< typename... Rest > + DynamicString( const char * fmt, Rest... rest ) { + sprintf( fmt, rest... ); + } + + template< typename T > + void operator+=( const T & x ) { + appendf( "{}", x ); + } + + template< typename... Rest > + void sprintf( const char * fmt, Rest... rest ) { + size_t len = ggformat( NULL, 0, fmt, rest... ); + buf.resize( len + 1 ); + ggformat( &buf[ 0 ], len + 1, fmt, rest... ); + } + + template< typename... Rest > + void appendf( const char * fmt, Rest... rest ) { + size_t len = ggformat( NULL, 0, fmt, rest... ); + size_t old_len = length(); + buf.extend( old_len == 0 ? len + 1 : len ); + ggformat( &buf[ old_len ], len + 1, fmt, rest... ); + } + + const char * c_str() const { + if( buf.size() == 0 ) { + return ""; + } + + return buf.ptr(); + } + + size_t length() const { + return buf.size() == 0 ? 0 : buf.size() - 1; + } + +private: + DynamicArray< char > buf; +};