From 8329d42d3e592f4cd42cdfa586e2325ddc76c898 Mon Sep 17 00:00:00 2001 From: aura Date: Tue, 10 Mar 2026 01:35:50 +0100 Subject: perf profiler, simplify 2d render, string struct, many small things --- src/util/string.h | 209 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 193 insertions(+), 16 deletions(-) (limited to 'src/util/string.h') diff --git a/src/util/string.h b/src/util/string.h index 47da1a0..0781fca 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -1,7 +1,9 @@ #pragma once +#include +#include #include -#include "typedef.h" +#include "allocator.h" constexpr U32 strlen_ct( const char* str ) { U32 len = 0; @@ -10,40 +12,215 @@ constexpr U32 strlen_ct( const char* str ) { } template -struct STR { +struct ARRSTR { char data[N]{ 0 }; enum { size = N }; - STR() { + ARRSTR() { memset( data, 0, N ); } - STR( const char* str ) { + ARRSTR( const char* str ) { memcpy( data, str, strlen_ct( str ) ); } - STR( const STR& str ) { + ARRSTR( const ARRSTR& str ) { memcpy( data, str.data, N ); } template - auto operator+( const STR& rhs ) { - constexpr U32 l1 = strlen_ct( data ); - constexpr U32 l2 = strlen_ct( rhs.data ); + auto operator+( const ARRSTR& rhs ) { + const U32 l1 = strlen_ct( data ); + const U32 l2 = strlen_ct( rhs.data ); - constexpr U32 high = N > other ? N : other; - constexpr U32 max = (l1 + l2 > high) ? l1 + l2 + 1 : high; + if( l1 + l2 >= N ) { + dlog( "STR::operator+(): string overflow" ); + abort(); + return *this; + } - STR result; - memcpy( result.data, data, l1 ); - memcpy( result.data + l1, rhs.data, l2 ); - result.data[l1 + l2] = '\0'; - return result; + memcpy( data + l1, rhs.data, l2 ); + data[l1 + l2] = '\0'; + return *this; } template - auto concat( const STR& str ) { + auto concat( const ARRSTR& str ) { return *this + str; } operator char*() { return data; } }; + +template +struct __str : public LIST { + __str() : LIST() {} + __str( const CT* fmt, ... ) : LIST() { + va_list args; + va_start( args, fmt ); + va_list args2; + va_copy( args2, args ); + U32 c = vsnprintf( 0, 0, fmt, args ); + va_end( args ); + this->data = 0; + this->reserve( c * 2 ); + vsnprintf( this->data, c + 1, fmt, args2 ); + this->data[c] = 0; + this->size = c; + va_end( args2 ); + } + + __str( const __str& rhs ) : LIST( rhs ) { + this->data[this->size] = 0; + } + + __str& operator=( const __str& other ) { + if( this == &other ) + return *this; + + if( this->data && this->data != other.data ) + free( this->data ); + + this->data = 0; + + if( !other.capacity || !other.size ) { + this->capacity = 1; + this->size = 0; + this->data = (CT*)malloc( sizeof(CT) ); + memset( this->data, 0, sizeof(CT) ); + return *this; + } + + this->data = (CT*)malloc( other.capacity * sizeof( CT ) ); + memcpy( this->data, other.data, (other.size + 1) * sizeof( CT ) ); + this->size = other.size; + this->capacity = other.capacity; + + return *this; + } + + const bool operator==( const __str& rhs ) { return this->equals( rhs ); } + const bool operator!=( const __str& rhs ) { return !(*this == rhs); } + const bool operator==( const CT* rhs ) { return this->equals( rhs ); } + const bool operator!=( const CT* rhs ) { return !(*this == rhs); } + __str operator+( const __str& rhs ) { __str ret = *this; return ret.append( rhs ); } + __str operator+( const CT* rhs ) { __str ret = *this; return ret.append( rhs ); } + __str operator+( const CT rhs ) { __str ret = *this; ret.push( rhs ); return ret; } + __str& operator+=( const __str& rhs ) { return this->append( rhs ); } + __str& operator+=( const CT* rhs ) { return this->append( rhs ); } + __str& operator+=( const CT rhs ) { this->push( rhs ); return this; } + + operator CT*() { return this->data; } + + CT operator[]( U32 i ) { + return this->data[i]; + } + + U8 equals( const __str& rhs ) { + if( rhs.size != this->size ) + return 0; + + for( U32 i = 0; i < this->size; ++i ) { + if( this->data[i] != rhs.data[i] ) + return 0; + } + + return 1; + } + + U8 equals( const CT* rhs ) { + for( U32 i = 0; i < this->size; ++i ) { + if( !rhs[i] || this->data[i] != rhs[i] ) + return 0; + } + + return 1; + } + + __str& fmt( const char* fmt, ... ) { + va_list args; + va_start( args, fmt ); + va_list args2; + va_copy( args2, args ); + U32 c = this->size + vsnprintf( 0, 0, fmt, args ); + va_end( args ); + if( c > this->capacity ) + this->reserve( c * 2 ); + vsnprintf( this->data + this->size, c + 1, fmt, args2 ); + this->data[c] = 0; + this->size = c; + va_end( args2 ); + } + + __str& append( const CT* str ) { + U32 len; + for( len = 0; !!str[len]; ++len ); + if( this->size + len > this->capacity ) + this->reserve( this->size * 2 ); + + memcpy( this->data + this->size, str, len * sizeof(CT) ); + this->size += len; + this->data[this->size] = 0; + return *this; + } + + __str& append( const __str& str ) { + U32 len = str.len; + if( this->size + len + 1 >= this->capacity ) + this->reserve( this->size + len + 1 ); + + memcpy( this->data + this->size, str, len * sizeof(CT) ); + this->size += len; + this->data[this->size] = 0; + return *this; + } + + CT* push( const CT& item ) { + if( this->capacity <= this->size + 1 ) + this->grow(); + this->data[this->size++] = item; + this->data[this->size] = 0; + + return &this->data[this->size - 1]; + } + + U32 idx_of( const CT* str ) { + return idx_of( str, 0 ); + } + + U32 idx_of( const CT* str, U32 offset ) { + for( U32 i = offset; i < this->size; ++i ) { + U8 found = 1; + for( U32 i2 = 0; !!str[i2] && i + i2 < this->size; ++i2 ) { + if( this->data[i + i2] != str[i2] ) { + found = 0; + break; + } + } + + if( found ) + return i; + } + } + + CT* find( const CT* str ) { + for( U32 i = 0; i < this->size; ++i ) { + U8 found = 1; + for( U32 i2 = 0; !!str[i2] && i + i2 < this->size; ++i2 ) { + if( this->data[i + i2] != str[i2] ) { + found = 0; + break; + } + } + if( found ) + return this->data + i; + } + return 0; + } + + LIST_ITERATOR end() { + return LIST_ITERATOR( this->data + this->size ); + } +}; + +using STR = __str; +using WSTR = __str; -- cgit v1.2.3