HandmadeHero/project/platform/strings.hpp

191 lines
3.4 KiB
C++
Raw Normal View History

2023-10-06 23:33:39 -07:00
#pragma once
2023-09-26 22:16:41 -07:00
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) }
2023-09-26 22:16:41 -07:00
// Length tracked raw strings.
struct Str
{
u32 len;
char* ptr;
2023-09-26 22:16:41 -07:00
void append( u32 src_len, char const* src ) {
str_append( len, ptr, src_len, src );
2023-09-26 22:16:41 -07:00
}
void append( Str const src ) {
str_append( len, ptr, src.len, src.ptr );
2023-09-26 22:16:41 -07:00
}
2023-09-29 12:58:18 -07:00
void concat( u32 dest_size, Str* dest, Str const str_a, Str const str_b )
2023-09-26 22:16:41 -07:00
{
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;
2023-09-26 22:16:41 -07:00
}
operator char*() const {
return ptr;
2023-09-26 22:16:41 -07:00
}
char& operator []( u32 idx ) {
return ptr[idx];
2023-09-26 22:16:41 -07:00
}
char const& operator []( u32 idx ) const {
return ptr[idx];
2023-09-26 22:16:41 -07:00
}
};
// Fixed length raw strings.
2023-09-29 12:58:18 -07:00
template< u32 capacity >
2023-09-26 22:16:41 -07:00
struct StrFixed
{
constexpr static u32 Capacity = capacity;
u32 len;
char ptr[capacity];
2023-09-26 22:16:41 -07:00
void append( u32 src_len, char const* src ) {
str_append( len, data, src_len, src );
2023-09-26 22:16:41 -07:00
}
void append( Str const src ) {
str_append( len, data, src.Len, src.data );
2023-09-26 22:16:41 -07:00
}
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;
2023-09-26 22:16:41 -07:00
}
operator char*() { return ptr;}
operator char const*() { return ptr; }
operator Str() { return { len, ptr }; }
operator Str const() const { return { len, ptr }; }
2023-09-26 22:16:41 -07:00
char& operator []( u32 idx ) {
assert( idx < Capacity );
return ptr[idx];
2023-09-26 22:16:41 -07:00
}
char const& operator []( u32 idx ) const {
assert( idx < Capacity );
return ptr[idx];
2023-09-26 22:16:41 -07:00
}
};
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;
2023-09-26 22:16:41 -07:00
while ( left-- )
{
*dest_a = *str_a;
2023-09-26 22:16:41 -07:00
*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;
2023-09-26 22:16:41 -07:00
}
}
else if ( str_a_len < str_b_len )
{
u32 left = str_a_len;
2023-09-26 22:16:41 -07:00
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;
2023-09-26 22:16:41 -07:00
}
}
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;
}
2023-09-29 12:58:18 -07:00
using StrPath = StrFixed< S16_MAX >;