31#if __STDC_VERSION__ < 202311L
48#define str_literal(SZ_LITERAL) (str){ (SZ_LITERAL), sizeof(SZ_LITERAL) - 1 }
85#define str_strip_prefix(IT, PREFIX) _Generic((PREFIX),\
86 const str : str_strip_prefix_str,\
87 str : str_strip_prefix_str,\
88 const char* : str_strip_prefix_cstr,\
89 char* : str_strip_prefix_cstr,\
90 bool (*)(char c) : str_strip_prefix_if\
108#define str_strip_postfix(IT, POSTFIX) _Generic((POSTFIX),\
109 const str : str_strip_postfix_str,\
110 str : str_strip_postfix_str,\
111 const char* : str_strip_postfix_cstr,\
112 char* : str_strip_postfix_cstr,\
113 bool (*)(char c) : str_strip_postfix_if\
128#define cstr_cmp_cstr strcmp
132#define str_cmp(LHS, RHS) _Generic((LHS),\
133 const str: _Generic((RHS),\
134 const str : str_cmp_str,\
136 const char*: str_cmp_cstr,\
139 str: _Generic((RHS),\
140 const str : str_cmp_str,\
142 const char*: str_cmp_cstr,\
145 const char*: _Generic((RHS),\
146 const str : cstr_cmp_str,\
148 const char*: strcmp,\
151 char*: _Generic((RHS),\
152 const str : cstr_cmp_str,\
154 const char*: strcmp,\
172#define str_eq(LHS, RHS) _Generic((LHS),\
173 const str: _Generic((RHS),\
174 const str : str_eq_str,\
176 const char*: str_eq_cstr,\
179 str: _Generic((RHS),\
180 const str : str_eq_str,\
182 const char*: str_eq_cstr,\
185 const char*: _Generic((RHS),\
186 const str : cstr_eq_str,\
188 const char*: cstr_eq_cstr,\
191 char*: _Generic((RHS),\
192 const str : cstr_eq_str,\
194 const char*: cstr_eq_cstr,\
247#define str_eq_any(LHS, COUNT, RHS, ...) _Generic((LHS),\
248 const str: _Generic((RHS),\
249 const str : str_eq_str_any,\
250 str : str_eq_str_any,\
251 const str* : str_eq_strs_any,\
252 str* : str_eq_strs_any,\
253 const char* : str_eq_cstr_any,\
254 char* : str_eq_cstr_any,\
255 const char**: str_eq_cstrs_any,\
256 char**: str_eq_cstrs_any\
258 str: _Generic((RHS),\
259 const str : str_eq_str_any,\
260 str : str_eq_str_any,\
261 const str* : str_eq_strs_any,\
262 str* : str_eq_strs_any,\
263 const char* : str_eq_cstr_any,\
264 char* : str_eq_cstr_any,\
265 const char**: str_eq_cstrs_any,\
266 char**: str_eq_cstrs_any\
268 const char*: _Generic((RHS),\
269 const str : cstr_eq_str_any,\
270 str : cstr_eq_str_any,\
271 const str* : cstr_eq_strs_any,\
272 str* : cstr_eq_strs_any,\
273 const char* : cstr_eq_cstr_any,\
274 char* : cstr_eq_cstr_any,\
275 const char**: cstr_eq_cstrs_any,\
276 char**: cstr_eq_cstrs_any\
278 char*: _Generic((RHS),\
279 const str : cstr_eq_str_any,\
280 str : cstr_eq_str_any,\
281 const str* : cstr_eq_strs_any,\
282 str* : cstr_eq_strs_any,\
283 const char* : cstr_eq_cstr_any,\
284 char* : cstr_eq_cstr_any,\
285 const char**: cstr_eq_cstrs_any,\
286 char**: cstr_eq_cstrs_any\
288)((LHS), (COUNT), (RHS) __VA_OPT__(, __VA_ARGS__))
391#define str_has_prefix(LHS, RHS) _Generic((LHS),\
392 const str: _Generic((RHS),\
393 const str : str_has_prefix_str,\
394 str : str_has_prefix_str,\
395 const char*: str_has_prefix_cstr,\
396 char*: str_has_prefix_cstr\
398 str: _Generic((RHS),\
399 const str : str_has_prefix_str,\
400 str : str_has_prefix_str,\
401 const char*: str_has_prefix_cstr,\
402 char*: str_has_prefix_cstr\
404 const char*: _Generic((RHS),\
405 const str : cstr_has_prefix_str,\
406 str : cstr_has_prefix_str,\
407 const char*: cstr_has_prefix_cstr,\
408 char*: cstr_has_prefix_cstr\
410 char*: _Generic((RHS),\
411 const str : cstr_has_prefix_str,\
412 str : cstr_has_prefix_str,\
413 const char*: cstr_has_prefix_cstr,\
414 char*: cstr_has_prefix_cstr\
419#define str_has_postfix(LHS, RHS) _Generic((LHS),\
420 const str: _Generic((RHS),\
421 const str : str_has_postfix_str,\
422 str : str_has_postfix_str,\
423 const char*: str_has_postfix_cstr,\
424 char*: str_has_postfix_cstr\
426 str: _Generic((RHS),\
427 const str : str_has_postfix_str,\
428 str : str_has_postfix_str,\
429 const char*: str_has_postfix_cstr,\
430 char*: str_has_postfix_cstr\
432 const char*: _Generic((RHS),\
433 const str : cstr_has_postfix_str,\
434 str : cstr_has_postfix_str,\
435 const char*: cstr_has_postfix_cstr,\
436 char*: cstr_has_postfix_cstr\
438 char*: _Generic((RHS),\
439 const str : cstr_has_postfix_str,\
440 str : cstr_has_postfix_str,\
441 const char*: cstr_has_postfix_cstr,\
442 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:42
char * data
Pointer to the start of the string.
Definition str.h:43
size_t len
The length of the string.
Definition str.h:44