-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlite_string.h
367 lines (246 loc) · 13.9 KB
/
lite_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
// Copyright (c) 2024 Ian Duncan
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
// Library version
#define _lite_string_major 1L ///< LiteString major version.
#define _lite_string_minor 0L ///< LiteString minor version.
#define _lite_string_patch 0L ///< LiteString patch version.
/// The LiteString version as a single integer.
#define _lite_string_version (_lite_string_major * 10000L + _lite_string_minor * 100L + _lite_string_patch)
// Check version compatibility requirements
#ifdef LITE_STRING_REQUIRE_MIN_VERSION
#if (LITE_STRING_REQUIRE_MIN_VERSION + 0) == 0
#if _MSC_VER && !defined(__clang__) // MSVC does not have '#warning', but clang-cl does
#pragma message ("WARNING: Lite String version requirement is enabled, but the version is not specified!")
#else
#warning "Lite String version requirement is enabled, but the version is not specified!"
#endif // _MSC_VER && !defined(__clang__)
#else
#if _lite_string_version < LITE_STRING_REQUIRE_MIN_VERSION
#error "Lite String version is lower than required!"
#endif // _lite_string_version < LITE_STRING_REQUIRE_MIN_VERSION
#endif // (LITE_STRING_REQUIRE_MIN_VERSION + 0) == 0
#endif // LITE_STRING_REQUIRE_MIN_VERSION
#ifndef LITE_STRING_NO_RESTRICT
#define LITE_STRING_NO_RESTRICT 0
#endif // LITE_STRING_NO_RESTRICT
#if LITE_STRING_NO_RESTRICT
// Ignore the warning for redefining the 'restrict' keyword
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif // __clang__
#define restrict
// Restore Clang warnings
#if __clang__
#pragma clang diagnostic pop
#endif // __clang__
#endif // LITE_STRING_NO_RESTRICT
#if defined(__cplusplus) && __cplusplus
#if !LITE_STRING_NO_RESTRICT // The keyword has not been redefined
#if __GNUC__ || __clang__ || _MSC_VER // Support for '__restrict' in C++
// Ignore the warning for redefining the 'restrict' keyword (So far, only Clang has this warning)
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif // __clang__
#define restrict __restrict // Use '__restrict' in C++ for GCC, Clang, and MSVC
#else // Support for C++ '__restrict' is unknown on this compiler
#define restrict
#endif // __GNUC__ || __clang__ || _MSC_VER
// Restore Clang warnings
#if __clang__
#pragma clang diagnostic pop
#endif
#endif // LITE_STRING_NO_RESTRICT
extern "C" {
#endif // __cplusplus
#include <stddef.h>
#define lite_string_npos ((size_t) -1)
#ifdef __has_attribute
#define HAS_ATTRIBUTE(x) __has_attribute(x)
#else
#define HAS_ATTRIBUTE(x) 0
#endif // __has_attribute
#ifdef __has_c_attribute
#define HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
#else
#define HAS_C_ATTRIBUTE(x) HAS_ATTRIBUTE(x)
#endif // __has_c_attribute
#if __STDC_VERSION__ >= 202311L // C23 is supported
#if HAS_C_ATTRIBUTE(nodiscard) // C23 'nodiscard' attribute
#define LITE_ATTR_NODISCARD [[__nodiscard__]]
#elif HAS_ATTRIBUTE(warn_unused_result) // GNU 'warn_unused_result' attribute
#define LITE_ATTR_NODISCARD [[gnu::warn_unused_result]]
#else
#define LITE_ATTR_NODISCARD
#endif // HAS_C_ATTRIBUTE(nodiscard)
#if HAS_ATTRIBUTE(hot) // GNU 'hot' attribute
#define LITE_ATTR_HOT [[gnu::hot]]
#else
#define LITE_ATTR_HOT
#endif // HAS_ATTRIBUTE(hot)
#if HAS_C_ATTRIBUTE(reproducible) // C23 'reproducible' attribute
#define LITE_ATTR_REPRODUCIBLE [[__reproducible__]]
#elif HAS_ATTRIBUTE(pure) // GNU 'pure' attribute as a substitute
#define LITE_ATTR_REPRODUCIBLE [[gnu::pure]]
#else
#define LITE_ATTR_REPRODUCIBLE
#endif // HAS_C_ATTRIBUTE(reproducible)
#if HAS_C_ATTRIBUTE(unsequenced) // C23 'unsequenced' attribute
#define LITE_ATTR_UNSEQUENCED [[__unsequenced__]]
#elif HAS_ATTRIBUTE(__const__) // GNU 'const' attribute as a substitute
#define LITE_ATTR_UNSEQUENCED [[gnu::const]]
#else
#define LITE_ATTR_UNSEQUENCED
#endif // HAS_C_ATTRIBUTE(unsequenced)
#if HAS_ATTRIBUTE(nothrow) // GNU 'nothrow' attribute
#define LITE_ATTR_NOEXCEPT [[gnu::nothrow]]
#elif _MSC_VER
#define LITE_ATTR_NOEXCEPT __declspec(nothrow) // MSVC equivalent
#else
#define LITE_ATTR_NOEXCEPT
#endif // HAS_ATTRIBUTE(nothrow)
#else // C23 is not supported
#ifndef __cplusplus
#include <stdbool.h>
#define nullptr ((void *) 0)
#endif // __cplusplus
#if HAS_ATTRIBUTE(__warn_unused_result__) // GNU 'warn_unused_result' attribute, pre-C23 syntax
#define LITE_ATTR_NODISCARD __attribute__((__warn_unused_result__))
#else
#define LITE_ATTR_NODISCARD
#endif // HAS_ATTRIBUTE(__warn_unused_result__)
#if HAS_ATTRIBUTE(__hot__) // GNU 'hot' attribute
#define LITE_ATTR_HOT __attribute__((__hot__))
#else
#define LITE_ATTR_HOT
#endif // HAS_ATTRIBUTE(__hot__)
#if HAS_ATTRIBUTE(__pure__) // GNU 'pure' attribute
#define LITE_ATTR_REPRODUCIBLE __attribute__((__pure__))
#else
#define LITE_ATTR_REPRODUCIBLE
#endif // HAS_ATTRIBUTE(__pure__)
#if HAS_ATTRIBUTE(__const__) // GNU 'const' attribute
#define LITE_ATTR_UNSEQUENCED __attribute__((__const__))
#else
#define LITE_ATTR_UNSEQUENCED
#endif // HAS_ATTRIBUTE(__const__)
#if HAS_ATTRIBUTE(__nothrow__) // GNU 'nothrow' attribute
#define LITE_ATTR_NOEXCEPT __attribute__((__nothrow__))
#elif _MSC_VER
#define LITE_ATTR_NOEXCEPT __declspec(nothrow) // MSVC equivalent
#else
#define LITE_ATTR_NOEXCEPT
#endif // HAS_ATTRIBUTE(nothrow)
#endif // __STDC_VERSION__ >= 202311L
typedef struct lite_string lite_string; ///< The \p lite_string type.
LITE_ATTR_NODISCARD LITE_ATTR_HOT lite_string *string_new(void);
LITE_ATTR_HOT void string_free(lite_string *restrict s);
LITE_ATTR_HOT bool string_reserve(lite_string *restrict s, size_t size);
bool string_push_back(lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE char string_at(const lite_string *restrict s, size_t index);
void string_pop_back(lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE bool string_empty(const lite_string *restrict s);
bool string_erase(lite_string *restrict s, size_t index);
LITE_ATTR_REPRODUCIBLE char string_back(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE char string_front(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE bool string_compare(const lite_string *restrict s1, const lite_string *restrict s2);
LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_length(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT size_t string_size(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE size_t string_capacity(const lite_string *restrict s);
void string_clear(lite_string *restrict s);
bool string_insert(lite_string *restrict s, size_t index, char c);
void string_set(const lite_string *restrict s, size_t index, char c);
LITE_ATTR_NODISCARD lite_string *string_substr(const lite_string *restrict s, size_t start, size_t len);
LITE_ATTR_NODISCARD lite_string *string_concat(const lite_string *restrict s1, const lite_string *restrict s2);
bool string_append_range(lite_string *restrict s1, const lite_string *restrict s2, size_t count);
bool string_append(lite_string *restrict s1, const lite_string *restrict s2);
bool string_append_cstr(lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_HOT char *string_cstr(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE LITE_ATTR_HOT char *string_data(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE bool string_compare_cstr(const lite_string *restrict s, const char *restrict cstr);
bool string_insert_cstr(lite_string *restrict s, const char *restrict cstr, size_t index);
bool string_append_cstr_range(lite_string *restrict s, const char *restrict cstr, size_t count);
bool string_copy_buffer(const lite_string *restrict s, char *buf);
bool string_copy(const lite_string *restrict src, lite_string *restrict dest);
LITE_ATTR_REPRODUCIBLE bool string_case_compare(const lite_string *restrict s1, const lite_string *restrict s2);
LITE_ATTR_REPRODUCIBLE bool string_case_compare_cstr(const lite_string *restrict s, const char *restrict cstr);
bool string_swap(lite_string *restrict s1, lite_string *restrict s2);
bool string_insert_cstr_range(lite_string *restrict s, const char *restrict cstr, size_t index, size_t count);
bool string_insert_range(lite_string *restrict s, const lite_string *restrict sub, size_t index, size_t count);
bool string_insert_string(lite_string *restrict s, const lite_string *restrict sub, size_t index);
LITE_ATTR_REPRODUCIBLE size_t string_find_last_of(const lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE size_t string_find_last_not_of(const lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE size_t string_find_first_from(const lite_string *restrict s, char c, size_t start);
LITE_ATTR_REPRODUCIBLE size_t string_find_first_of(const lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE size_t string_find_first_not_of(const lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE size_t string_find_first_of_chars(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE size_t string_find_first_not_of_chars(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE size_t string_find_last_of_chars(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE size_t string_find_last_not_of_chars(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE size_t string_find_from(const lite_string *restrict s, const lite_string *restrict sub, size_t start);
LITE_ATTR_REPRODUCIBLE size_t string_find(const lite_string *restrict s, const lite_string *restrict sub);
LITE_ATTR_REPRODUCIBLE size_t string_rfind(const lite_string *restrict s, const lite_string *restrict sub);
LITE_ATTR_REPRODUCIBLE size_t string_find_cstr_from(const lite_string *restrict s, const char *restrict cstr, size_t start);
LITE_ATTR_REPRODUCIBLE size_t string_rfind_cstr(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE size_t string_find_cstr(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE bool string_contains_char(const lite_string *restrict s, char c);
LITE_ATTR_REPRODUCIBLE bool string_contains(const lite_string *restrict s, const lite_string *restrict sub);
LITE_ATTR_REPRODUCIBLE bool string_contains_cstr(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE bool string_starts_with(const lite_string *restrict s, const lite_string *restrict sub);
LITE_ATTR_REPRODUCIBLE bool string_starts_with_cstr(const lite_string *restrict s, const char *restrict cstr);
LITE_ATTR_REPRODUCIBLE bool string_ends_with(const lite_string *restrict s, const lite_string *restrict sub);
LITE_ATTR_REPRODUCIBLE bool string_ends_with_cstr(const lite_string *restrict s, const char *restrict cstr);
bool string_shrink(lite_string *restrict s, size_t size);
bool string_shrink_to_fit(lite_string *restrict s);
void string_to_lower(const lite_string *restrict s);
void string_to_upper(const lite_string *restrict s);
void string_to_title(const lite_string *restrict s);
LITE_ATTR_NODISCARD LITE_ATTR_HOT lite_string *string_new_cstr(const char *restrict cstr);
bool string_replace(lite_string *restrict s, const lite_string *restrict old_sub,
const lite_string *restrict new_sub);
void string_replace_char(const lite_string *restrict s, char old_char, char new_char);
bool string_replace_cstr(lite_string *restrict s, const char *restrict old_cstr,
const char *restrict new_cstr);
bool string_erase_range(lite_string *restrict s, size_t start, size_t count);
LITE_ATTR_NODISCARD lite_string *string_duplicate(const lite_string *restrict s);
void string_reverse(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE long long string_to_ll(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE unsigned long long string_to_ull(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE long string_to_l(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE unsigned long string_to_ul(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE int string_to_int(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE unsigned int string_to_uint(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE double string_to_double(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE float string_to_float(const lite_string *restrict s);
LITE_ATTR_REPRODUCIBLE long double string_to_ldouble(const lite_string *restrict s);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_l(long value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ll(long long value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ul(unsigned long value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ull(unsigned long long value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_int(int value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_uint(unsigned int value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_double(double value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_float(float value);
LITE_ATTR_NODISCARD LITE_ATTR_UNSEQUENCED lite_string *string_from_ldouble(long double value);
#if defined(__cplusplus) && __cplusplus
}
#endif