#pragma once // #TODO: #strings: // [ ] Always null-terminate strings! // [ ] How do I accept variadic arguments of any type to my print function? // [ ] Need to sort out how formatted strings and string builders are allocated // [ ] Separate functions for temp alloc (tprint??) // [ ] API needs to be completely overhauled // [ ] I should also put path manipulation here or in a separate file. struct string { s64 count; u8* data; // Construct from a string literal or C-string string () { // default constructor count = 0; data = nullptr; } string (char* cstr) { count = strlen(cstr); data = (u8*)cstr; } string (s64 _count, char* str) { count = _count; data = (u8*)str; } string (s64 _count, u8* str) { count = _count; data = str; } bool operator==(const string& other) const { string first_string = *this; string second_string = other; // return strings_match(*this, other); if (first_string.count != second_string.count) { return false; } for (s64 i = 0; i < first_string.count; i += 1) { if (first_string.data[i] != second_string.data[i]) { return false; } } return true; } }; struct wstring { s64 count; u16* data; wstring () { // default constructor count = 0; data = nullptr; } }; // ~Keep these API bool is_valid (string s); bool is_c_string (string s); u8* to_c_string (string s); // #allocates string copy_string (string s); // #allocates, returned string is #null-terminated. string copy_string (char* c_string); // #allocates, returned string is #null-terminated. string to_string (ArrayView str); void free(string& s); // String manipulation & comparison force_inline string string_view (string s, s64 start_index, s64 view_count); string copy_string_view (string s, s64 start_index, s64 view_count); bool strings_match (string first_string, string second_string); // #Unicode string wide_to_utf8 (u16* source, s32 length); // wstring utf8_to_wide (string source); TODO. string format_string (char* format, ...); // Parsing stuff: // is_white_space(char: u8) // advance // eat_spaces // Print stuff // s64 string_to_int (string v, s32 base = 10, s64* remainder=nullptr); // // #string_builder // #limitations This won't be as fast as Jon's String_Builder in jai because we're backing it with an // Arena, which requires a variable number of cycles depending on if our process has // memory available already. It also has a max capacity depending on what Arena_Reserve we choose. // That being said, the implementation is much simpler. typedef ArenaArray String_Builder; // struct String_Builder force_inline String_Builder* new_string_builder (Arena_Reserve new_reserve=Arena_Reserve::Size_64K); force_inline void append (String_Builder* sb, string s); void append (String_Builder* sb, ArrayView strings); internal force_inline void append_no_add (String_Builder* sb, string s); // for appending null terminators, does not increment count. void print_to_builder (String_Builder* sb, string format, ...); void print_to_builder (String_Builder* sb, string format, va_list args); string string_view (String_Builder* sb); internal force_inline void reset_string_builder (String_Builder* sb); force_inline string builder_to_string (String_Builder* sb); // returns string view internal force_inline void free_string_builder (String_Builder* sb);