lib/string/string.x
Canonical byte strings and core text operations.
Primary API
| Function | Summary |
|---|---|
String.add | Returns str followed by other. |
String.capitalize | Upper-cases the first byte of str and lower-cases the remainder. |
String.contains | Reports whether the bytes of sub occur anywhere in str. |
String.count | Returns the non-overlapping count of sub in str. |
String.dedent | Removes the indentation the text was written with. |
String.endswith | Reports whether str ends with suffix. |
String.filter | Returns the bytes of str accepted by ordinary Var truthiness of fn. |
String.find | Returns the index of the first occurrence of sub in str, or -1. |
String.find_all | Returns each non-overlapping starting index at which sub occurs. |
String.find_within | Returns the first index of sub within str[start:end], or -1. |
String.getindex | Returns the byte at index in str as an int, or -1 if out of range. |
String.getslice | Returns the canonical String s[start:stop:step]. |
String.iter | Initializes dest as a lazy iterator over the bytes of x. |
String.join | Joins strings into one canonical String with sep between elements. |
String.keep | Returns a canonical String containing only bytes found in chars. |
String.len | Returns the byte length of str, excluding the terminating NUL. |
String.lower | Returns str with every upper-case byte lowered. |
String.lstrip | Removes leading bytes found in the C string negChars. |
String.map | Returns str with fn applied to every byte. |
String.new | Returns the canonical String holding the bytes of the C string str. |
String.pad_center | Pads both sides of str to the requested width. |
String.pad_left | Pads the left side of str to the requested width. |
String.pad_right | Pads the right side of str to the requested width. |
String.partition | Splits str at the first sep into a three-element List. |
String.reject | Returns a canonical String after removing bytes found in chars. |
String.remove_prefix | Removes prefix when str starts with it and returns a canonical String. |
String.remove_suffix | Removes suffix when str ends with it and returns a canonical String. |
String.repeat | Returns a canonical String containing count copies of str. |
String.replace | Returns str with every occurrence of old replaced by replacement. |
String.replace_n | Replaces at most max_replacements non-overlapping occurrences of old. |
String.rfind | Returns the index of the last occurrence of sub in str, or -1. |
String.rpartition | Splits str around its final occurrence of sep. |
String.rstrip | Removes trailing bytes found in the C string negChars. |
String.squeeze | Collapses adjacent runs of each byte listed in chars. |
String.startswith | Reports whether str starts with prefix. |
String.strip | Returns str with leading and trailing bytes in negChars removed. |
String.try_next | Writes the next byte, advances cursor, and returns one. |
String.upper | Returns str with every lower-case byte raised. |
String.withindex | Returns a canonical copy of str with the byte at index set. |
String.write_str | Appends str to out unchanged. |
String
String.add
String String.add(String str, String other)
Returns str followed by other.
This implements the add row of protocol Var(String), so it is what
+ on two Strings lowers to, and because the result is interned, ==
on a newly built result is a content comparison. Either operand may be
the empty String, in which case the other pointer is returned unchanged
with its existing ownership and canonical or transient state.
Every concatenation interns its result, so building text by repeated
concatenation in a loop allocates and hashes at every step. Use
Buffer for that, or collect the pieces and call String.join once.
Raises: <size-limit> when the result cannot fit the String
representation. Allocation failures propagate from the owning allocator.
Source: lib/string/building.x:18
String.capitalize
meta native String String.capitalize(String str)
Upper-cases the first byte of str and lower-cases the remainder.
Mapping is bytewise through C’s toupper and tolower. Null, empty, and
unchanged inputs are returned as-is.
Raises: <alloc-fail> while constructing the result.
Source: lib/string/mapping.x:54
String.contains
meta native int String.contains(String str, String sub)
Reports whether the bytes of sub occur anywhere in str.
An empty sub is contained in every String, including the empty one,
so a truth test on user-supplied text should check for emptiness
separately if that matters.
Source: lib/string/search.x:119
String.count
meta native int String.count(String str, String sub)
Returns the non-overlapping count of sub in str.
A null or empty str or sub returns zero.
Source: lib/string/search.x:96
String.dedent
meta native String String.dedent(String str)
Removes the indentation the text was written with.
The prefix is the run of spaces and tabs that opens the first content
line, after one leading newline is dropped. Every following line that
starts with that prefix loses exactly it, so indentation written past the
prefix survives and the block renormalizes as a unit. A line that does not
carry the prefix, including a blank one, is left alone, except that a
final line of only spaces and tabs is removed so the closing quote’s own
indentation does not reach the result. \r\n is preserved because only
the prefix after a newline is removed.
Raises: <alloc-fail> while constructing a changed result. Null input
returns NULL and text with no prefix is returned as-is.
Source: lib/string/splitting.x:62
String.endswith
meta native int String.endswith(String str, String suffix)
Reports whether str ends with suffix.
An empty suffix is a suffix of every String. The comparison is
bytewise, so this is a safe test for a file extension but not for a
case-insensitive one; lower both sides first.
Source: lib/string/search.x:142
String.filter
String String.filter(String str, Func fn)
Returns the bytes of str accepted by ordinary Var truthiness of fn.
Each byte is boxed from char and passed by value. A null or empty str
returns str without invoking the callback. Otherwise fn
is called once per byte from left to right and is not retained.
A null fn raises <bad-arg> on the first invocation.
Raises: whatever Func.apply, fn, or the returned Var’s truth
operation raises, or <alloc-fail> when the result cannot be allocated.
Source: lib/string/mapping.x:81
String.find
meta native int String.find(String str, String sub)
Returns the index of the first occurrence of sub in str, or -1.
The search compares bytes, so an index may land inside a multibyte
sequence. An empty sub matches at index 0. Use String.find_within to
bound the search to a range, or String.rfind to scan from the end.
Source: lib/string/search.x:10
String.find_all
meta native List String.find_all(String str, String sub, int start, int end)
Returns each non-overlapping starting index at which sub occurs.
The search begins at start and uses the same normalized exclusive end
as String.find_within. Null or empty str or sub returns nil. The
result is a canonical List whose cells follow their owning pools.
Raises: <alloc-fail> or <size-limit> while constructing the result.
Source: lib/string/search.x:81
String.find_within
meta native int String.find_within( String str, String sub, int start, int end)
Returns the first index of sub within str[start:end], or -1.
The returned index is absolute and counts from the start of str.
Negative start and end count from the end of str, and both are then
clamped to the String.
An end of -1 is the sentinel for “to the end of str”, not “one byte
before the end”. There is therefore no negative end that excludes only
the last byte; pass a nonnegative end for that. An empty sub matches at
the normalized start.
String text = "abcabc";
printf("%d %d %d\n", text.find_within("c", 0, -1),
text.find_within("c", 0, 2), text.find_within("a", -3, -1));
Source: lib/string/search.x:29
String.getindex
int String.getindex(String str, int index)
Returns the byte at index in str as an int, or -1 if out of range.
This is what str[index] lowers to on a canonical String, so indexing
yields an int byte value. A negative index counts from the end, so -1
is the last byte.
The byte is unsigned, so the result is 0 through 255 on every platform and
-1 means out of range and nothing else. An index at or beyond the length
is out of range.
Source: lib/string/editing.x:83
String.getslice
meta native String String.getslice(String s, int start, int stop, int step)
Returns the canonical String s[start:stop:step].
This is what slice syntax lowers to. stop is exclusive, negative
start and stop count from the end, and a negative step walks
backwards, so s[::-1] reverses. Indices are byte positions, so a
slice can split a multibyte sequence. A full unit-step slice may return
s; other nonempty slices return their canonical String.
Raises: <alloc-fail> while constructing a nonempty result. An empty
range, a range that runs the wrong way for its step, or a step of zero
also returns NULL, the empty String, without raising.
Source: lib/string/editing.x:99
String.iter
Iter String.iter(String x, Iter dest)
Initializes dest as a lazy iterator over the bytes of x.
The caller owns dest; it borrows x, which must remain live through
traversal. A null dest returns NULL, and null x is exhausted. Each pull
yields the next byte as an <i32> Var in index order. The function
retains neither argument.
Foreach may convert each yielded byte to either int or char:
foreach (int byte, "abc") printf("%d\n", byte);
foreach (char ch, "abc") printf("%c\n", ch);
This is byte traversal, not Unicode character iteration.
Source: lib/string/adapters.x:44
String.join
meta native String String.join(String sep, List strings)
Joins strings into one canonical String with sep between elements.
The receiver is the separator, not the sequence, so this reads
sep.join(parts). A null sep joins with nothing between elements.
Empty elements contribute no bytes but still count as positions, so
joining a split result with the same separator reproduces the original
text, adjacent separators included. List elements that are not Strings
convert to the empty String.
Raises: <alloc-fail> when result storage cannot be allocated. A null or
empty List, or an oversized result, also returns NULL, the empty
String, without raising.
Source: lib/string/building.x:83
String.keep
meta native String String.keep(String str, String chars)
Returns a canonical String containing only bytes found in chars.
Null str returns NULL; null chars returns NULL for any nonnull input.
Raises: <alloc-fail> while constructing the result.
Source: lib/string/mapping.x:119
String.len
int String.len(String str)
Returns the byte length of str, excluding the terminating NUL.
Constant time: the length is cached in the String’s private header.
Lengths count bytes, so a multibyte UTF-8 sequence counts once per byte.
On a transient String.malloc buffer this reports the writable byte
count.
The empty String is the null pointer, whose length is 0.
Source: lib/string/storage.x:43
String.lower
meta native String String.lower(String str)
Returns str with every upper-case byte lowered.
Case mapping runs byte by byte through C’s tolower, so it covers
ASCII in the default locale and does not case-fold multibyte text. When
no byte would change, str itself is returned after the unchanged
temporary buffer is released.
Raises: <alloc-fail> while constructing the result.
Source: lib/string/mapping.x:35
String.lstrip
String String.lstrip(String str, char *negChars)
Removes leading bytes found in the C string negChars.
Passing NULL uses " \t\n\v\f\r". The result is canonical; null input
returns NULL and an unchanged input is returned as-is.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/splitting.x:29
String.map
String String.map(String str, Func fn)
Returns str with fn applied to every byte.
Each byte is boxed from char and passed by value. Each result is
converted to int and truncated to the byte that is stored, and that byte
is what is checked, so a result such as 256 raises because its stored byte
would be NUL.
A null or empty str returns str without invoking the callback.
Otherwise fn is called once per byte from left to right and is
not retained. Each result must convert to a non-NUL byte.
A null fn raises <bad-arg> on the first invocation.
Raises: whatever Func.apply, fn, or result conversion raises,
<bad-result> when the converted result is zero, or <alloc-fail> when
the result cannot be allocated.
Source: lib/string/mapping.x:99
String.new
String String.new(const char *str)
Returns the canonical String holding the bytes of the C string str.
The input is borrowed and copied, so str may be a stack buffer and
mutating it afterwards does not disturb the result. Equal nonempty content
visible in the active pool chain yields the same pointer, which is why
== on canonical Strings from that chain is a content comparison. A
detached or sibling pool may hold a distinct equal pointer. Empty input
canonicalizes to the null pointer, the empty String’s only
representation.
Raises: <alloc-fail> when canonical storage cannot be allocated. A null,
empty, or oversized input returns NULL, which is indistinguishable from the
empty String, without raising.
Source: lib/string/storage.x:100
String.pad_center
meta native String String.pad_center(String str, int width, char fill)
Pads both sides of str to the requested width.
Raises: the same causes as String.pad_left.
Source: lib/string/building.x:146
String.pad_left
meta native String String.pad_left(String str, int width, char fill)
Pads the left side of str to the requested width.
Raises: <bad-arg> when fill is NUL, <size-limit> when width
cannot be represented, or <alloc-fail> when result storage cannot be
allocated.
Source: lib/string/building.x:134
String.pad_right
meta native String String.pad_right(String str, int width, char fill)
Pads the right side of str to the requested width.
Raises: the same causes as String.pad_left.
Source: lib/string/building.x:140
String.partition
meta native List String.partition(String str, String sep)
Splits str at the first sep into a three-element List.
The elements are the text before the separator, the separator itself,
and the text after it. When sep does not occur, the result is str
followed by two empty Strings, so the shape is three elements either
way and a caller can destructure it without testing for the separator
first. A leading separator gives an empty first element and a missing
separator gives two empty trailing elements, so compare the middle element
against sep if you need to tell them apart. The result and any new
substrings are canonical and follow their owning List and String pools.
Unchanged str and sep elements are borrowed into the result, so a
transient input must outlive the returned List.
Raises: <alloc-fail> or <size-limit> while constructing the result.
Source: lib/string/splitting.x:117
String.reject
meta native String String.reject(String str, String chars)
Returns a canonical String after removing bytes found in chars.
Null or empty str, or null chars, returns str unchanged.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/mapping.x:130
String.remove_prefix
meta native String String.remove_prefix(String str, String prefix)
Removes prefix when str starts with it and returns a canonical
String.
A null or absent prefix returns str unchanged; removing the complete
String returns NULL.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/splitting.x:89
String.remove_suffix
meta native String String.remove_suffix(String str, String suffix)
Removes suffix when str ends with it and returns a canonical String.
A null or absent suffix returns str unchanged; removing the complete
String returns NULL.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/splitting.x:99
String.repeat
meta native String String.repeat(String str, int count)
Returns a canonical String containing count copies of str.
Null or empty input, a nonpositive count, or an oversized result returns
NULL. A count of one returns str when it is already visible in the active
pool; a transient buffer is copied and interned instead.
Raises: <alloc-fail> while constructing a nonempty result.
Source: lib/string/building.x:42
String.replace
meta native String String.replace( String str, String old, String replacement)
Returns str with every occurrence of old replaced by replacement.
Scanning runs left to right and matches do not overlap: each one
resumes after the text it consumed, so replacing aa in aaaa performs
two replacements, not three. Replaced text is never rescanned, so a
replacement that contains old does not loop. An empty replacement
deletes the matches.
When there is nothing to replace, str itself is returned, so the
result may be the same pointer as the input.
Raises: <alloc-fail> when result storage cannot be allocated. An empty
or null old returns str, and an oversized result returns NULL, without
raising.
Source: lib/string/editing.x:18
String.replace_n
meta native String String.replace_n( String str, String old, String replacement, int max_replacements)
Replaces at most max_replacements non-overlapping occurrences of old.
Scanning proceeds left to right and does not rescan replacement text. A
negative limit replaces all matches; zero, null or empty old, null input,
or no match returns str unchanged. Null replacement deletes matches.
An oversized result returns NULL.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/editing.x:29
String.rfind
meta native int String.rfind(String str, String sub)
Returns the index of the last occurrence of sub in str, or -1.
Scanning runs backwards from the end, and the returned index still
measures from the start of str. An empty sub reports the length of
str, matching after the last byte and mirroring the forward search
reporting 0.
Source: lib/string/search.x:67
String.rpartition
meta native List String.rpartition(String str, String sep)
Splits str around its final occurrence of sep.
The three elements are the text before the separator, the separator itself,
and the text after it. When sep is null or absent, two empty Strings
precede str. New substrings are canonical; the result follows its owning
List and String pools. Unchanged str and sep elements are
borrowed into the result, so a transient input must outlive the returned
List.
Raises: <alloc-fail> or <size-limit> while constructing the result.
Source: lib/string/splitting.x:137
String.rstrip
String String.rstrip(String str, char *negChars)
Removes trailing bytes found in the C string negChars.
Passing NULL uses " \t\n\v\f\r". The result is canonical; null input
returns NULL and an unchanged input is returned as-is.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/splitting.x:42
String.squeeze
meta native String String.squeeze(String str, String chars)
Collapses adjacent runs of each byte listed in chars.
Bytes outside chars are preserved even when repeated. Null or empty
str, or null chars, returns str unchanged.
Raises: <alloc-fail> while constructing a changed result.
Source: lib/string/mapping.x:140
String.startswith
meta native int String.startswith(String str, String prefix)
Reports whether str starts with prefix.
An empty prefix is a prefix of every String. String.remove_prefix
performs the same test and returns the remainder, so there is rarely a
reason to run both.
Source: lib/string/search.x:131
String.strip
String String.strip(String str, char *negChars)
Returns str with leading and trailing bytes in negChars removed.
negChars is a NUL-terminated C string listing the bytes to remove, not
a substring and not a pattern; order and repetition in it are irrelevant.
Passing NULL uses the default whitespace set “ \t\n\v\f\r“. Trimming
stops at each end on the first byte not in the set, and str itself is
returned when nothing is trimmed.
Raises: <alloc-fail> while constructing the result. A String made
entirely of removable bytes trims to NULL, the empty String, without
raising.
Source: lib/string/splitting.x:15
String.try_next
int String.try_next(String str, int &?cursor, int &?out)
Writes the next byte, advances cursor, and returns one.
Initialize the caller-owned cursor to zero. A null String, a null
pointer, a negative cursor, or exhaustion returns zero without changing
cursor or out. This is byte traversal, not Unicode characters.
foreach (int byte, str) and foreach (char ch, str) compile to this
loop.
Source: lib/string/adapters.x:65
String.upper
meta native String String.upper(String str)
Returns str with every lower-case byte raised.
Like String.lower, mapping runs byte by byte through C’s toupper and
covers ASCII in the default locale. str itself is returned when nothing
would change.
Raises: <alloc-fail> while constructing the result.
Source: lib/string/mapping.x:45
String.withindex
meta native String String.withindex(String str, int index, char value)
Returns a canonical copy of str with the byte at index set.
Canonical Strings are immutable, so str is not modified. When the byte
already has value, this may return str; otherwise a new String is
built and interned. Native assignment str[index] = value writes through
shared canonical storage and belongs only on a transient String.malloc
buffer. A negative index counts from the end.
String word = "hello";
String capital = word.withindex(0, 'H');
printf("%s %s\n", word, capital);
Raises: <bad-arg> when value is NUL, which a String cannot contain,
or <alloc-fail> while constructing the result. An out-of-range index
returns str unchanged.
Source: lib/string/editing.x:127
String.write_str
Buffer String.write_str(String str, Buffer out)
Appends str to out unchanged.
A String is already its own display text, so this writes it directly
instead of routing through String.str. Null str is a no-op. The
borrowed out is returned and not retained.
Raises: any cause from Buffer.write.
Source: lib/string/adapters.x:16
Advanced and interop API
| Function | Summary |
|---|---|
String.compare | Compares x and y bytewise, returning negative, zero, or positive. |
String.equal | Reports whether x and y contain the same bytes. |
String.free | Releases a transient String.malloc buffer early. |
String.hash | Returns the content hash of str, or zero for the empty String. |
String.intern | Returns the canonical String for the borrowed bytes of string. |
String.intern_free | Finalizes an owned String.malloc buffer into a canonical String. |
String.malloc | Allocates a transient mutable buffer of len bytes, not a String. |
String.new_fill | Returns the canonical String containing count copies of fill. |
String.new_in | Returns the canonical String for at most length borrowed bytes in pool. |
String.new_len | Returns the canonical String holding at most len bytes of str. |
String.printf | Formats a canonical String from fmt and the trailing arguments. |
String.promote | Moves str from the active pool to its parent and returns the same pointer. |
String.str | Returns str itself as its display String without copying or retaining it. |
String.symbol | Returns the compact Symbol encoded from str, or zero for empty input. |
String
String.compare
meta native int String.compare(String x, String y)
Compares x and y bytewise, returning negative, zero, or positive.
The ordering is C’s strcmp on the raw bytes, so it is neither
locale-aware nor Unicode collation, and only the sign of the result is
meaningful. The empty String, being the null pointer, sorts before
every non-empty String, and two empty Strings compare equal.
Source: lib/string/storage.x:78
String.equal
int String.equal(String x, String y)
Reports whether x and y contain the same bytes.
Interning already makes x == y a content test for two canonical
Strings, so use this when one side may be a transient
String.malloc buffer or when null has to compare cleanly. Two nulls
are equal, since the null pointer is the empty String, and a null
equals no non-empty String.
Source: lib/string/storage.x:66
String.free
meta native void String.free(String str)
Releases a transient String.malloc buffer early.
The pointer is first looked up in the intern table, including the
enclosing pools, and the call does nothing if it is the canonical String
visible from the active pool. Only a transient buffer allocated in the
active pool chain is released; a canonical pointer from a detached or
unrelated pool is not a valid argument.
A null argument is ignored.
Source: lib/string/storage.x:302
String.hash
meta native unsigned String.hash(String str)
Returns the content hash of str, or zero for the empty String.
Canonical Strings use the cached hash; transient buffers are hashed from
their current NUL-terminated contents.
Source: lib/string/storage.x:53
String.intern
meta native Self String.intern(Self string)
Returns the canonical String for the borrowed bytes of string.
This is String.new under another name. The bytes are copied into
canonical storage and the caller keeps ownership of whatever buffer it
passed in, so a stack array or a C library return value is a fine
argument. It is not the finalizer for a String.malloc buffer:
handing one here interns a second copy and leaves the buffer for the
caller to free. Use String.intern_free for an owned buffer.
Raises: <alloc-fail> when canonical storage cannot be allocated. Null
or empty input returns NULL, the empty String, without raising.
Source: lib/string/storage.x:149
String.intern_free
Self String.intern_free(Self string)
Finalizes an owned String.malloc buffer into a canonical String.
This takes ownership. The length and hash are computed from the
buffer’s NUL-terminated contents, then the buffer either becomes the
canonical String for that content or, when an equal canonical String
already exists, is released in favor of the existing one. Either way
the argument must not be used again; keep the return value. Passing an
already canonical String visible in the active pool chain is a harmless
no-op that returns it unchanged. The argument and its storage must be
visible in that chain; a canonical String from a detached or sibling pool
is not valid here because installing its pointer would outlive its storage.
String buf = String.malloc(6);
char *bytes = buf;
for (int i = 0; i < 5; i++) bytes[i] = 'a' + i;
String canonical = buf.intern_free();
printf("%s %d\n", canonical, canonical == "abcde");
Raises: <alloc-fail> when the canonical value cannot be registered. A
null argument returns NULL, and a buffer empty at its first byte is
released and reported as NULL, the empty String, without raising.
Source: lib/string/storage.x:246
String.malloc
String String.malloc(int len)
Allocates a transient mutable buffer of len bytes, not a String.
The byte count includes room for the terminating NUL, so len - 1
bytes are writable and String.len on a fresh buffer reports
len - 1. The buffer is not interned and has no cached hash, so ==
against a canonical String is meaningless until it is finalized. Fill
it with native indexing, then call String.intern_free to canonicalize
and release it, or String.free to discard it. The backing allocation
belongs to the active String/List pool and is invalidated when that
pool is released, even though the caller controls finalization.
String buf = String.malloc(6);
printf("%d writable bytes\n", buf.len());
String.free(buf);
Raises: <alloc-fail> when storage cannot be allocated. A nonpositive or
oversized len returns NULL without raising.
Source: lib/string/storage.x:213
String.new_fill
meta native String String.new_fill(char fill, int count)
Returns the canonical String containing count copies of fill.
Raises: <bad-arg> when fill is NUL, <size-limit> when count is
INT_MAX, because the allocation includes one trailing NUL byte, or
<alloc-fail> when canonical storage cannot be allocated. A nonpositive
count returns NULL without raising.
Source: lib/string/building.x:62
String.new_in
String String.new_in(Pool pool, const char *bytes, int length)
Returns the canonical String for at most length borrowed bytes in
pool.
The active pool does not change. Copying stops at the first NUL. An
existing equal String in pool or an ancestor is returned with that
owner’s lifetime; otherwise the new value is owned by pool. A null
argument, nonpositive length, or empty input returns NULL.
Raises: <alloc-fail>, <size-limit>, or <invariant> while interning.
Source: lib/string/storage.x:132
String.new_len
String String.new_len(const char *str, int len)
Returns the canonical String holding at most len bytes of str.
Copying stops at len bytes or at the first NUL, whichever comes
first, because a String cannot carry embedded NUL bytes:
String.new_len("ab\0cd", 5) is the two-byte String ab. str need
not be NUL-terminated, so it may be bounded C input or a window into a
larger buffer.
Raises: <alloc-fail> when canonical storage cannot be allocated. A null
str, nonpositive len, or leading NUL returns NULL, the empty String,
without raising.
Source: lib/string/storage.x:117
String.printf
String String.printf(String fmt, ...)
Formats a canonical String from fmt and the trailing arguments.
The receiver is the format String, so format-dependent construction reads
%"%-12s %.2f".printf(name, score). Conversions, promotion rules, and
argument matching are C’s, since the work is done by vsnprintf;
canonical Strings are NUL-terminated and satisfy %s directly. Prefer
%"$name has ${name.len()} bytes" when interpolation already says what
you want, and String.format when the arguments must be checked.
Raises: <alloc-fail> when result storage cannot be allocated. An empty
fmt or formatting error also returns NULL without raising. Arguments
that do not match the conversions are undefined behavior as in C.
Source: lib/string/building.x:177
String.promote
Self String.promote(Self str)
Moves str from the active pool to its parent and returns the same
pointer. Empty, transient, and ancestor-owned Strings are returned
unchanged.
Raises: <alloc-fail>, <size-limit>, or <invariant> while recording
the promotion.
Source: lib/string/storage.x:325
String.str
String String.str(String str)
Returns str itself as its display String without copying or retaining
it.
Source: lib/string/adapters.x:8
String.symbol
meta native Symbol String.symbol(String str)
Returns the compact Symbol encoded from str, or zero for empty input.
Symbol’s restricted spelling folds case and _ with -; other spellings
use seven-bit bytes, and input beyond the selected encoding’s capacity is
truncated. Use Symbol.try_new when every byte must be preserved.
Source: lib/string/adapters.x:23
Runtime-internal callables
These callables connect runtime translation units. They are documented for source readers but are not supported as user API.
| Function | Summary |
|---|---|
String.is_permanent | Asks whether str already outlives every canonical String pool. |
String.try_own | Proves str safe beyond every active canonical String pool. |
String
String.is_permanent
int String.is_permanent(String str)
Asks whether str already outlives every canonical String pool.
Returns 1 when str is empty or the outermost pool owns it, and 0 for a
transient buffer or a String a nested pool can still reclaim. Unlike
String.try_own it neither promotes nor allocates, so a caller may ask
about a String it does not own.
Source: lib/string/storage.x:350
String.try_own
int String.try_own(String str)
Proves str safe beyond every active canonical String pool.
Returns 1 when str is empty, already permanent, or can be promoted to
the outermost pool. Returns 0 when no active pool owns it. Promotion
proceeds one pool at a time; if a later step fails, the earlier promotions
remain.
Raises: <alloc-fail>, <size-limit>, or <invariant> while recording a
promotion.
Source: lib/string/storage.x:339
Public types
| Type | Kind | Summary |
|---|---|---|
String | alias | An immutable canonical NUL-terminated byte string, or NULL for empty. |
String
typedef char *String
An immutable canonical NUL-terminated byte string, or NULL for empty.
Equal nonempty contents visible in one String/List pool chain share a
pointer. Assignment borrows that pointer; it does not copy or extend the
owning pool’s lifetime. String.malloc is the mutable exception;
its backing allocation still belongs to the active pool, and must be
finalized with String.intern_free or released with String.free.
Source: lib/string/string.x:29
Design notes
String owns canonical immutable byte strings. Equal nonempty contents in one pool chain share one pointer, the empty String is native zero, and a private header before the bytes holds the exact length and a cached content hash. A String cannot hold an embedded NUL, and every operation here works on bytes, without Unicode character semantics.
A canonical String belongs to the pool that interned it or to an
ancestor, and releasing that pool invalidates it unless it was promoted.
A transient String.malloc buffer belongs to the active pool until it is
interned or freed. Pool storage and registration causes transfer and
never return to the constructing operation.
Tests and examples
make verify (unittest/test-string.x) and make examples (docs-word-count).