mirror of
https://github.com/Ed94/gencpp.git
synced 2025-07-13 08:58:59 -07:00
WIP(broken): Converting base library to use c-linkage symbols only
This commit is contained in:
@ -5,15 +5,19 @@
|
||||
|
||||
#pragma region Strings
|
||||
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
struct StrC;
|
||||
|
||||
bool are_equal (StrC lhs, StrC rhs);
|
||||
char const* back (StrC str);
|
||||
bool contains (StrC str, StrC substring);
|
||||
StrC duplicate (StrC str, AllocatorInfo allocator);
|
||||
b32 starts_with (StrC str, StrC substring);
|
||||
StrC to_str (char const* bad_string);
|
||||
StrC visualize_whitespace(StrC str, AllocatorInfo allocator);
|
||||
bool strc_are_equal (StrC lhs, StrC rhs);
|
||||
char const* strc_back (StrC str);
|
||||
bool strc_contains (StrC str, StrC substring);
|
||||
StrC strc_duplicate (StrC str, AllocatorInfo allocator);
|
||||
b32 strc_starts_with (StrC str, StrC substring);
|
||||
StrC strc_to_str (char const* bad_string);
|
||||
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator);
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
// Constant string with length.
|
||||
struct StrC
|
||||
@ -21,17 +25,17 @@ struct StrC
|
||||
ssize Len;
|
||||
char const* Ptr;
|
||||
|
||||
#if ! GEN_COMPILER_C
|
||||
operator char const* () const { return Ptr; }
|
||||
char const& operator[]( ssize index ) const { return Ptr[index]; }
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline operator char const* () const { return Ptr; }
|
||||
forceinline char const& operator[]( ssize index ) const { return Ptr[index]; }
|
||||
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
bool is_equal (StrC rhs) const { return GEN_NS are_equal(* this, rhs); }
|
||||
char const* back () const { return GEN_NS back(* this); }
|
||||
bool contains (StrC substring) const { return GEN_NS contains(* this, substring); }
|
||||
StrC duplicate (AllocatorInfo allocator) const { return GEN_NS duplicate(* this, allocator); }
|
||||
b32 starts_with (StrC substring) const { return GEN_NS starts_with(* this, substring); }
|
||||
StrC visualize_whitespace(AllocatorInfo allocator) const { return GEN_NS visualize_whitespace(* this, allocator); }
|
||||
forceinline bool is_equal (StrC rhs) const { return GEN_NS strc_are_equal(* this, rhs); }
|
||||
forceinline char const* back () const { return GEN_NS strc_back(* this); }
|
||||
forceinline bool contains (StrC substring) const { return GEN_NS strc_contains(* this, substring); }
|
||||
forceinline StrC duplicate (AllocatorInfo allocator) const { return GEN_NS strc_duplicate(* this, allocator); }
|
||||
forceinline b32 starts_with (StrC substring) const { return GEN_NS strc_starts_with(* this, substring); }
|
||||
forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return GEN_NS strc_visualize_whitespace(* this, allocator); }
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
@ -39,12 +43,21 @@ struct StrC
|
||||
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
|
||||
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
|
||||
|
||||
inline char const* begin(StrC str) { return str.Ptr; }
|
||||
inline char const* end (StrC str) { return str.Ptr + str.Len; }
|
||||
inline char const* next (StrC str, char const* iter) { return iter + 1; }
|
||||
GEN_API_C_BEGIN
|
||||
forceinline char const* strc_begin(StrC str) { return str.Ptr; }
|
||||
forceinline char const* strc_end (StrC str) { return str.Ptr + str.Len; }
|
||||
forceinline char const* strc_next (StrC str, char const* iter) { return iter + 1; }
|
||||
GEN_API_C_END
|
||||
|
||||
#if GEN_COMPILER_CPP && 0
|
||||
forceinline char const* begin(StrC str) { return str.Ptr; }
|
||||
forceinline char const* end (StrC str) { return str.Ptr + str.Len; }
|
||||
forceinline char const* next (StrC str, char const* iter) { return iter + 1; }
|
||||
#endif
|
||||
|
||||
GEN_API_C_BEGIN
|
||||
inline
|
||||
bool are_equal(StrC lhs, StrC rhs)
|
||||
bool strc_are_equal(StrC lhs, StrC rhs)
|
||||
{
|
||||
if (lhs.Len != rhs.Len)
|
||||
return false;
|
||||
@ -57,12 +70,12 @@ bool are_equal(StrC lhs, StrC rhs)
|
||||
}
|
||||
|
||||
inline
|
||||
char const* back(StrC str) {
|
||||
char const* strc_back(StrC str) {
|
||||
return & str.Ptr[str.Len - 1];
|
||||
}
|
||||
|
||||
inline
|
||||
bool contains(StrC str, StrC substring)
|
||||
bool strc_contains(StrC str, StrC substring)
|
||||
{
|
||||
if (substring.Len > str.Len)
|
||||
return false;
|
||||
@ -71,25 +84,26 @@ bool contains(StrC str, StrC substring)
|
||||
ssize sub_len = substring.Len;
|
||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||
{
|
||||
if (str_compare(str.Ptr + idx, substring.Ptr, sub_len) == 0)
|
||||
if (str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline
|
||||
b32 starts_with(StrC str, StrC substring) {
|
||||
b32 strc_starts_with(StrC str, StrC substring) {
|
||||
if (substring.Len > str.Len)
|
||||
return false;
|
||||
|
||||
b32 result = str_compare(str.Ptr, substring.Ptr, substring.Len) == 0;
|
||||
b32 result = str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
StrC to_str( char const* bad_str ) {
|
||||
StrC to_strc_from_c_str( char const* bad_str ) {
|
||||
return { str_len( bad_str ), bad_str };
|
||||
}
|
||||
GEN_API_C_END
|
||||
|
||||
// Dynamic String
|
||||
// This is directly based off the ZPL string api.
|
||||
@ -104,42 +118,44 @@ typedef char* String;
|
||||
struct String;
|
||||
#endif
|
||||
|
||||
usize string_grow_formula(usize value);
|
||||
GEN_API_C_BEGIN
|
||||
forceinline usize string_grow_formula(usize value);
|
||||
|
||||
String string_make (AllocatorInfo allocator, char const* str);
|
||||
String string_make (AllocatorInfo allocator, StrC str);
|
||||
String string_make_reserve (AllocatorInfo allocator, ssize capacity);
|
||||
String string_make_length (AllocatorInfo allocator, char const* str, ssize length);
|
||||
String string_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
|
||||
String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
|
||||
String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
|
||||
bool are_equal (String const lhs, String const rhs);
|
||||
bool are_equal (String const lhs, StrC rhs);
|
||||
bool make_space_for (String* str, char const* to_append, ssize add_len);
|
||||
bool append (String* str, char c);
|
||||
bool append (String* str, char const* str_to_append);
|
||||
bool append (String* str, char const* str_to_append, ssize length);
|
||||
bool append (String* str, StrC str_to_append);
|
||||
bool append (String* str, String const other);
|
||||
bool append_fmt (String* str, char const* fmt, ...);
|
||||
ssize avail_space (String const str);
|
||||
char* back (String str);
|
||||
bool contains (String const str, StrC substring);
|
||||
bool contains (String const str, String const substring);
|
||||
ssize capacity (String const str);
|
||||
void clear (String str);
|
||||
String duplicate (String const str, AllocatorInfo allocator);
|
||||
void free (String* str);
|
||||
StringHeader* get_header (String str);
|
||||
ssize length (String const str);
|
||||
b32 starts_with (String const str, StrC substring);
|
||||
b32 starts_with (String const str, String substring);
|
||||
void skip_line (String str);
|
||||
void strip_space (String str);
|
||||
StrC to_strc (String str);
|
||||
void trim (String str, char const* cut_set);
|
||||
void trim_space (String str);
|
||||
String visualize_whitespace(String const str);
|
||||
String string_make_c_str (AllocatorInfo allocator, char const* str);
|
||||
String string_make_strc (AllocatorInfo allocator, StrC str);
|
||||
String string_make_reserve (AllocatorInfo allocator, ssize capacity);
|
||||
String string_make_length (AllocatorInfo allocator, char const* str, ssize length);
|
||||
String string_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
|
||||
String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
|
||||
String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
|
||||
bool string_are_equal (String const lhs, String const rhs);
|
||||
bool string_are_equal_strc (String const lhs, StrC rhs);
|
||||
bool string_make_space_for (String* str, char const* to_append, ssize add_len);
|
||||
bool string_append_char (String* str, char c);
|
||||
bool string_append_c_str (String* str, char const* str_to_append);
|
||||
bool string_append_c_str_len (String* str, char const* str_to_append, ssize length);
|
||||
bool string_append_strc (String* str, StrC str_to_append);
|
||||
bool string_append_string (String* str, String const other);
|
||||
bool string_append_fmt (String* str, char const* fmt, ...);
|
||||
ssize string_avail_space (String const str);
|
||||
char* string_back (String str);
|
||||
bool string_contains_strc (String const str, StrC substring);
|
||||
bool string_contains_string (String const str, String const substring);
|
||||
ssize string_capacity (String const str);
|
||||
void string_clear (String str);
|
||||
String string_duplicate (String const str, AllocatorInfo allocator);
|
||||
void string_free (String* str);
|
||||
StringHeader* string_get_header (String str);
|
||||
ssize string_length (String const str);
|
||||
b32 string_starts_with_strc (String const str, StrC substring);
|
||||
b32 string_starts_with_string (String const str, String substring);
|
||||
void string_skip_line (String str);
|
||||
void string_strip_space (String str);
|
||||
StrC string_to_strc (String str);
|
||||
void string_trim (String str, char const* cut_set);
|
||||
void string_trim_space (String str);
|
||||
String string_visualize_whitespace(String const str);
|
||||
GEN_API_C_END
|
||||
|
||||
struct StringHeader {
|
||||
AllocatorInfo Allocator;
|
||||
@ -147,7 +163,7 @@ struct StringHeader {
|
||||
ssize Length;
|
||||
};
|
||||
|
||||
#if ! GEN_COMPILER_C && GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
#if GEN_COMPILER_CPP && GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
struct String
|
||||
{
|
||||
char* Data;
|
||||
@ -169,10 +185,10 @@ struct String
|
||||
forceinline char& operator[](ssize index) { return Data[index]; }
|
||||
forceinline char const& operator[](ssize index) const { return Data[index]; }
|
||||
|
||||
bool operator==(std::nullptr_t) const { return Data == nullptr; }
|
||||
bool operator!=(std::nullptr_t) const { return Data != nullptr; }
|
||||
friend bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
|
||||
friend bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
|
||||
forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; }
|
||||
forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; }
|
||||
friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
|
||||
friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
|
||||
|
||||
forceinline char* begin() const { return Data; }
|
||||
forceinline char* end() const { return Data + GEN_NS length(* this); }
|
||||
@ -206,29 +222,29 @@ struct String
|
||||
}
|
||||
|
||||
forceinline bool make_space_for(char const* str, ssize add_len) { return GEN_NS make_space_for(this, str, add_len); }
|
||||
forceinline bool append(char c) { return GEN_NS append(this, c); }
|
||||
forceinline bool append(char const* str) { return GEN_NS append(this, str); }
|
||||
forceinline bool append(char const* str, ssize length) { return GEN_NS append(this, str, length); }
|
||||
forceinline bool append(StrC str) { return GEN_NS append(this, str); }
|
||||
forceinline bool append(const String other) { return GEN_NS append(this, other); }
|
||||
forceinline ssize avail_space() const { return GEN_NS avail_space(* this); }
|
||||
forceinline char* back() { return GEN_NS back(* this); }
|
||||
forceinline bool contains(StrC substring) const { return GEN_NS contains(* this, substring); }
|
||||
forceinline bool contains(String const& substring) const { return GEN_NS contains(* this, substring); }
|
||||
forceinline bool append(char c) { return GEN_NS string_append_char(this, c); }
|
||||
forceinline bool append(char const* str) { return GEN_NS string_append_c_str(this, str); }
|
||||
forceinline bool append(char const* str, ssize length) { return GEN_NS string_append_c_str_len(this, str, length); }
|
||||
forceinline bool append(StrC str) { return GEN_NS string_append_strc(this, str); }
|
||||
forceinline bool append(const String other) { return GEN_NS string_append_string(this, other); }
|
||||
forceinline ssize avail_space() const { return GEN_NS string_avail_space(* this); }
|
||||
forceinline char* back() { return GEN_NS string_back(* this); }
|
||||
forceinline bool contains(StrC substring) const { return GEN_NS string_contains_strc(* this, substring); }
|
||||
forceinline bool contains(String const& substring) const { return GEN_NS string_contains_string(* this, substring); }
|
||||
forceinline ssize capacity() const { return GEN_NS capacity(* this); }
|
||||
forceinline void clear() { GEN_NS clear(* this); }
|
||||
forceinline void clear() { GEN_NS clear(* this); }
|
||||
forceinline String duplicate(AllocatorInfo allocator) const { return GEN_NS duplicate(* this, allocator); }
|
||||
forceinline void free() { GEN_NS free(this); }
|
||||
forceinline void free() { GEN_NS free(this); }
|
||||
forceinline bool is_equal(String const& other) const { return GEN_NS are_equal(* this, other); }
|
||||
forceinline bool is_equal(StrC other) const { return GEN_NS are_equal(* this, other); }
|
||||
forceinline ssize length() const { return GEN_NS length(* this); }
|
||||
forceinline b32 starts_with(StrC substring) const { return GEN_NS starts_with(* this, substring); }
|
||||
forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(* this, substring); }
|
||||
forceinline void skip_line() { GEN_NS skip_line(* this); }
|
||||
forceinline void strip_space() { GEN_NS strip_space(* this); }
|
||||
forceinline void skip_line() { GEN_NS skip_line(* this); }
|
||||
forceinline void strip_space() { GEN_NS strip_space(* this); }
|
||||
forceinline StrC to_strc() { return { length(), Data}; }
|
||||
forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); }
|
||||
forceinline void trim_space() { GEN_NS trim_space(* this); }
|
||||
forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); }
|
||||
forceinline void trim_space() { GEN_NS trim_space(* this); }
|
||||
forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(* this); }
|
||||
forceinline StringHeader& get_header() { return * GEN_NS get_header(* this); }
|
||||
|
||||
@ -247,37 +263,47 @@ struct String
|
||||
};
|
||||
#endif
|
||||
|
||||
inline char* begin(String str) { return ((char*) str); }
|
||||
inline char* end (String str) { return ((char*) str + length(str)); }
|
||||
inline char* next (String str, char* iter) { return ((char*) iter + 1); }
|
||||
GEN_API_C_BEGIN
|
||||
forceinline char* string_begin(String str) { return ((char*) str); }
|
||||
forceinline char* string_end (String str) { return ((char*) str + string_length(str)); }
|
||||
forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); }
|
||||
GEN_API_C_END
|
||||
|
||||
#if GEN_SUPPORT_CPP_REFERENCES
|
||||
inline bool make_space_for(String& str, char const* to_append, ssize add_len);
|
||||
inline bool append(String& str, char c);
|
||||
inline bool append(String& str, char const* str_to_append);
|
||||
inline bool append(String& str, char const* str_to_append, ssize length);
|
||||
inline bool append(String& str, StrC str_to_append);
|
||||
inline bool append(String& str, const String other);
|
||||
inline bool append_fmt(String& str, char const* fmt, ...);
|
||||
inline char& back(String& str);
|
||||
inline void clear(String& str);
|
||||
inline void free(String& str);
|
||||
#if GEN_COMPILER_CPP && 0
|
||||
forceinline char* begin(String str) { return ((char*) str); }
|
||||
forceinline char* end (String str) { return ((char*) str + string_length(str)); }
|
||||
forceinline char* next (String str, char* iter) { return ((char*) iter + 1); }
|
||||
#endif
|
||||
|
||||
inline
|
||||
#if GEN_SUPPORT_CPP_REFERENCES
|
||||
forceinline bool make_space_for(String& str, char const* to_append, ssize add_len);
|
||||
forceinline bool append(String& str, char c);
|
||||
forceinline bool append(String& str, char const* str_to_append);
|
||||
forceinline bool append(String& str, char const* str_to_append, ssize length);
|
||||
forceinline bool append(String& str, StrC str_to_append);
|
||||
forceinline bool append(String& str, const String other);
|
||||
forceinline bool append_fmt(String& str, char const* fmt, ...);
|
||||
forceinline char& back(String& str);
|
||||
forceinline void clear(String& str);
|
||||
forceinline void free(String& str);
|
||||
#endif
|
||||
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
forceinline
|
||||
usize string_grow_formula(usize value) {
|
||||
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
|
||||
return 4 * value + 8;
|
||||
}
|
||||
|
||||
inline
|
||||
String string_make(AllocatorInfo allocator, char const* str) {
|
||||
forceinline
|
||||
String string_make_c_str(AllocatorInfo allocator, char const* str) {
|
||||
ssize length = str ? str_len(str) : 0;
|
||||
return string_make_length(allocator, str, length);
|
||||
}
|
||||
|
||||
inline
|
||||
String string_make(AllocatorInfo allocator, StrC str) {
|
||||
forceinline
|
||||
String string_make_strc(AllocatorInfo allocator, StrC str) {
|
||||
return string_make_length(allocator, str.Ptr, str.Len);
|
||||
}
|
||||
|
||||
@ -285,10 +311,10 @@ inline
|
||||
String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
str_fmt_va(buf, buf_size, fmt, va);
|
||||
ssize res = str_fmt_va(buf, buf_size, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return string_make(allocator, buf);
|
||||
return string_make_length(allocator, buf, res);
|
||||
}
|
||||
|
||||
inline
|
||||
@ -299,52 +325,52 @@ String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||
ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return string_make(allocator, buf);
|
||||
return string_make_length(allocator, buf, res);
|
||||
}
|
||||
|
||||
inline
|
||||
String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue)
|
||||
{
|
||||
String result = string_make(allocator, "");
|
||||
String result = string_make_c_str(allocator, "");
|
||||
|
||||
for (ssize idx = 0; idx < num_parts; ++idx)
|
||||
{
|
||||
append(& result, parts[idx]);
|
||||
string_append_c_str(& result, parts[idx]);
|
||||
|
||||
if (idx < num_parts - 1)
|
||||
append(& result, glue);
|
||||
string_append_c_str(& result, glue);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
bool append(String* str, char c) {
|
||||
forceinline
|
||||
bool string_append_char(String* str, char c) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
return append( str, (char const*)& c, (ssize)1);
|
||||
return string_append_c_str_len( str, (char const*)& c, (ssize)1);
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool string_append_c_str(String* str, char const* str_to_append) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
return string_append_c_str_len(str, str_to_append, str_len(str_to_append));
|
||||
}
|
||||
|
||||
inline
|
||||
bool append(String* str, char const* str_to_append) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
return append(str, str_to_append, str_len(str_to_append));
|
||||
}
|
||||
|
||||
inline
|
||||
bool append(String* str, char const* str_to_append, ssize append_length)
|
||||
bool string_append_str_c_len(String* str, char const* str_to_append, ssize append_length)
|
||||
{
|
||||
GEN_ASSERT(str != nullptr);
|
||||
if (sptr(str_to_append) > 0)
|
||||
{
|
||||
ssize curr_len = length(* str);
|
||||
ssize curr_len = string_length(* str);
|
||||
|
||||
if ( ! make_space_for(str, str_to_append, append_length))
|
||||
if ( ! string_make_space_for(str, str_to_append, append_length))
|
||||
return false;
|
||||
|
||||
StringHeader* header = get_header(* str);
|
||||
StringHeader* header = string_get_header(* str);
|
||||
|
||||
char* Data = * str;
|
||||
mem_copy( Data + curr_len, str_to_append, append_length);
|
||||
@ -356,16 +382,16 @@ bool append(String* str, char const* str_to_append, ssize append_length)
|
||||
return str_to_append != nullptr;
|
||||
}
|
||||
|
||||
inline
|
||||
bool append(String* str, StrC str_to_append) {
|
||||
forceinline
|
||||
bool string_append_strc(String* str, StrC str_to_append) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
return append(str, str_to_append.Ptr, str_to_append.Len);
|
||||
return string_append_c_str_len(str, str_to_append.Ptr, str_to_append.Len);
|
||||
}
|
||||
|
||||
inline
|
||||
bool append(String* str, String const other) {
|
||||
forceinline
|
||||
bool string_append_string(String* str, String const other) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
return append(str, (char const*)other, length(other));
|
||||
return string_append_c_str_len(str, (char const*)other, string_length(other));
|
||||
}
|
||||
|
||||
bool append_fmt(String* str, char const* fmt, ...) {
|
||||
@ -378,16 +404,16 @@ bool append_fmt(String* str, char const* fmt, ...) {
|
||||
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
||||
va_end(va);
|
||||
|
||||
return append(str, (char const*)buf, res);
|
||||
return string_append_c_str_len(str, (char const*)buf, res);
|
||||
}
|
||||
|
||||
inline
|
||||
bool are_equal(String const lhs, String const rhs)
|
||||
bool string_are_equal_string(String const lhs, String const rhs)
|
||||
{
|
||||
if (length(lhs) != length(rhs))
|
||||
if (string_length(lhs) != string_length(rhs))
|
||||
return false;
|
||||
|
||||
for (ssize idx = 0; idx < length(lhs); ++idx)
|
||||
for (ssize idx = 0; idx < string_length(lhs); ++idx)
|
||||
if (lhs[idx] != rhs[idx])
|
||||
return false;
|
||||
|
||||
@ -395,27 +421,27 @@ bool are_equal(String const lhs, String const rhs)
|
||||
}
|
||||
|
||||
inline
|
||||
bool are_equal(String const lhs, StrC rhs)
|
||||
bool string_are_equal_strc(String const lhs, StrC rhs)
|
||||
{
|
||||
if (length(lhs) != (rhs.Len))
|
||||
if (string_length(lhs) != (rhs.Len))
|
||||
return false;
|
||||
|
||||
for (ssize idx = 0; idx < length(lhs); ++idx)
|
||||
for (ssize idx = 0; idx < string_length(lhs); ++idx)
|
||||
if (lhs[idx] != rhs.Ptr[idx])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
forceinline
|
||||
ssize avail_space(String const str) {
|
||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||
return header->Capacity - header->Length;
|
||||
}
|
||||
|
||||
inline
|
||||
forceinline
|
||||
char* back(String* str) {
|
||||
return & (*str)[length(* str) - 1];
|
||||
return & (*str)[string_length(* str) - 1];
|
||||
}
|
||||
|
||||
inline
|
||||
@ -431,7 +457,7 @@ bool contains(String const str, StrC substring)
|
||||
|
||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||
{
|
||||
if (str_compare(str + idx, substring.Ptr, sub_len) == 0)
|
||||
if (str_compare_len(str + idx, substring.Ptr, sub_len) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -439,67 +465,67 @@ bool contains(String const str, StrC substring)
|
||||
}
|
||||
|
||||
inline
|
||||
bool contains(String const str, String const substring)
|
||||
bool string_contains_string(String const str, String const substring)
|
||||
{
|
||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||
|
||||
if (length(substring) > header->Length)
|
||||
if (string_length(substring) > header->Length)
|
||||
return false;
|
||||
|
||||
ssize main_len = header->Length;
|
||||
ssize sub_len = length(substring);
|
||||
ssize sub_len = string_length(substring);
|
||||
|
||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||
{
|
||||
if (str_compare(str + idx, substring, sub_len) == 0)
|
||||
if (str_compare_len(str + idx, substring, sub_len) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline
|
||||
ssize capacity(String const str) {
|
||||
forceinline
|
||||
ssize string_capacity(String const str) {
|
||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||
return header->Capacity;
|
||||
}
|
||||
|
||||
inline
|
||||
void clear(String str) {
|
||||
get_header(str)->Length = 0;
|
||||
forceinline
|
||||
void string_clear(String str) {
|
||||
string_get_header(str)->Length = 0;
|
||||
}
|
||||
|
||||
inline
|
||||
String duplicate(String const str, AllocatorInfo allocator) {
|
||||
return string_make_length(allocator, str, length(str));
|
||||
forceinline
|
||||
String string_duplicate(String const str, AllocatorInfo allocator) {
|
||||
return string_make_length(allocator, str, string_length(str));
|
||||
}
|
||||
|
||||
inline
|
||||
void free(String* str) {
|
||||
forceinline
|
||||
void string_free(String* str) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
if (! (* str))
|
||||
return;
|
||||
|
||||
StringHeader* header = get_header(* str);
|
||||
GEN_NS free(header->Allocator, header);
|
||||
StringHeader* header = string_get_header(* str);
|
||||
allocator_free(header->Allocator, header);
|
||||
}
|
||||
|
||||
inline
|
||||
StringHeader* get_header(String str) {
|
||||
forceinline
|
||||
StringHeader* string_get_header(String str) {
|
||||
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader));
|
||||
}
|
||||
|
||||
inline
|
||||
ssize length(String const str)
|
||||
forceinline
|
||||
ssize string_length(String const str)
|
||||
{
|
||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||
return header.Length;
|
||||
}
|
||||
|
||||
inline
|
||||
bool make_space_for(String* str, char const* to_append, ssize add_len)
|
||||
bool string_make_space_for(String* str, char const* to_append, ssize add_len)
|
||||
{
|
||||
ssize available = avail_space(* str);
|
||||
ssize available = string_avail_space(* str);
|
||||
|
||||
if (available >= add_len) {
|
||||
return true;
|
||||
@ -510,12 +536,12 @@ bool make_space_for(String* str, char const* to_append, ssize add_len)
|
||||
void* ptr;
|
||||
void* new_ptr;
|
||||
|
||||
AllocatorInfo allocator = get_header(* str)->Allocator;
|
||||
AllocatorInfo allocator = string_get_header(* str)->Allocator;
|
||||
StringHeader* header = nullptr;
|
||||
|
||||
new_len = string_grow_formula(length(* str) + add_len);
|
||||
ptr = get_header(* str);
|
||||
old_size = size_of(StringHeader) + length(* str) + 1;
|
||||
new_len = string_grow_formula(string_length(* str) + add_len);
|
||||
ptr = string_get_header(* str);
|
||||
old_size = size_of(StringHeader) + string_length(* str) + 1;
|
||||
new_size = size_of(StringHeader) + new_len + 1;
|
||||
|
||||
new_ptr = resize(allocator, ptr, old_size, new_size);
|
||||
@ -534,26 +560,26 @@ bool make_space_for(String* str, char const* to_append, ssize add_len)
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
b32 starts_with(String const str, StrC substring) {
|
||||
if (substring.Len > length(str))
|
||||
forceinline
|
||||
b32 string_starts_with_strc(String const str, StrC substring) {
|
||||
if (substring.Len > string_length(str))
|
||||
return false;
|
||||
|
||||
b32 result = str_compare(str, substring.Ptr, substring.Len) == 0;
|
||||
b32 result = str_compare_len(str, substring.Ptr, substring.Len) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
b32 starts_with(String const str, String substring) {
|
||||
if (length(substring) > length(str))
|
||||
forceinline
|
||||
b32 string_starts_with_string(String const str, String substring) {
|
||||
if (string_length(substring) > string_length(str))
|
||||
return false;
|
||||
|
||||
b32 result = str_compare(str, substring, length(substring) - 1) == 0;
|
||||
b32 result = str_compare_len(str, substring, string_length(substring) - 1) == 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
void skip_line(String str)
|
||||
void string_skip_line(String str)
|
||||
{
|
||||
#define current (*scanner)
|
||||
char* scanner = str;
|
||||
@ -569,7 +595,7 @@ void skip_line(String str)
|
||||
|
||||
mem_move((char*)str, scanner, new_length);
|
||||
|
||||
StringHeader* header = get_header(str);
|
||||
StringHeader* header = string_get_header(str);
|
||||
header->Length = new_length;
|
||||
#undef current
|
||||
}
|
||||
@ -593,12 +619,12 @@ void strip_space(String str)
|
||||
write_pos[0] = '\0'; // Null-terminate the modified string
|
||||
|
||||
// Update the length if needed
|
||||
get_header(str)->Length = write_pos - str;
|
||||
string_get_header(str)->Length = write_pos - str;
|
||||
}
|
||||
|
||||
inline
|
||||
StrC to_strc(String str) {
|
||||
return { length(str), (char const*)str };
|
||||
forceinline
|
||||
StrC string_to_strc(String str) {
|
||||
return { string_length(str), (char const*)str };
|
||||
}
|
||||
|
||||
inline
|
||||
@ -607,7 +633,7 @@ void trim(String str, char const* cut_set)
|
||||
ssize len = 0;
|
||||
|
||||
char* start_pos = str;
|
||||
char* end_pos = scast(char*, str) + length(str) - 1;
|
||||
char* end_pos = scast(char*, str) + string_length(str) - 1;
|
||||
|
||||
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
|
||||
start_pos++;
|
||||
@ -622,10 +648,10 @@ void trim(String str, char const* cut_set)
|
||||
|
||||
str[len] = '\0';
|
||||
|
||||
get_header(str)->Length = len;
|
||||
string_get_header(str)->Length = len;
|
||||
}
|
||||
|
||||
inline
|
||||
forceinline
|
||||
void trim_space(String str) {
|
||||
trim(str, " \t\r\n\v\f");
|
||||
}
|
||||
@ -634,30 +660,31 @@ inline
|
||||
String visualize_whitespace(String const str)
|
||||
{
|
||||
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
|
||||
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
|
||||
String result = string_make_reserve(header->Allocator, string_length(str) * 2); // Assume worst case for space requirements.
|
||||
|
||||
foreach (char*, c, str) switch ( * c )
|
||||
for (char const* c = string_begin(str); c != string_end(str); c = string_next(str, c))
|
||||
switch ( * c )
|
||||
{
|
||||
case ' ':
|
||||
append(& result, txt("·"));
|
||||
string_append_strc(& result, txt("·"));
|
||||
break;
|
||||
case '\t':
|
||||
append(& result, txt("→"));
|
||||
string_append_strc(& result, txt("→"));
|
||||
break;
|
||||
case '\n':
|
||||
append(& result, txt("↵"));
|
||||
string_append_strc(& result, txt("↵"));
|
||||
break;
|
||||
case '\r':
|
||||
append(& result, txt("⏎"));
|
||||
string_append_strc(& result, txt("⏎"));
|
||||
break;
|
||||
case '\v':
|
||||
append(& result, txt("⇕"));
|
||||
string_append_strc(& result, txt("⇕"));
|
||||
break;
|
||||
case '\f':
|
||||
append(& result, txt("⌂"));
|
||||
string_append_strc(& result, txt("⌂"));
|
||||
break;
|
||||
default:
|
||||
append(& result, c);
|
||||
string_append_char(& result, * c);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -670,47 +697,50 @@ struct String_POD {
|
||||
};
|
||||
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
|
||||
|
||||
inline
|
||||
StrC duplicate(StrC str, AllocatorInfo allocator) {
|
||||
forceinline
|
||||
StrC strc_duplicate(StrC str, AllocatorInfo allocator) {
|
||||
String result = string_make_length(allocator, str.Ptr, str.Len);
|
||||
return { get_header(result)->Length, result };
|
||||
return { string_get_header(result)->Length, result };
|
||||
}
|
||||
|
||||
inline
|
||||
StrC visualize_whitespace(StrC str, AllocatorInfo allocator)
|
||||
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator)
|
||||
{
|
||||
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
|
||||
foreach (char const*, c, str) switch ( * c )
|
||||
for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c))
|
||||
switch ( * c )
|
||||
{
|
||||
case ' ':
|
||||
append(& result, txt("·"));
|
||||
string_append_strc(& result, txt("·"));
|
||||
break;
|
||||
case '\t':
|
||||
append(& result, txt("→"));
|
||||
string_append_strc(& result, txt("→"));
|
||||
break;
|
||||
case '\n':
|
||||
append(& result, txt("↵"));
|
||||
string_append_strc(& result, txt("↵"));
|
||||
break;
|
||||
case '\r':
|
||||
append(& result, txt("⏎"));
|
||||
string_append_strc(& result, txt("⏎"));
|
||||
break;
|
||||
case '\v':
|
||||
append(& result, txt("⇕"));
|
||||
string_append_strc(& result, txt("⇕"));
|
||||
break;
|
||||
case '\f':
|
||||
append(& result, txt("⌂"));
|
||||
string_append_strc(& result, txt("⌂"));
|
||||
break;
|
||||
default:
|
||||
append(& result, c);
|
||||
string_append_char(& result, * c);
|
||||
break;
|
||||
}
|
||||
return to_strc(result);
|
||||
}
|
||||
return string_to_strc(result);
|
||||
}
|
||||
|
||||
// Represents strings cached with the string table.
|
||||
// Should never be modified, if changed string is desired, cache_string( str ) another.
|
||||
typedef StrC StringCached;
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
||||
typedef HashTable<StringCached> StringTable;
|
||||
#pragma endregion Strings
|
||||
|
Reference in New Issue
Block a user