|
solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
|
High-performance C string with Small String Optimization (SSO). More...
#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include <string.h>#include "macros.h"Go to the source code of this file.
Classes | |
| struct | cstr |
| A dynamically resizable C string with SSO. More... | |
Macros | |
| #define | CSTR_MAX_LEN ((uint32_t)0x7FFFFFFFu) |
| #define | CSTR_SSO_CAP 16u /* 15 usable chars + NUL */ |
| #define | CSTR_HEAP_FLAG ((uint32_t)0x80000000u) |
| #define | CSTR_NPOS (-1) |
Typedefs | |
| typedef struct cstr | cstr |
| A dynamically resizable C string with SSO. | |
Functions | |
| CSTR_INLINE bool | cstr_is_heap (const cstr *s) CSTR_PURE |
| CSTR_INLINE uint32_t | cstr_heap_cap (const cstr *s) CSTR_PURE |
| CSTR_INLINE size_t | cstr_len (const cstr *s) CSTR_PURE |
| Length of the string, excluding NUL. | |
| CSTR_INLINE size_t | cstr_capacity (const cstr *s) CSTR_PURE |
| Current storage capacity (bytes available before reallocation). For SSO strings this is CSTR_SSO_CAP - 1 (15 chars + room for NUL). | |
| CSTR_INLINE bool | cstr_empty (const cstr *s) CSTR_PURE |
| CSTR_INLINE bool | cstr_allocated (const cstr *s) CSTR_PURE |
| CSTR_INLINE char * | cstr_data (cstr *s) CSTR_PURE |
| Mutable pointer to the NUL-terminated string data. Never NULL for a valid cstr. | |
| CSTR_INLINE const char * | cstr_data_const (const cstr *s) CSTR_PURE |
| Const pointer to the NUL-terminated string data. | |
| CSTR_INLINE char | cstr_at (const cstr *s, size_t index) CSTR_PURE |
| Character at index, or NUL if out of range. | |
| CSTR_INLINE cstr_view | cstr_as_view (const cstr *s) |
| Construct a cstr_view from a cstr (zero copy). | |
| CSTR_INLINE void | cstr_init_inplace (cstr *s) |
| Initialize an already-allocated cstr in SSO mode (no heap). | |
| cstr * | cstr_init (size_t initial_capacity) CSTR_WARN_UNUSED |
| Create a new heap-allocated cstr with a given initial capacity. | |
| cstr * | cstr_new (const char *input) CSTR_WARN_UNUSED |
| Create a new cstr from a C string. | |
| cstr * | cstr_new_len (const char *data, size_t length) CSTR_WARN_UNUSED |
| Create a new cstr from a buffer of known length (no strlen needed). | |
| void | cstr_free (cstr *s) |
| Free a heap-allocated cstr and its storage. Safe to call with NULL. | |
| void | cstr_drop (cstr *s) |
| Release only the internal heap buffer of an embedded cstr (one created via cstr_init_inplace). Does NOT free the cstr struct itself. | |
| void | cstr_debug (const cstr *s) |
| Print debug information about a cstr to stderr. | |
| bool | cstr_reserve (cstr *s, size_t capacity) CSTR_NONNULL(1) CSTR_WARN_UNUSED |
Ensure at least capacity usable bytes are available (NUL extra). | |
| CSTR_INLINE bool | cstr_resize (cstr *s, size_t capacity) CSTR_NONNULL(1) CSTR_WARN_UNUSED |
| void | cstr_shrink_to_fit (cstr *s) CSTR_NONNULL(1) |
| Shrink heap allocation to fit the current length (frees wasted memory). | |
| CSTR_INLINE void | cstr_clear (cstr *s) |
| Set length to 0 (data pointer and capacity unchanged). | |
| bool | cstr_append (cstr *s, const char *CSTR_RESTRICT append) CSTR_NONNULL(1 |
| Append a NUL-terminated C string. | |
| bool bool | cstr_append_cstr (cstr *s, const cstr *append) CSTR_NONNULL(1 |
| Append another cstr. | |
| bool bool bool | cstr_ncat (cstr *dest, const cstr *src, size_t n) CSTR_NONNULL(1 |
| Append at most n chars from src. | |
| bool bool bool CSTR_INLINE bool | cstr_cat (cstr *dest, const cstr *src) CSTR_NONNULL(1 |
| CSTR_INLINE bool | cstr_append_fast (cstr *s, const char *CSTR_RESTRICT append) CSTR_NONNULL(1 |
| Append without capacity check — caller guarantees space. ~20% faster for bulk building when capacity is pre-reserved. | |
| bool | cstr_append_char (cstr *s, char c) CSTR_NONNULL(1) |
| Append a single character. | |
| PRINTF_FORMAT (1, 2) cstr *cstr_format(const char *format | |
| Create a new cstr from a printf-style format string. | |
| PRINTF_FORMAT (2, 3) bool cstr_append_fmt(cstr *s | |
| Append a printf-style formatted string. | |
| bool | cstr_prepend (cstr *s, const char *prepend) CSTR_NONNULL(1 |
| Prepend a NUL-terminated C string. | |
| bool bool | cstr_prepend_cstr (cstr *s, const cstr *prepend) CSTR_NONNULL(1 |
| Prepend another cstr. | |
| bool bool bool | cstr_prepend_fast (cstr *s, const char *prepend) CSTR_NONNULL(1 |
| Prepend without capacity check — caller guarantees space. | |
| bool bool bool bool | cstr_insert (cstr *s, size_t index, const char *insert) CSTR_NONNULL(1 |
Insert a C string at byte offset index. | |
| bool bool bool bool bool | cstr_insert_cstr (cstr *s, size_t index, const cstr *insert) CSTR_NONNULL(1 |
Insert a cstr at byte offset index. | |
| bool bool bool bool bool bool | cstr_remove (cstr *s, size_t index, size_t count) CSTR_NONNULL(1) |
Remove count characters starting at index. | |
| size_t | cstr_remove_all (cstr *s, const char *substr) CSTR_NONNULL(1 |
| Remove all occurrences of substr (in-place, single pass). | |
| size_t size_t void | cstr_remove_char (cstr *s, char c) CSTR_NONNULL(1) |
| Remove a specific character from every position. | |
| void | cstr_remove_substr (cstr *str, size_t start, size_t substr_length) CSTR_NONNULL(1) |
Remove a run of substr_length bytes starting at start. | |
| bool | cstr_copy (cstr *dest, const cstr *src) CSTR_NONNULL(1 |
| Deep copy src into dest (dest is overwritten). | |
| bool CSTR_INLINE bool | cstr_assign (cstr *dest, const cstr *src) CSTR_NONNULL(1 |
| void int | cstr_cmp (const cstr *s1, const cstr *s2) CSTR_PURE |
| Lexicographic compare. NULL < non-NULL; two NULLs are equal. | |
| CSTR_INLINE bool | cstr_equals (const cstr *s1, const cstr *s2) CSTR_PURE |
| Equality check (length-first — very fast for non-equal strings). | |
| int | cstr_find (const cstr *s, const char *substr) CSTR_NONNULL(1 |
| Find first occurrence of substr. Uses optimised search (no memmem). | |
| int | cstr_rfind (const cstr *s, const char *substr) CSTR_NONNULL(1 |
| size_t | cstr_count_substr (const cstr *s, const char *substr) CSTR_NONNULL(1 |
| cstr ** | cstr_split (const cstr *s, const char *delim, size_t *count_out) CSTR_NONNULL(1 |
| Split on delimiter. Returns array of cstr* (each must be freed), terminated by setting *count_out. Caller must free each element and the array itself. | |
| cstr * | cstr_join (const cstr **strings, size_t count, const char *delim) CSTR_WARN_UNUSED |
| Join an array of cstr pointers with a delimiter. | |
High-performance C string with Small String Optimization (SSO).
Key design decisions vs. the convential implementation:
data always points to the live bytes — either into buf[] (stack) or a heap allocation. Every read/write goes through one pointer with zero branching; the "is-heap?" test is only needed for free/resize paths.length and capacity in the struct root (uint32_t) No union-of-structs, no masked flag bits in length. The heap-flag lives in the MSB of capacity only. Reading length is always s->length.Struct layout (64-bit, little-endian): offset 0 : char* data (8 bytes) — always valid pointer offset 8 : uint32_t length (4 bytes) offset 12 : uint32_t capacity (4 bytes) — MSB = heap flag offset 16 : char buf[16] (16 bytes) — inline storage Total: 32 bytes
Definition in file cstr.h.
| #define CSTR_HEAP_FLAG ((uint32_t)0x80000000u) |
| #define CSTR_MAX_LEN ((uint32_t)0x7FFFFFFFu) |
| #define CSTR_NPOS (-1) |
| #define CSTR_SSO_CAP 16u /* 15 usable chars + NUL */ |
A dynamically resizable C string with SSO.
data is ALWAYS a valid, NUL-terminated pointer:
This eliminates the branch in every read — callers just dereference data.
| CSTR_INLINE bool cstr_allocated | ( | const cstr * | s | ) |
True if the string is heap-allocated (i.e. not in SSO mode).
Definition at line 171 of file cstr.h.
References cstr_is_heap().
| CSTR_INLINE bool CSTR_INLINE bool cstr_append_fast | ( | cstr * | s, |
| const char *CSTR_RESTRICT | append | ||
| ) |
Append without capacity check — caller guarantees space. ~20% faster for bulk building when capacity is pre-reserved.
Definition at line 333 of file cstr.h.
References cstr::data, and cstr::length.
Alias for cstr_copy.
Definition at line 410 of file cstr.h.
References cstr_copy().
Alias: concatenate two cstrs.
Definition at line 325 of file cstr.h.
References cstr_append_cstr().
| size_t cstr_count_substr | ( | const cstr * | s, |
| const char * | substr | ||
| ) |
Count occurrences (non-overlapping).
| CSTR_INLINE bool cstr_empty | ( | const cstr * | s | ) |
True if the string is empty or NULL.
Definition at line 167 of file cstr.h.
References cstr::length.
| int cstr_find | ( | const cstr * | s, |
| const char * | substr | ||
| ) |
Find first occurrence of substr. Uses optimised search (no memmem).
Referenced by cstr_rfind().
| CSTR_INLINE uint32_t cstr_heap_cap | ( | const cstr * | s | ) |
Extract actual heap capacity (strip flag bit).
Definition at line 143 of file cstr.h.
References cstr::capacity.
Referenced by cstr_capacity(), cstr_debug(), and cstr_shrink_to_fit().
| cstr * cstr_init | ( | size_t | initial_capacity | ) |
Create a new heap-allocated cstr with a given initial capacity.
| initial_capacity | Desired usable capacity (NUL not counted). |
Definition at line 127 of file cstr.c.
References cstr_init_inplace(), and CSTR_SSO_CAP.
Referenced by cstr_join().
| CSTR_INLINE void cstr_init_inplace | ( | cstr * | s | ) |
Initialize an already-allocated cstr in SSO mode (no heap).
Use this to embed a cstr inside another struct without a separate alloc. The cstr must be freed with cstr_drop() (not cstr_free()) when done.
| s | Pointer to uninitialised cstr storage. |
Definition at line 225 of file cstr.h.
References cstr::buf, cstr::capacity, cstr::data, and cstr::length.
Referenced by cstr_drop(), cstr_init(), and cstr_new_len().
| CSTR_INLINE bool cstr_is_heap | ( | const cstr * | s | ) |
True when string data lives on the heap.
Definition at line 139 of file cstr.h.
References cstr::capacity, and CSTR_HEAP_FLAG.
Referenced by cstr_allocated(), cstr_capacity(), cstr_debug(), cstr_drop(), cstr_free(), and cstr_shrink_to_fit().
| cstr * cstr_new | ( | const char * | input | ) |
Create a new cstr from a C string.
| input | NUL-terminated source. Must not be NULL. |
Definition at line 146 of file cstr.c.
References cstr_new_len().
| cstr * cstr_new_len | ( | const char * | data, |
| size_t | length | ||
| ) |
Create a new cstr from a buffer of known length (no strlen needed).
| data | Pointer to characters (need not be NUL-terminated). |
| length | Number of bytes to copy. |
Definition at line 151 of file cstr.c.
References cstr_init_inplace(), cstr::data, and cstr::length.
Referenced by cstr_join(), and cstr_new().
| size_t cstr_remove_all | ( | cstr * | s, |
| const char * | substr | ||
| ) |
Remove all occurrences of substr (in-place, single pass).
| bool cstr_reserve | ( | cstr * | s, |
| size_t | capacity | ||
| ) |
Ensure at least capacity usable bytes are available (NUL extra).
Definition at line 205 of file cstr.c.
Referenced by cstr_resize().
| CSTR_INLINE bool cstr_resize | ( | cstr * | s, |
| size_t | capacity | ||
| ) |
Alias kept for compatibility.
Definition at line 286 of file cstr.h.
References cstr_reserve().
| int cstr_rfind | ( | const cstr * | s, |
| const char * | substr | ||
| ) |
Find last occurrence.
References cstr_find(), and CSTR_NPOS.