#pragma once API int64_t WideLength(char16_t *string); struct String16 { char16_t *data; int64_t len; String16() = default; String16(char16_t *s) : data(s), len(WideLength(s)) {} String16(char16_t *s, int64_t l) : data((char16_t *)s), len(l) {} String16(const char16_t *s) : data((char16_t *)s), len(WideLength((char16_t *)s)) {} String16(const char16_t *s, int64_t l) : data((char16_t *)s), len(l) {} char16_t &operator[](int64_t index) { Assert(index < len); return data[index]; } char16_t *begin() { return data; } char16_t *end() { return data + len; } struct ReverseIter { char16_t *data; String16 *arr; ReverseIter operator++(int) { ReverseIter ret = *this; data -= 1; return ret; } ReverseIter &operator++() { data -= 1; return *this; } char16_t &operator*() { return data[0]; } char16_t *operator->() { return data; } friend bool operator==(const ReverseIter &a, const ReverseIter &b) { return a.data == b.data; }; friend bool operator!=(const ReverseIter &a, const ReverseIter &b) { return a.data != b.data; }; ReverseIter begin() { return ReverseIter{arr->end() - 1, arr}; } ReverseIter end() { return ReverseIter{arr->begin() - 1, arr}; } }; ReverseIter reverse() { return {this->end() - 1, this}; } }; API char16_t ToLowerCase(char16_t a); API char16_t ToUpperCase(char16_t a); API bool IsWhitespace(char16_t w); API bool IsAlphabetic(char16_t a); API bool IsIdent(char16_t a); API bool IsDigit(char16_t a); API bool IsAlphanumeric(char16_t a); API bool IsSymbol(char16_t w); API bool IsNonWord(char16_t w); API bool IsWord(char16_t w); API bool IsBrace(char16_t c); API bool IsParen(char16_t c); API bool EndsWith(String16 a, String16 end, unsigned ignore_case = false); API bool StartsWith(String16 a, String16 start, unsigned ignore_case = false); API bool AreEqual(String16 a, String16 b, unsigned ignore_case = false); inline bool operator==(String16 a, String16 b) { return AreEqual(a, b); } inline bool operator!=(String16 a, String16 b) { return !AreEqual(a, b); } API String16 Trim(String16 string); API String16 TrimEnd(String16 string); API String16 Chop(String16 a, int64_t len); API String16 Skip(String16 a, int64_t len); API String16 GetPostfix(String16 a, int64_t len); API String16 GetPrefix(String16 a, int64_t len); API String16 GetSlice(String16 arr, int64_t first_index = 0, int64_t one_past_last_index = SLICE_LAST); API String16 CutLastSlash(String16 *s); API String16 ChopLastSlash(String16 s); API String16 ChopLastPeriod(String16 s); API String16 SkipToLastSlash(String16 s); API String16 SkipToLastPeriod(String16 s); API String16 CutPrefix(String16 *string, int64_t len); API String16 CutPostfix(String16 *string, int64_t len); // @todo: think about this API, for parsing, maybe redesign or something API String16 SkipIntEx(String16 *string); API Int SkipInt(String16 *string); API String16 SkipUntil(String16 *string, String16 str); API String16 SkipWhitespace(String16 *string); API String16 ChopNumberEx(String16 *string); API Int ChopNumber(String16 *string); API String16 Copy16(Allocator allocator, String16 string); API String16 Copy16(Allocator allocator, char16_t *string, int64_t len); API String16 Copy16(Allocator allocator, char *string); API void NormalizePathInPlace(String16 s); API String16 NormalizePath(Allocator allocator, String16 s); API String16 Format16V(Allocator allocator, const char *data, va_list args1); API String16 Format16(Allocator allocator, const char *data, ...); API bool Seek(String16 string, String16 find, int64_t *index_out = NULL, SeekFlag flags = SeekFlag_None); API Array Split(Allocator allocator, String16 string, String16 delimiter = u" "); API String16 Merge(Allocator allocator, Array list, String16 separator); API Int GetSize(Array array);