-
Notifications
You must be signed in to change notification settings - Fork 1
/
dqn_string.h
403 lines (349 loc) · 22.7 KB
/
dqn_string.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
#pragma once
#include "dqn.h"
/*
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// $$$$$$\ $$$$$$$$\ $$$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\
// $$ __$$\\__$$ __|$$ __$$\ \_$$ _|$$$\ $$ |$$ __$$\
// $$ / \__| $$ | $$ | $$ | $$ | $$$$\ $$ |$$ / \__|
// \$$$$$$\ $$ | $$$$$$$ | $$ | $$ $$\$$ |$$ |$$$$\
// \____$$\ $$ | $$ __$$< $$ | $$ \$$$$ |$$ |\_$$ |
// $$\ $$ | $$ | $$ | $$ | $$ | $$ |\$$$ |$$ | $$ |
// \$$$$$$ | $$ | $$ | $$ |$$$$$$\ $$ | \$$ |\$$$$$$ |
// \______/ \__| \__| \__|\______|\__| \__| \______/
//
// dqn_string.h -- UTF8/16 string manipulation
//
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// [$CSTR] Dqn_CStr8 -- C-string helpers
// [$STR8] Dqn_Str8 -- Pointer and length strings
// [$STRB] Dqn_Str8Builder -- Construct strings dynamically
// [$FSTR] Dqn_FStr8 -- Fixed-size strings
// [$CHAR] Dqn_Char -- Character ascii/digit.. helpers
// [$UTFX] Dqn_UTF -- Unicode helpers
//
////////////////////////////////////////////////////////////////////////////////////////////////////
*/
// NOTE: [$STR8] Dqn_Str8 //////////////////////////////////////////////////////////////////////////
struct Dqn_Str8Link
{
Dqn_Str8 string; // The string
Dqn_Str8Link *next; // The next string in the linked list
};
struct Dqn_Str16 // A pointer and length style string that holds slices to UTF16 bytes.
{
wchar_t *data; // The UTF16 bytes of the string
Dqn_usize size; // The number of characters in the string
#if defined(__cplusplus)
wchar_t const *begin() const { return data; } // Const begin iterator for range-for loops
wchar_t const *end () const { return data + size; } // Const end iterator for range-for loops
wchar_t *begin() { return data; } // Begin iterator for range-for loops
wchar_t *end () { return data + size; } // End iterator for range-for loops
#endif
};
struct Dqn_Str8BinarySplitResult
{
Dqn_Str8 lhs;
Dqn_Str8 rhs;
};
struct Dqn_Str8FindResult
{
bool found; // True if string was found. If false, the subsequent fields below are not set.
Dqn_usize index; // The index in the buffer where the found string starts
Dqn_Str8 match; // The matching string in the buffer that was searched
Dqn_Str8 match_to_end_of_buffer; // The substring containing the found string to the end of the buffer
Dqn_Str8 start_to_before_match; // The substring from the start of the buffer up until the found string, not including it
};
enum Dqn_Str8IsAll
{
Dqn_Str8IsAll_Digits,
Dqn_Str8IsAll_Hex,
};
enum Dqn_Str8EqCase
{
Dqn_Str8EqCase_Sensitive,
Dqn_Str8EqCase_Insensitive,
};
enum Dqn_Str8FindFlag
{
Dqn_Str8FindFlag_Digit = 1 << 0, // 0-9
Dqn_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
Dqn_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
Dqn_Str8FindFlag_Plus = 1 << 3, // +
Dqn_Str8FindFlag_Minus = 1 << 4, // -
Dqn_Str8FindFlag_AlphaNum = Dqn_Str8FindFlag_Alphabet | Dqn_Str8FindFlag_Digit,
};
enum Dqn_Str8SplitIncludeEmptyStrings
{
Dqn_Str8SplitIncludeEmptyStrings_No,
Dqn_Str8SplitIncludeEmptyStrings_Yes,
};
struct Dqn_Str8ToU64Result
{
bool success;
uint64_t value;
};
struct Dqn_Str8ToI64Result
{
bool success;
int64_t value;
};
// NOTE: [$FSTR] Dqn_FStr8 /////////////////////////////////////////////////////////////////////////
#if !defined(DQN_NO_FSTR8)
template <Dqn_usize N> struct Dqn_FStr8
{
char data[N+1];
Dqn_usize size;
char *begin() { return data; }
char *end () { return data + size; }
char const *begin() const { return data; }
char const *end () const { return data + size; }
};
#endif // !defined(DQN_NO_FSTR8)
struct Dqn_Str8Builder
{
Dqn_Arena *arena; // Allocator to use to back the string list
Dqn_Str8Link *head; // First string in the linked list of strings
Dqn_Str8Link *tail; // Last string in the linked list of strings
Dqn_usize string_size; // The size in bytes necessary to construct the current string
Dqn_usize count; // The number of links in the linked list of strings
};
// NOTE: [$CSTR] Dqn_CStr8 /////////////////////////////////////////////////////////////////////////
template <Dqn_usize N> constexpr Dqn_usize Dqn_CStr8_ArrayUCount (char const (&literal)[N]) { (void)literal; return N - 1; }
template <Dqn_usize N> constexpr Dqn_usize Dqn_CStr8_ArrayICount (char const (&literal)[N]) { (void)literal; return N - 1; }
DQN_API Dqn_usize Dqn_CStr8_FSize (DQN_FMT_ATTRIB char const *fmt, ...);
DQN_API Dqn_usize Dqn_CStr8_FVSize (DQN_FMT_ATTRIB char const *fmt, va_list args);
DQN_API Dqn_usize Dqn_CStr8_Size (char const *a);
DQN_API Dqn_usize Dqn_CStr16_Size (wchar_t const *a);
// NOTE: [$STR6] Dqn_Str16 /////////////////////////////////////////////////////////////////////////
#define DQN_STR16(string) Dqn_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1}
#define Dqn_Str16_HasData(string) ((string).data && (string).size)
#if defined(__cplusplus)
DQN_API bool operator== (Dqn_Str16 const &lhs, Dqn_Str16 const &rhs);
DQN_API bool operator!= (Dqn_Str16 const &lhs, Dqn_Str16 const &rhs);
#endif
// NOTE: [$STR8] Dqn_Str8 //////////////////////////////////////////////////////////////////////////
#define DQN_STR8(string) Dqn_Str8{(char *)(string), (sizeof(string) - 1)}
#define DQN_STR_FMT(string) (int)((string).size), (string).data
#define Dqn_Str8_Init(data, size) Dqn_Str8{(char *)(data), (size_t)(size)}
DQN_API Dqn_Str8 Dqn_Str8_InitCStr8 (char const *src);
#define Dqn_Str8_HasData(string) ((string).data && (string).size)
DQN_API bool Dqn_Str8_IsAll (Dqn_Str8 string, Dqn_Str8IsAll is_all);
DQN_API Dqn_Str8 Dqn_Str8_InitF (Dqn_Arena *arena, DQN_FMT_ATTRIB char const *fmt, ...);
DQN_API Dqn_Str8 Dqn_Str8_InitFV (Dqn_Arena *arena, DQN_FMT_ATTRIB char const *fmt, va_list args);
DQN_API Dqn_Str8 Dqn_Str8_Alloc (Dqn_Arena *arena, Dqn_usize size, Dqn_ZeroMem zero_mem);
DQN_API Dqn_Str8 Dqn_Str8_CopyCString (Dqn_Arena *arena, char const *string, Dqn_usize size);
DQN_API Dqn_Str8 Dqn_Str8_Copy (Dqn_Arena *arena, Dqn_Str8 string);
DQN_API Dqn_Str8 Dqn_Str8_Slice (Dqn_Str8 string, Dqn_usize offset, Dqn_usize size);
DQN_API Dqn_Str8 Dqn_Str8_Advance (Dqn_Str8 string, Dqn_usize amount);
DQN_API Dqn_Str8 Dqn_Str8_NextLine (Dqn_Str8 string);
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitArray (Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size);
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplit (Dqn_Str8 string, Dqn_Str8 find);
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitLastArray (Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size);
DQN_API Dqn_Str8BinarySplitResult Dqn_Str8_BinarySplitLast (Dqn_Str8 string, Dqn_Str8 find);
DQN_API Dqn_usize Dqn_Str8_Split (Dqn_Str8 string, Dqn_Str8 delimiter, Dqn_Str8 *splits, Dqn_usize splits_count, Dqn_Str8SplitIncludeEmptyStrings mode);
DQN_API Dqn_Slice<Dqn_Str8> Dqn_Str8_SplitAlloc (Dqn_Arena *arena, Dqn_Str8 string, Dqn_Str8 delimiter, Dqn_Str8SplitIncludeEmptyStrings mode);
DQN_API Dqn_Str8FindResult Dqn_Str8_FindStr8Array (Dqn_Str8 string, Dqn_Str8 const *find, Dqn_usize find_size);
DQN_API Dqn_Str8FindResult Dqn_Str8_FindStr8 (Dqn_Str8 string, Dqn_Str8 find);
DQN_API Dqn_Str8FindResult Dqn_Str8_Find (Dqn_Str8 string, uint32_t flags);
DQN_API Dqn_Str8 Dqn_Str8_Segment (Dqn_Arena *arena, Dqn_Str8 src, Dqn_usize segment_size, char segment_char);
DQN_API Dqn_Str8 Dqn_Str8_ReverseSegment (Dqn_Arena *arena, Dqn_Str8 src, Dqn_usize segment_size, char segment_char);
DQN_API bool Dqn_Str8_Eq (Dqn_Str8 lhs, Dqn_Str8 rhs, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API bool Dqn_Str8_EqInsensitive (Dqn_Str8 lhs, Dqn_Str8 rhs);
DQN_API bool Dqn_Str8_StartsWith (Dqn_Str8 string, Dqn_Str8 prefix, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API bool Dqn_Str8_StartsWithInsensitive (Dqn_Str8 string, Dqn_Str8 prefix);
DQN_API bool Dqn_Str8_EndsWith (Dqn_Str8 string, Dqn_Str8 prefix, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API bool Dqn_Str8_EndsWithInsensitive (Dqn_Str8 string, Dqn_Str8 prefix);
DQN_API bool Dqn_Str8_HasChar (Dqn_Str8 string, char ch);
DQN_API Dqn_Str8 Dqn_Str8_TrimPrefix (Dqn_Str8 string, Dqn_Str8 prefix, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API Dqn_Str8 Dqn_Str8_TrimSuffix (Dqn_Str8 string, Dqn_Str8 suffix, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API Dqn_Str8 Dqn_Str8_TrimAround (Dqn_Str8 string, Dqn_Str8 trim_string);
DQN_API Dqn_Str8 Dqn_Str8_TrimWhitespaceAround (Dqn_Str8 string);
DQN_API Dqn_Str8 Dqn_Str8_TrimByteOrderMark (Dqn_Str8 string);
DQN_API Dqn_Str8 Dqn_Str8_FileNameFromPath (Dqn_Str8 path);
DQN_API Dqn_Str8 Dqn_Str8_FileNameNoExtension (Dqn_Str8 path);
DQN_API Dqn_Str8 Dqn_Str8_FilePathNoExtension (Dqn_Str8 path);
DQN_API Dqn_Str8 Dqn_Str8_FileExtension (Dqn_Str8 path);
DQN_API Dqn_Str8ToU64Result Dqn_Str8_ToU64 (Dqn_Str8 string, char separator);
DQN_API Dqn_Str8ToI64Result Dqn_Str8_ToI64 (Dqn_Str8 string, char separator);
DQN_API Dqn_Str8 Dqn_Str8_Replace (Dqn_Str8 string, Dqn_Str8 find, Dqn_Str8 replace, Dqn_usize start_index, Dqn_Arena *arena, Dqn_Str8EqCase eq_case = Dqn_Str8EqCase_Sensitive);
DQN_API Dqn_Str8 Dqn_Str8_ReplaceInsensitive (Dqn_Str8 string, Dqn_Str8 find, Dqn_Str8 replace, Dqn_usize start_index, Dqn_Arena *arena);
DQN_API void Dqn_Str8_Remove (Dqn_Str8 *string, Dqn_usize offset, Dqn_usize size);
#if defined(__cplusplus)
DQN_API bool operator== (Dqn_Str8 const &lhs, Dqn_Str8 const &rhs);
DQN_API bool operator!= (Dqn_Str8 const &lhs, Dqn_Str8 const &rhs);
#endif
// NOTE: [$FSTR] Dqn_Str8Builder ///////////////////////////////////////////////////////////////////
DQN_API bool Dqn_Str8Builder_AppendRefArray (Dqn_Str8Builder *builder, Dqn_Slice<Dqn_Str8> string);
DQN_API bool Dqn_Str8Builder_AppendCopyArray(Dqn_Str8Builder *builder, Dqn_Slice<Dqn_Str8> string);
DQN_API bool Dqn_Str8Builder_AppendFV (Dqn_Str8Builder *builder, DQN_FMT_ATTRIB char const *fmt, va_list args);
DQN_API bool Dqn_Str8Builder_AppendF (Dqn_Str8Builder *builder, DQN_FMT_ATTRIB char const *fmt, ...);
DQN_API bool Dqn_Str8Builder_AppendRef (Dqn_Str8Builder *builder, Dqn_Str8 string);
DQN_API bool Dqn_Str8Builder_AppendCopy (Dqn_Str8Builder *builder, Dqn_Str8 string);
DQN_API Dqn_Str8 Dqn_Str8Builder_Build (Dqn_Str8Builder const *builder, Dqn_Arena *arena);
DQN_API Dqn_Str8 Dqn_Str8Builder_BuildCRT (Dqn_Str8Builder const *builder);
DQN_API Dqn_Slice<Dqn_Str8> Dqn_Str8Builder_BuildSlice (Dqn_Str8Builder const *builder, Dqn_Arena *arena);
DQN_API void Dqn_Str8Builder_PrintF (Dqn_Str8Builder const *builder);
// NOTE: [$FSTR] Dqn_FStr8 //////////////////////////////////////////////////////////////////////
#if !defined(DQN_NO_FSTR8)
template <Dqn_usize N> Dqn_FStr8<N> Dqn_FStr8_InitF (DQN_FMT_ATTRIB char const *fmt, ...);
template <Dqn_usize N> Dqn_usize Dqn_FStr8_Max (Dqn_FStr8<N> const *string);
template <Dqn_usize N> void Dqn_FStr8_Clear (Dqn_FStr8<N> *string);
template <Dqn_usize N> bool Dqn_FStr8_AppendFV (Dqn_FStr8<N> *string, DQN_FMT_ATTRIB char const *fmt, va_list va);
template <Dqn_usize N> bool Dqn_FStr8_AppendF (Dqn_FStr8<N> *string, DQN_FMT_ATTRIB char const *fmt, ...);
template <Dqn_usize N> bool Dqn_FStr8_AppendCStr8 (Dqn_FStr8<N> *string, char const *value, Dqn_usize size);
template <Dqn_usize N> bool Dqn_FStr8_Append (Dqn_FStr8<N> *string, Dqn_Str8 value);
template <Dqn_usize N> Dqn_Str8 Dqn_FStr8_ToStr8 (Dqn_FStr8<N> const *string);
template <Dqn_usize N> bool Dqn_FStr8_Eq (Dqn_FStr8<N> const *lhs, Dqn_FStr8<N> const *rhs, Dqn_Str8EqCase eq_case);
template <Dqn_usize N> bool Dqn_FStr8_EqStr8 (Dqn_FStr8<N> const *lhs, Dqn_Str8 rhs, Dqn_Str8EqCase eq_case);
template <Dqn_usize N> bool Dqn_FStr8_EqInsensitive (Dqn_FStr8<N> const *lhs, Dqn_FStr8<N> const *rhs);
template <Dqn_usize N> bool Dqn_FStr8_EqStr8Insensitive (Dqn_FStr8<N> const *lhs, Dqn_Str8 rhs);
template <Dqn_usize A, Dqn_usize B> bool Dqn_FStr8_EqFStr8 (Dqn_FStr8<A> const *lhs, Dqn_FStr8<B> const *rhs, Dqn_Str8EqCase eq_case);
template <Dqn_usize A, Dqn_usize B> bool Dqn_FStr8_EqFStr8Insensitive (Dqn_FStr8<A> const *lhs, Dqn_FStr8<B> const *rhs);
template <Dqn_usize N> bool operator== (Dqn_FStr8<N> const &lhs, Dqn_FStr8<N> const &rhs);
template <Dqn_usize N> bool operator!= (Dqn_FStr8<N> const &lhs, Dqn_FStr8<N> const &rhs);
#endif // !defined(DQN_NO_FSTR8)
// NOTE: [$CHAR] Dqn_Char //////////////////////////////////////////////////////////////////////////
struct Dqn_CharHexToU8
{
bool success;
uint8_t value;
};
DQN_API bool Dqn_Char_IsAlphabet (char ch);
DQN_API bool Dqn_Char_IsDigit (char ch);
DQN_API bool Dqn_Char_IsAlphaNum (char ch);
DQN_API bool Dqn_Char_IsWhitespace (char ch);
DQN_API bool Dqn_Char_IsHex (char ch);
DQN_API Dqn_CharHexToU8 Dqn_Char_HexToU8 (char ch);
DQN_API char Dqn_Char_ToHex (char ch);
DQN_API char Dqn_Char_ToHexUnchecked (char ch);
DQN_API char Dqn_Char_ToLower (char ch);
// NOTE: [$UTFX] Dqn_UTF ///////////////////////////////////////////////////////////////////////////
DQN_API int Dqn_UTF8_EncodeCodepoint (uint8_t utf8[4], uint32_t codepoint);
DQN_API int Dqn_UTF16_EncodeCodepoint (uint16_t utf16[2], uint32_t codepoint);
#if !defined(DQN_NO_FSTR8)
// NOTE: [$FSTR] Dqn_FStr8 /////////////////////////////////////////////////////////////////////////
template <Dqn_usize N> Dqn_FStr8<N> Dqn_FStr8_InitF(DQN_FMT_ATTRIB char const *fmt, ...)
{
Dqn_FStr8<N> result = {};
if (fmt) {
va_list args;
va_start(args, fmt);
Dqn_FStr8_AppendFV(&result, fmt, args);
va_end(args);
}
return result;
}
template <Dqn_usize N> Dqn_usize Dqn_FStr8_Max(Dqn_FStr8<N> const *)
{
Dqn_usize result = N;
return result;
}
template <Dqn_usize N> void Dqn_FStr8_Clear(Dqn_FStr8<N> *string)
{
*string = {};
}
template <Dqn_usize N> bool Dqn_FStr8_AppendFV(Dqn_FStr8<N> *string, DQN_FMT_ATTRIB char const *fmt, va_list args)
{
bool result = false;
if (!string || !fmt)
return result;
Dqn_usize require = Dqn_CStr8_FVSize(fmt, args) + 1 /*null_terminate*/;
Dqn_usize space = (N + 1) - string->size;
result = require <= space;
string->size += DQN_VSNPRINTF(string->data + string->size, DQN_CAST(int)space, fmt, args);
// NOTE: snprintf returns the required size of the format string
// irrespective of if there's space or not.
string->size = DQN_MIN(string->size, N);
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_AppendF(Dqn_FStr8<N> *string, DQN_FMT_ATTRIB char const *fmt, ...)
{
bool result = false;
if (!string || !fmt)
return result;
va_list args;
va_start(args, fmt);
result = Dqn_FStr8_AppendFV(string, fmt, args);
va_end(args);
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_AppendCStr8(Dqn_FStr8<N> *string, char const *src, Dqn_usize size)
{
DQN_ASSERT(string->size <= N);
bool result = false;
if (!string || !src || size == 0 || string->size >= N)
return result;
Dqn_usize space = N - string->size;
result = size <= space;
DQN_MEMCPY(string->data + string->size, src, DQN_MIN(space, size));
string->size = DQN_MIN(string->size + size, N);
string->data[string->size] = 0;
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_Append(Dqn_FStr8<N> *string, Dqn_Str8 src)
{
bool result = Dqn_FStr8_AppendCStr8(string, src.data, src.size);
return result;
}
template <Dqn_usize N> Dqn_Str8 Dqn_FStr8_ToStr8(Dqn_FStr8<N> const *string)
{
Dqn_Str8 result = {};
if (!string || string->size <= 0)
return result;
result.data = DQN_CAST(char *)string->data;
result.size = string->size;
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_Eq(Dqn_FStr8<N> const *lhs, Dqn_FStr8<N> const *rhs, Dqn_Str8EqCase eq_case)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
Dqn_Str8 rhs_s8 = Dqn_FStr8_ToStr8(rhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs_s8, eq_case);
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_EqStr8(Dqn_FStr8<N> const *lhs, Dqn_Str8 rhs, Dqn_Str8EqCase eq_case)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs, eq_case);
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_EqInsensitive(Dqn_FStr8<N> const *lhs, Dqn_FStr8<N> const *rhs)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
Dqn_Str8 rhs_s8 = Dqn_FStr8_ToStr8(rhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs_s8, Dqn_Str8EqCase_Insensitive);
return result;
}
template <Dqn_usize N> bool Dqn_FStr8_EqStr8Insensitive(Dqn_FStr8<N> const *lhs, Dqn_Str8 rhs)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs, Dqn_Str8EqCase_Insensitive);
return result;
}
template <Dqn_usize A, Dqn_usize B> bool Dqn_FStr8_EqFStr8(Dqn_FStr8<A> const *lhs, Dqn_FStr8<B> const *rhs, Dqn_Str8EqCase eq_case)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
Dqn_Str8 rhs_s8 = Dqn_FStr8_ToStr8(rhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs_s8, eq_case);
return result;
}
template <Dqn_usize A, Dqn_usize B> bool Dqn_FStr8_EqFStr8Insensitive(Dqn_FStr8<A> const *lhs, Dqn_FStr8<B> const *rhs)
{
Dqn_Str8 lhs_s8 = Dqn_FStr8_ToStr8(lhs);
Dqn_Str8 rhs_s8 = Dqn_FStr8_ToStr8(rhs);
bool result = Dqn_Str8_Eq(lhs_s8, rhs_s8, Dqn_Str8EqCase_Insensitive);
return result;
}
template <Dqn_usize N> bool operator==(Dqn_FStr8<N> const &lhs, Dqn_FStr8<N> const &rhs)
{
bool result = Dqn_FStr8_Eq(&lhs, &rhs, Dqn_Str8EqCase_Sensitive);
return result;
}
template <Dqn_usize N> bool operator!=(Dqn_FStr8<N> const &lhs, Dqn_FStr8<N> const &rhs)
{
bool result = !(lhs == rhs);
return result;
}
#endif // !defined(DQN_NO_FSTR8)