The C API is built around length-bounded raw pointers, so most functions take a sz_cptr_t, an alias of char const *, or a sz_ptr_t, an alias of char *, together with a sz_size_t length, and return either a sz_cptr_t into the input or one of the small enums below.
Scalar and result types from types.h:
sz_cptr_t, sz_ptr_t — immutable and mutable byte pointers.
sz_size_t, sz_ssize_t — unsigned and signed size types.
sz_u8_t, sz_u32_t, sz_u64_t — fixed-width integers; sz_rune_t is a 32-bit Unicode scalar value.
sz_bool_t — { sz_false_k = 0, sz_true_k = 1 }.
sz_ordering_t — { sz_less_k = -1, sz_equal_k = 0, sz_greater_k = 1 }, the C analog of std::strong_ordering.
sz_pgram_t — a pointer-sized N-gram, an alias of sz_size_t, which also indexes every permutation.
sz_byteset_t is a 256-bit set of byte values used by the byte-set search functions:
sz_byteset_t set;sz_byteset_init(&set); // all bits clearedsz_byteset_add(&set, '\n'); // include a byteint has = sz_byteset_contains(&set, '\n');sz_byteset_invert(&set); // complement the set
sz_allocator_t is the explicit allocator, a { allocate, free, handle } triple, handed to any function that may allocate:
sz_allocator_t allocator;sz_status_t status = sz_allocator_init_heap(&allocator); // libc malloc/freeif (status != sz_success_k) return status;// or a fixed arena with no dynamic allocation:char arena[4096];status = sz_allocator_init_arena(&allocator, arena, sizeof(arena), 64);if (status != sz_success_k) return status;
sz_strings_view_t is the read-only collection of strings every collection family takes, in one of three layouts: an Apache Arrow tape of 32-bit or 64-bit offsets, which GPUs read directly, or an accessor writing up to 64 views per call over any other shape.
Helpers wire it to plain arrays of C strings, of views, of records, and of NUL-padded rows:
There is no dedicated sz_string_view_t struct in the C ABI — views are passed as the (pointer, length) pairs described above.
The one owning C string type is sz_string_t, documented under String Collections and Containers below.
API
Types
sz_i8_tEven when LibC is not available, compiler macros let us infer the size of integer types.
The C standard doesn't specify the signedness of char. On x86 char is signed by default while on Arm it is unsigned by default. That's why we don't define sz_char_t and generally use explicit sz_i8_t and sz_u8_t.
sz_u1x8_tEight booleans in one byte, item 0 in the least significant bit, the order of Arrow and cuDF validity masks and the reverse of NumKong's nk_u1x8_t.
Tapes are what Apache Arrow, the Python Strings class and GPU kernels read directly. The accessor covers every other shape, from arrays of views to the nodes of a parsed tree, at one indirect call per block of strings. A slice of a tape keeps its parent's offsets, so its first offset may be above zero.
Its payload and offsets are two blocks of exactly the sizes they need, so both sizes follow from the offsets, which the host can always read. A zeroed span is an empty tape holding no blocks.
sz_u64_bits_reverseReverse the 64 bits of value, so bit i moves to bit 63 - i: swap adjacent bits, then bit-pairs within nibbles, then nibbles within bytes, then the bytes.
sz_ssize_clamp_interval_checkedClamps signed offsets to a Python-style [offset, offset + length) slice and reports whether the requested window was non-degenerate.
Mirrors CPython's ADJUST_INDICES: negative indices count from the end, end is clamped into the string, and a window with start past end, out of range or inverted, is "empty" - exactly when str.find("") and str.rfind("") return -1.
sz_ssize_clamp_intervalClamps signed offsets in a string to a valid range.
A step of one over a tape yields a tape over the same bytes and offsets, leaving views untouched. Every other selection fills views and points the accessor of slice at them.
Parameters
strings
in
The collection to slice, which must outlive slice.
start
in
Index of the first selected string.
step
in
Distance between selected indices, negative to walk backward.
count
in
Number of strings to select.
views
out
Room for count views, or null for a step of one over a tape.
slice
out
The selected strings.
sz_strings_from_matchesViews the spans a substrings, regex or subdocuments search located, copying no bytes.
A branchless approach is well known for signed integers, but it doesn't apply to unsigned ones. The simple branching baseline comes first, then the shift-only form for signed integers, then two forms for any integers, with and without multiplication: