34#if !REX_PLATFORM_WIN32
38namespace rex::string {
47 return _stricmp(string1, string2);
49 return strcasecmp(string1, string2);
61 return _strnicmp(string1, string2, count);
63 return strncasecmp(string1, string2, count);
69template <
typename CharT>
70inline constexpr CharT kWhitespaceChars[] = {
static_cast<CharT
>(
' '),
static_cast<CharT
>(
'\t'),
71 static_cast<CharT
>(
'\r'),
static_cast<CharT
>(
'\n')};
76template <
typename CharT>
77inline constexpr std::basic_string_view<CharT>
kWhitespaceOf{detail::kWhitespaceChars<CharT>, 4};
87template <
typename CharT>
90 auto start = sv.find_first_not_of(chars);
91 return start == std::basic_string_view<CharT>::npos ? std::basic_string_view<CharT>{}
100template <
typename CharT>
103 auto end = sv.find_last_not_of(chars);
104 return end == std::basic_string_view<CharT>::npos ? std::basic_string_view<CharT>{}
105 : sv.substr(0, end + 1);
113template <
typename CharT>
114inline std::basic_string_view<CharT>
Trim(
142inline std::string_view
Trim(std::string_view sv, std::string_view chars =
kWhitespace) {
152 return std::string(
Trim(sv, chars));
161#if REX_PLATFORM_WIN32
162 return _strdup(source);
164 return strdup(source);
174inline size_t CopyTruncating(
char* dest,
const std::string_view source,
size_t dest_buffer_count) {
175 if (!dest_buffer_count) {
178 size_t chars_copied = std::min(source.size(), dest_buffer_count -
static_cast<size_t>(1));
179 std::memcpy(dest, source.data(), chars_copied);
180 dest[chars_copied] =
'\0';
191 size_t dest_buffer_count) {
192 if (!dest_buffer_count) {
195 size_t chars_copied = std::min(source.size(), dest_buffer_count -
static_cast<size_t>(1));
196 std::memcpy(dest, source.data(), chars_copied *
sizeof(
char16_t));
197 dest[chars_copied] = u
'\0';
208 size_t dest_buffer_count) {
209 if (!dest_buffer_count) {
212 size_t chars_copied = std::min(source.size(), dest_buffer_count -
static_cast<size_t>(1));
213 const std::u16string_view head = source.substr(0, chars_copied);
215 dest[chars_copied] = u
'\0';
226 size_t dest_buffer_count) {
227 if (!dest_buffer_count) {
230 size_t chars_copied = std::min(source.size(), dest_buffer_count);
231 std::memcpy(dest, source.data(), chars_copied);
271 const std::string_view needles,
272 bool remove_empty =
false);
281REX_API bool utf8_equal_case(
const std::string_view left,
const std::string_view right);
296 const std::string_view needles);
304 const std::string_view needles);
312 const std::string_view needle);
320 const std::string_view needle);
461 void Append(
const char* value);
463 void Append(
const std::string_view value);
470 template <
typename... Args>
471 void AppendFormat(std::format_string<const Args&...> format,
const Args&... args) {
472 Append(std::format(format, args...));
482 void AppendBytes(
const u8* buffer,
size_t length);
484 std::string ToString();
497 void Grow(
size_t additional_length);
499 char* buffer_ =
nullptr;
501 size_t buffer_capacity_ = 0;
506struct StringKeyBase {
508 std::variant<std::string, std::string_view> value_;
511 explicit StringKeyBase(
const std::string_view value) : value_(value) {}
512 explicit StringKeyBase(std::string value) : value_(std::move(value)) {}
514 std::string_view GetView()
const {
515 if (
const auto* owned = std::get_if<std::string>(&value_)) {
518 const auto* borrowed = std::get_if<std::string_view>(&value_);
519 return borrowed ? *borrowed : std::string_view();
529 explicit StringKey(
const std::string_view value) : StringKeyBase(value) {}
532 explicit StringKey(std::string value) : StringKeyBase(std::move(value)) {}
549 size_t operator()(
const StringKey& t)
const {
return t.
hash(); }
574 return rex::string::utf8_equal_case(other.GetView(), GetView());
593struct hash<
rex::string::StringKey> {
598struct hash<
rex::string::StringKeyIgnoreCase> {
void Append(char c, size_t count)
void AppendFormat(std::format_string< const Args &... > format, const Args &... args)
Definition text.h:471
void AppendVarargs(const char *format, va_list args)
StringBuffer(size_t initial_capacity=0)
std::string_view ToStringView() const
std::vector< u8 > ToBytes() const
size_t GetLength() const
Definition text.h:451
char * GetBuffer() const
Definition text.h:448
void copy_and_swap(T *dest, const T *src, size_t count)
Definition endian.h:98
static StringKeyIgnoreCase Create(std::string value)
Definition text.h:568
bool operator==(const StringKeyIgnoreCase &other) const
Definition text.h:573
static StringKeyIgnoreCase Create(const std::string_view value)
Definition text.h:563
StringKeyIgnoreCase(const std::string_view value)
Definition text.h:557
StringKeyIgnoreCase(std::string value)
Definition text.h:560
size_t hash() const
Definition text.h:582
static StringKey Create(std::string value)
Definition text.h:538
static StringKey Create(const std::string_view value)
Definition text.h:535
size_t hash() const
Definition text.h:546
StringKey(const std::string_view value)
Definition text.h:529
StringKey(std::string value)
Definition text.h:532
bool operator==(const StringKey &other) const
Definition text.h:541
bool utf8_equal_case_z(const std::string_view left, const std::string_view right)
size_t utf8_count(const std::string_view view)
size_t CopyTruncating(char *dest, const std::string_view source, size_t dest_buffer_count)
Definition text.h:174
std::string ShiftJISToUTF8(const std::string_view source)
std::string utf8_lower_ascii(const std::string_view view)
std::string ToUTF8(const std::u16string_view source)
std::string PathToUTF8(const std::filesystem::path &path)
constexpr std::basic_string_view< CharT > kWhitespaceOf
Definition text.h:77
std::basic_string_view< CharT > TrimLeft(std::basic_string_view< CharT > sv, std::basic_string_view< CharT > chars=kWhitespaceOf< CharT >)
Definition text.h:88
std::basic_string_view< CharT > Trim(std::basic_string_view< CharT > sv, std::basic_string_view< CharT > chars=kWhitespaceOf< CharT >)
Definition text.h:114
std::filesystem::path to_path(const std::string_view source)
constexpr std::string_view kWhitespace
Definition text.h:80
bool utf8_starts_with_case(const std::string_view haystack, const std::string_view needle)
size_t utf8_hash_fnv1a(const std::string_view view)
std::string_view::size_type utf8_find_any_of(const std::string_view haystack, const std::string_view needles)
bool utf8_starts_with(const std::string_view haystack, const std::string_view needle)
std::string_view::size_type utf8_find_any_of_case(const std::string_view haystack, const std::string_view needles)
i32 CompareIgnoreCase(const char *string1, const char *string2)
Definition text.h:45
std::u16string ToUTF16(const std::string_view source)
std::wstring ToWideString(const std::string_view source)
size_t CopyUnterminated(char *dest, const std::string_view source, size_t dest_buffer_count)
Definition text.h:225
bool utf8_ends_with(const std::string_view haystack, const std::string_view needle)
std::u16string PathToUTF16(const std::filesystem::path &path)
std::string utf8_upper_ascii(const std::string_view view)
size_t utf8_hash_fnv1a_case(const std::string_view view)
std::vector< std::string_view > utf8_split(const std::string_view haystack, const std::string_view needles, bool remove_empty=false)
std::string UTF8ToShiftJIS(const std::string_view source)
bool utf8_ends_with_case(const std::string_view haystack, const std::string_view needle)
char * Duplicate(const char *source)
Definition text.h:160
std::basic_string_view< CharT > TrimRight(std::basic_string_view< CharT > sv, std::basic_string_view< CharT > chars=kWhitespaceOf< CharT >)
Definition text.h:101
size_t CopyAndSwapTruncating(char16_t *dest, const std::u16string_view source, size_t dest_buffer_count)
Definition text.h:207
bool utf8_equal_z(const std::string_view left, const std::string_view right)
std::string_view::size_type utf8_find_first_of(const std::string_view haystack, const std::string_view needle)
std::string TrimString(std::string_view sv, std::string_view chars=kWhitespace)
Definition text.h:151
i32 CompareIgnoreCaseN(const char *string1, const char *string2, size_t count)
Definition text.h:59
std::string_view::size_type utf8_find_first_of_case(const std::string_view haystack, const std::string_view needle)
Integer types, byte order wrappers and size literals.