lib/split.x
String field splitting and repeatable typed cursors.
Primary API
| Function | Summary |
|---|---|
Split.iter | Returns an iterator over a lazy String cursor. |
Split.try_next | Yields the next field and advances a caller-owned position on success. |
String.lines | Returns a lazy cursor over lines in str, with endings removed. |
String.split | Splits str on every occurrence of sep into a List of Strings. |
String.split_lines | Splits str into a List of lines. |
String.split_n | Splits str at no more than max_splits separators. |
String.splits | Returns a lazy cursor over fields separated by sep. |
String.words | Returns a lazy cursor over whitespace-delimited words in str. |
Split
Split.iter
Iter Split.iter(Split split, Iter dest)
Returns an iterator over a lazy String cursor.
This adapter over Split.try_next boxes each field into a Var and
keeps the Iter state in step. Use the typed cursor in hot code and this
method when you need the Iter protocol.
The cursor descriptor is Scope-owned; dest is caller-supplied iterator
storage. Every iterator keeps its own byte position, so cursors can be
nested or traversed concurrently. The Split descriptor, its borrowed
input Strings, and dest must remain live until iteration ends.
Constructing the iterator does not raise. Pulling may raise
<alloc-fail> as Split.try_next does. A null dest returns NULL.
Source: lib/split.x:269
Split.try_next
int Split.try_next(Split split, int *cursor, String *out)
Yields the next field and advances a caller-owned position on success.
Position must start at zero and thereafter retain only values written by
this method. Both it and out are written only on success, so an empty
String field stays distinct from exhaustion and a walk that has ended
leaves the last field in place. The position belongs to the caller, so one
descriptor supports repeated, nested, and concurrent walks, including
alongside a Split.iter iterator over the same descriptor. A yielded
canonical String remains live until its actual owning pool is released.
Split words = %"ada lovelace".words();
int cursor = 0;
String word;
while (words.try_next(&cursor, &word)) printf("%s\n", word);
This is what foreach(String word, split) lowers to; Split.iter is the
boxing adapter for every other binder.
Raises: <alloc-fail> while canonicalizing a nonempty field. Null
arguments produce exhaustion without raising.
Source: lib/split.x:243
String
String.lines
Split String.lines(String str)
Returns a lazy cursor over lines in str, with endings removed.
LF, CR, and CRLF end a line, with CRLF counted as one ending. The yielded
fields agree with str.split_lines(0), including empty interior lines and
the rule that a trailing ending does not add a final empty line.
Each yielded field is a canonical String. Distinct fields remain resident
in the active String pool; bracket bulk traversal with
String.pool_retain / String.pool_release and promote retained values
when that residency should be temporary. The cursor borrows str, whose
actual owning pool must remain live through traversal.
Raises: <alloc-fail> when the cursor descriptor cannot be allocated.
An empty String produces an exhausted cursor.
Source: lib/split.x:206
String.split
List String.split(String str, String sep)
Splits str on every occurrence of sep into a List of Strings.
Separators are not coalesced, so adjacent ones produce empty fields and
the result holds one more element than the number of separators found.
An empty field is the empty String, the null pointer. An empty or null
sep yields a one-element List holding str, and splitting the empty
String yields the empty List. The canonical fields and List remain
live
until their actual String and List pools are released.
printf("%s\n", %"a:b:c".split(":").repr());
printf("%s\n", %"a::b".split(":").repr());
Raises: the same causes as String.split_n.
Source: lib/split.x:110
String.split_lines
List String.split_lines(String str, int keep_ends)
Splits str into a List of lines.
LF, CR, and CRLF all end a line, and CRLF counts as one ending. A
nonzero keep_ends leaves each line’s ending attached to it. A trailing
line ending does not produce a final empty line, so text that ends in a
newline yields as many lines as it has endings. A null or empty str
returns nil. The canonical fields and List remain live until their
actual
String and List pools are released.
Raises: <alloc-fail> or <size-limit> while constructing fields or the
result.
Source: lib/split.x:123
String.split_n
List String.split_n(String str, String sep, int max_splits)
Splits str at no more than max_splits separators.
A negative limit splits every occurrence; zero returns str as one field.
A null str returns nil. A null or empty sep returns str as one
field.
The canonical fields and List remain live until their actual String and
List pools are released.
Raises: <alloc-fail> or <size-limit> while constructing the result.
Source: lib/split.x:80
String.splits
Split String.splits(String str, String sep)
Returns a lazy cursor over fields separated by sep.
Separators are not coalesced, so adjacent separators produce empty
fields. The yielded fields agree with str.split(sep). A null or empty
separator yields str once, while an empty str yields nothing.
Each yielded field is a canonical String. Distinct fields remain resident
in the active String pool; bracket bulk traversal with
String.pool_retain / String.pool_release and promote retained values
when that residency should be temporary. The cursor borrows str and
sep; both actual owning pools must remain live through traversal.
Raises: <alloc-fail> when the cursor descriptor cannot be allocated.
Source: lib/split.x:220
String.words
Split String.words(String str)
Returns a lazy cursor over whitespace-delimited words in str.
Runs of C isspace bytes are coalesced, leading and trailing whitespace
is ignored, and no empty String is yielded. str.splits(" ") instead
preserves empty fields around every explicit separator.
Each yielded field is a canonical String. Distinct fields remain resident
in the active String pool; bracket bulk traversal with
String.pool_retain / String.pool_release and promote retained values
when that residency should be temporary. The cursor borrows str, whose
actual owning pool must remain live through traversal.
Raises: <alloc-fail> when the cursor descriptor cannot be allocated.
An empty String produces an exhausted cursor.
Source: lib/split.x:191
Public types
| Type | Kind | Summary |
|---|---|---|
Split | struct | Describes an immutable, repeatable lazy traversal of a borrowed String. |
Split
typedef struct Split *Split
Describes an immutable, repeatable lazy traversal of a borrowed String.
The descriptor is Scope-owned and keeps no position; each caller or
Iter
keeps its own cursor. The input and separator are not retained, so their
actual String pools must remain live through every traversal. No cleanup
is needed before the descriptor’s Scope is released.
Source: lib/split.x:22
Design notes
A Split description is immutable and Scope-owned. It keeps no position;
the caller holds the cursor, so one Split supports repeated, nested, and
concurrent walks. Eager and lazy splitting share the same separator and
line-ending scans.
Tests and examples
make verify (unittest/test-split.x).