27#if __STDC_VERSION__ < 202311L
44#define str_literal(SZ_LITERAL) (str){ (SZ_LITERAL), sizeof(SZ_LITERAL) - 1 }
81#define str_strip_prefix(IT, PREFIX) _Generic((PREFIX),\
82 const str : str_strip_prefix_str,\
83 str : str_strip_prefix_str,\
84 const char* : str_strip_prefix_cstr,\
85 char* : str_strip_prefix_cstr,\
86 bool (*)(char c) : str_strip_prefix_if\
104#define str_strip_postfix(IT, POSTFIX) _Generic((POSTFIX),\
105 const str : str_strip_postfix_str,\
106 str : str_strip_postfix_str,\
107 const char* : str_strip_postfix_cstr,\
108 char* : str_strip_postfix_cstr,\
109 bool (*)(char c) : str_strip_postfix_if\
124#define cstr_cmp_cstr strcmp
128#define str_cmp(LHS, RHS) _Generic((LHS),\
129 const str: _Generic((RHS),\
130 const str : str_cmp_str,\
132 const char*: str_cmp_cstr,\
135 str: _Generic((RHS),\
136 const str : str_cmp_str,\
138 const char*: str_cmp_cstr,\
141 const char*: _Generic((RHS),\
142 const str : cstr_cmp_str,\
144 const char*: strcmp,\
147 char*: _Generic((RHS),\
148 const str : cstr_cmp_str,\
150 const char*: strcmp,\
168#define str_eq(LHS, RHS) _Generic((LHS),\
169 const str: _Generic((RHS),\
170 const str : str_eq_str,\
172 const char*: str_eq_cstr,\
175 str: _Generic((RHS),\
176 const str : str_eq_str,\
178 const char*: str_eq_cstr,\
181 const char*: _Generic((RHS),\
182 const str : cstr_eq_str,\
184 const char*: cstr_eq_cstr,\
187 char*: _Generic((RHS),\
188 const str : cstr_eq_str,\
190 const char*: cstr_eq_cstr,\
244#if __STDC_VERSION__ >= 202311L
245 #define str_eq_any(LHS, COUNT, RHS, ...) _Generic((LHS),\
246 const str: _Generic((RHS),\
247 const str : str_eq_str_any,\
248 str : str_eq_str_any,\
249 const str* : str_eq_strs_any,\
250 str* : str_eq_strs_any,\
251 const char* : str_eq_cstr_any,\
252 char* : str_eq_cstr_any,\
253 const char**: str_eq_cstrs_any,\
254 char**: str_eq_cstrs_any\
256 str: _Generic((RHS),\
257 const str : str_eq_str_any,\
258 str : str_eq_str_any,\
259 const str* : str_eq_strs_any,\
260 str* : str_eq_strs_any,\
261 const char* : str_eq_cstr_any,\
262 char* : str_eq_cstr_any,\
263 const char**: str_eq_cstrs_any,\
264 char**: str_eq_cstrs_any\
266 const char*: _Generic((RHS),\
267 const str : cstr_eq_str_any,\
268 str : cstr_eq_str_any,\
269 const str* : cstr_eq_strs_any,\
270 str* : cstr_eq_strs_any,\
271 const char* : cstr_eq_cstr_any,\
272 char* : cstr_eq_cstr_any,\
273 const char**: cstr_eq_cstrs_any,\
274 char**: cstr_eq_cstrs_any\
276 char*: _Generic((RHS),\
277 const str : cstr_eq_str_any,\
278 str : cstr_eq_str_any,\
279 const str* : cstr_eq_strs_any,\
280 str* : cstr_eq_strs_any,\
281 const char* : cstr_eq_cstr_any,\
282 char* : cstr_eq_cstr_any,\
283 const char**: cstr_eq_cstrs_any,\
284 char**: cstr_eq_cstrs_any\
286 )((LHS), (COUNT), (RHS) __VA_OPT__(, __VA_ARGS__))
287#elif defined(__GNUC__)
288 #define str_eq_any(LHS, COUNT, RHS, ...) _Generic((LHS),\
289 const str: _Generic((RHS),\
290 const str : str_eq_str_any,\
291 str : str_eq_str_any,\
292 const str* : str_eq_strs_any,\
293 str* : str_eq_strs_any,\
294 const char* : str_eq_cstr_any,\
295 char* : str_eq_cstr_any,\
296 const char**: str_eq_cstrs_any,\
297 char**: str_eq_cstrs_any\
299 str: _Generic((RHS),\
300 const str : str_eq_str_any,\
301 str : str_eq_str_any,\
302 const str* : str_eq_strs_any,\
303 str* : str_eq_strs_any,\
304 const char* : str_eq_cstr_any,\
305 char* : str_eq_cstr_any,\
306 const char**: str_eq_cstrs_any,\
307 char**: str_eq_cstrs_any\
309 const char*: _Generic((RHS),\
310 const str : cstr_eq_str_any,\
311 str : cstr_eq_str_any,\
312 const str* : cstr_eq_strs_any,\
313 str* : cstr_eq_strs_any,\
314 const char* : cstr_eq_cstr_any,\
315 char* : cstr_eq_cstr_any,\
316 const char**: cstr_eq_cstrs_any,\
317 char**: cstr_eq_cstrs_any\
319 char*: _Generic((RHS),\
320 const str : cstr_eq_str_any,\
321 str : cstr_eq_str_any,\
322 const str* : cstr_eq_strs_any,\
323 str* : cstr_eq_strs_any,\
324 const char* : cstr_eq_cstr_any,\
325 char* : cstr_eq_cstr_any,\
326 const char**: cstr_eq_cstrs_any,\
327 char**: cstr_eq_cstrs_any\
329 )((LHS), (COUNT), (RHS), ##__VA_ARGS__)
331 #warning Neither C23's __VA_OPT__ nor GNU's ##__VA_ARGS__ are available, str_eq_any() will be unavailable
435#define str_has_prefix(LHS, RHS) _Generic((LHS),\
436 const str: _Generic((RHS),\
437 const str : str_has_prefix_str,\
438 str : str_has_prefix_str,\
439 const char*: str_has_prefix_cstr,\
440 char*: str_has_prefix_cstr\
442 str: _Generic((RHS),\
443 const str : str_has_prefix_str,\
444 str : str_has_prefix_str,\
445 const char*: str_has_prefix_cstr,\
446 char*: str_has_prefix_cstr\
448 const char*: _Generic((RHS),\
449 const str : cstr_has_prefix_str,\
450 str : cstr_has_prefix_str,\
451 const char*: cstr_has_prefix_cstr,\
452 char*: cstr_has_prefix_cstr\
454 char*: _Generic((RHS),\
455 const str : cstr_has_prefix_str,\
456 str : cstr_has_prefix_str,\
457 const char*: cstr_has_prefix_cstr,\
458 char*: cstr_has_prefix_cstr\
463#define str_has_postfix(LHS, RHS) _Generic((LHS),\
464 const str: _Generic((RHS),\
465 const str : str_has_postfix_str,\
466 str : str_has_postfix_str,\
467 const char*: str_has_postfix_cstr,\
468 char*: str_has_postfix_cstr\
470 str: _Generic((RHS),\
471 const str : str_has_postfix_str,\
472 str : str_has_postfix_str,\
473 const char*: str_has_postfix_cstr,\
474 char*: str_has_postfix_cstr\
476 const char*: _Generic((RHS),\
477 const str : cstr_has_postfix_str,\
478 str : cstr_has_postfix_str,\
479 const char*: cstr_has_postfix_cstr,\
480 char*: cstr_has_postfix_cstr\
482 char*: _Generic((RHS),\
483 const str : cstr_has_postfix_str,\
484 str : cstr_has_postfix_str,\
485 const char*: cstr_has_postfix_cstr,\
486 char*: cstr_has_postfix_cstr\
size_t cstr_has_prefix_cstr(const char *it, const char *prefix)
Checks if a string begins with another string.
size_t str_eq_cstrs_any(str it, size_t count, const char *others[static count])
Compares a string to several others to see if its contents are equal to any of them.
size_t str_eq_str_any(str it, size_t count,...)
Compares a string to several others to see if its contents are equal to any of them.
size_t str_eq_strs_any(str it, size_t count, const str others[static count])
Compares a string to several others to see if its contents are equal to any of them.
size_t cstr_has_postfix_cstr(const char *it, const char *postfix)
Checks if a string ends with another string.
str str_strip_prefix_if(str it, bool(*predicate)(char))
Returns a non-owning copy of a str with all leading characters satisfying predicate removed.
bool str_eq_cstr(str a, const char *b)
Compares two strings to see if their contents are equal.
str str_strip_prefix_cstr(str it, const char *prefix)
Returns a non-owning copy of a str with a given prefix removed, if it is present.
bool cstr_eq_str(const char *a, str b)
Compares two strings to see if their contents are equal.
str str_strip_whitespace(str it)
Returns a non-owning copy of a str with all leading and trailing whitespace removed.
str str_strip_postfix_str(str it, str postfix)
Returns a non-owning copy of a str with a given postfix removed, if it is present.
size_t cstr_satisfies_any(const char *it, size_t count,...)
Checks if a string satisfies any of several predicates.
int str_cmp_str(str a, str b)
Compares two strings lexicographically.
bool str_satisfies_alls(str it, size_t count, bool(*predicates[static count])(str))
Checks if a string satisfies all of several predicates.
size_t cstr_eq_strs_any(const char *it, size_t count, const str others[static count])
Compares a string to several others to see if its contents are equal to any of them.
bool str_eq_str(str a, str b)
Compares two strings to see if their contents are equal.
bool str_satisfies_all(str it, size_t count,...)
Checks if a string satisfies all of several predicates.
size_t cstr_has_postfix_str(const char *it, str postfix)
Checks if a string ends with another string.
str str_strip_whitespace_pre(str it)
Returns a non-owning copy of a str with all leading whitespace removed.
size_t cstr_has_prefix_str(const char *it, str prefix)
Checks if a string begins with another string.
str str_strip_prefix_str(str it, str prefix)
Returns a non-owning copy of a str with a given prefix removed, if it is present.
size_t cstr_eq_cstr_any(const char *it, size_t count,...)
Compares a string to several others to see if its contents are equal to any of them.
int str_cmp_cstr(str a, const char *b)
Compares two strings lexicographically.
str str_strip_postfix_cstr(str it, const char *postfix)
Returns a non-owning copy of a str with a given postfix removed, if it is present.
bool cstr_satisfies_all(const char *it, size_t count,...)
Checks if a string satisfies all of several predicates.
size_t str_has_prefix_str(str it, str prefix)
Checks if a string begins with another string.
str str_slice_cstr(char *sz, size_t len)
Constructs a non-owning str from part of a nil-terminated C-string.
bool cstr_chars_satisfies(const char *it, bool(*predicate)(char))
Checks if all characters in a string satisfies a predicate.
size_t cstr_eq_str_any(const char *it, size_t count,...)
Compares a string to several others to see if its contents are equal to any of them.
int cstr_cmp_str(const char *a, str b)
Compares two strings lexicographically.
size_t cstr_eq_cstrs_any(const char *it, size_t count, const char *others[static count])
Compares a string to several others to see if its contents are equal to any of them.
bool cstr_satisfies_alls(const char *it, size_t count, bool(*predicates[static count])(const char *))
Checks if a string satisfies all of several predicates.
str str_from_cstr(char *sz)
Constructs a non-owning str from a nil-terminated C-string.
size_t str_has_postfix_str(str it, str postfix)
Checks if a string ends with another string.
size_t str_has_postfix_cstr(str it, const char *postfix)
Checks if a string ends with another string.
size_t cstr_satisfies_anys(const char *it, size_t count, bool(*predicates[static count])(const char *))
Checks if a string satisfies any of several predicates.
size_t str_eq_cstr_any(str it, size_t count,...)
Compares a string to several others to see if its contents are equal to any of them.
size_t str_satisfies_any(str it, size_t count,...)
Checks if a string satisfies any of several predicates.
str str_strip_whitespace_post(str it)
Returns a non-owning copy of a str with all trailing whitespace removed.
str str_strip_postfix_if(str it, bool(*predicate)(char))
Returns a non-owning copy of a str with all trailing characters satisfying predicate removed.
bool str_chars_satisfies(str it, bool(*predicate)(char))
Checks if all characters in a string satisfies a predicate.
size_t str_has_prefix_cstr(str it, const char *prefix)
Checks if a string begins with another string.
size_t str_satisfies_anys(str it, size_t count, bool(*predicates[static count])(str))
Checks if a string satisfies any of several predicates.
bool cstr_eq_cstr(const char *a, const char *b)
Compares two strings to see if their contents are equal.
A string "slice", which is a pointer & length pair.
Definition str.h:38
char * data
Pointer to the start of the string.
Definition str.h:39
size_t len
The length of the string.
Definition str.h:40