HandmadeHero/project/platform/strings.hpp
Ed_ dc43db117c Day 25 Part 1
I'm splitting this implementation into parts since so much already happened...

I fully updated the code the the latest convention I want to use for the project.
Engine & Game replay should work.
2023-09-30 10:05:37 -04:00

192 lines
3.5 KiB
C++

#include "macros.hpp"
#include "types.hpp"
void str_append( u32 dest_len, char* dest, u32 src_len, char const* src );
void str_concat( u32 dest_size, char* dest
, u32 str_a_len, char const* str_a
, u32 str_b_len, char const* str_b );
u32 str_length( char const* str );
#define str_ascii( str ) { sizeof( str ) - 1, ccast( char*, str) }
// Length tracked raw strings.
struct Str
{
u32 len;
char* ptr;
void append( u32 src_len, char const* src ) {
str_append( len, ptr, src_len, src );
}
void append( Str const src ) {
str_append( len, ptr, src.len, src.ptr );
}
void concat( u32 dest_size, Str* dest, Str const str_a, Str const str_b )
{
str_concat( dest_size, dest->ptr
, str_a.len, str_a.ptr
, str_b.len, str_b.ptr );
dest->len = str_a.len + str_b.len;
}
operator char*() const {
return ptr;
}
char& operator []( u32 idx ) {
return ptr[idx];
}
char const& operator []( u32 idx ) const {
return ptr[idx];
}
};
// Fixed length raw strings.
template< u32 capacity >
struct StrFixed
{
constexpr static u32 Capacity = capacity;
u32 len;
char ptr[capacity];
void append( u32 src_len, char const* src ) {
str_append( len, data, src_len, src );
}
void append( Str const src ) {
str_append( len, data, src.Len, src.data );
}
void concat( Str const str_a, Str const str_b )
{
str_concat( Capacity, ptr
, str_a.len, str_a.ptr
, str_b.len, str_b.ptr );
len = str_a.len + str_b.len;
}
operator char*() { return ptr;}
operator char const*() { return ptr; }
operator Str() { return { len, ptr }; }
operator Str const() const { return { len, ptr }; }
char& operator []( u32 idx ) {
assert( idx < Capacity );
return ptr[idx];
}
char const& operator []( u32 idx ) const {
assert( idx < Capacity );
return ptr[idx];
}
};
inline
void str_append( u32 dest_len, char* dest, u32 src_len, char const* src )
{
assert( dest_len > 0 );
assert( dest != nullptr );
assert( src_len > 0 );
assert( src != nullptr );
assert( dest_len >= src_len );
char* dest_end = dest + dest_len;
assert( *dest_end == '\0' );
u32 left = src_len;
while ( left-- )
{
*dest = *src;
++ dest;
++ src;
}
}
void str_concat( u32 dest_size, char* dest
, u32 str_a_len, char const* str_a
, u32 str_b_len, char const* str_b )
{
assert( dest_size > 0 );
assert( dest != nullptr );
assert( *dest == '\0' );
assert( str_a_len > 0 );
assert( str_a != nullptr );
assert( str_b_len > 0 );
assert( str_b != nullptr );
assert( str_a_len + str_b_len < dest_size );
char* dest_a = dest;
char* dest_b = dest + str_a_len;
if ( str_a_len > str_b_len )
{
u32 left = str_b_len;
while ( left-- )
{
*dest_a = *str_a;
*dest_b = *str_b;
++ dest_a;
++ dest_b;
++ str_a;
++ str_b;
}
left = str_a_len - str_b_len;
while ( left-- )
{
*dest_a = *str_a;
++ dest_a;
++ str_a;
}
}
else if ( str_a_len < str_b_len )
{
u32 left = str_a_len;
while ( left-- )
{
*dest_a = *str_a;
*dest_b = *str_b;
++ dest_a;
++ dest_b;
++ str_a;
++ str_b;
}
left = str_b_len - str_a_len;
while ( left-- )
{
*dest_b = *str_b;
++ dest_b;
++ str_b;
}
}
else
{
u32 left = str_a_len;
while ( left-- )
{
*dest_a = *str_a;
*dest_b = *str_b;
++ dest_a;
++ str_a;
++ dest_b;
++ str_b;
}
}
}
inline
u32 str_length( char const* str )
{
assert( str != nullptr );
u32 result = 0;
while ( *str != '\0' )
{
++ result;
++ str;
}
return result;
}
using StrPath = StrFixed< S16_MAX >;