Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Strings, Numbers, and Binary Data

Byte strings

Whim strings hold bytes, so Whim\Str uses byte offsets and byte lengths.

length returns uint; searches return null|uint. Search and slice input offsets stay signed, so negative offsets can count from the end. Slice, splice, and comparison lengths use null|uint. A length larger than the remaining bytes clamps to the end. Repeat counts and padding lengths use uint too. Chunk sizes, split limits, and wrap widths use NonZero<uint>.

Inspection functions include length, ord, chr, byte_at, compare, compare_ci, search, search_last, contains, starts_with, and ends_with. Search and containment functions accept a byte offset. The byte checks are is_whitespace, is_digit, is_letter, is_alphanumeric, is_hex_digit, and is_ascii_punctuation. A _ci suffix means ASCII case-insensitive matching.

Slice functions include slice, splice, chunk, split, range, before, after, and their last and case-insensitive forms.

Transform functions include ASCII lowercase, uppercase, capitalize, reverse, repeat, rot13, replacements, prefix and suffix stripping, padding, trimming, shuffling, word splitting, and wrapping.

use Whim\Str;

$words = Str\split('one,two,three', ',');
assert!(Str\join(' + ', $words) == 'one + two + three');
assert!(Str\starts_with('whimsical', 'whim'));
assert!(Str\slice('abcdef', 1, 3u) == 'bcd');
assert!(Str\length('abcdef') == 6u);

Use Encoding\UTF8 before treating unknown bytes as Unicode text.

Unicode text and code points

Unicode\case_fold applies full, locale-independent case folding to valid UTF-8. It can expand one code point into several, such as \u{df} into ss. It throws EncodingException when the string is not valid UTF-8.

Unicode\code_point_at reads a scalar value at a byte offset. Unicode\code_point_before reads the value ending before an offset. They return null at the matching string end and U+FFFD for malformed UTF-8. Str\from_code_point encodes a Unicode\ScalarValue as UTF-8.

Unicode\CodePoint covers all code points from zero through U+10FFFF. Unicode\ScalarValue excludes the surrogate range, which UTF-8 cannot encode.

The other Whim\Unicode functions test integer code points without decoding a string. They check valid scalar values, whitespace, letters, marks, numbers, decimal digits, punctuation, symbols, separators, controls, and case. Every check returns false for an invalid code point.

use Whim\Unicode;

assert!(Unicode\case_fold("Stra\u{df}e") == 'strasse');
assert!(Unicode\code_point_at("\u{1f600}", 0) == 0x1f600);
assert!(Unicode\is_letter(0x4e2d));
assert!(Unicode\is_whitespace(0x3000));
assert!(Unicode\is_punctuation(0x3001));

Integers and floats

Int\try_parse($text), UInt\try_parse($text), and Float\try_parse($text) return null for invalid input. They do not accept a partial number.

UInt\try_parse accepts decimal digits, an optional leading +, and leading zeros. It rejects a minus sign, whitespace, underscores, base prefixes, source suffixes, fractions, exponents, and values above the unsigned maximum. UInt\div(uint $numerator, uint $denominator): uint returns the exact integer quotient and throws DivisionByZeroError for a zero denominator.

use Whim\Math;
use Whim\UInt;

assert!(UInt\try_parse('18446744073709551615') == Math\UINT_MAX);
assert!(UInt\try_parse('42u') == null);
assert!(UInt\div(Math\UINT_MAX, 2u) == 9_223_372_036_854_775_807u);

Float also tests NaN, finite, and infinite values. to_bits and from_bits convert a 64-bit float to its integer bit pattern. to_bytes and from_bytes use an explicit Binary\Endianness.

Math

Whim\Math provides checked integer division, absolute value, clamp, square root, exponent, logarithms, floor, ceiling, round, and trigonometry.

expm1(x) computes exp(x) - 1, and log1p(x) computes ln(1 + x). Both keep accuracy when x is close to zero. log1p(-1.0) returns negative infinity, and inputs below -1.0 return NAN. tanh computes the hyperbolic tangent. All three use native floating-point operations and preserve signed zero.

dot multiplies pairs of floats and adds the products in iteration order. It accepts vectors, tuples, dictionaries, and objects that implement Iterator or ToIterator. Dictionary keys do not affect the pairs. Both inputs must have the same length, or it throws Whim\Unwind\LengthException. Empty inputs return 0.0.

sum and sum_floats accept iterables. min, max, min_by, and max_by return null for no input. mean and median accept arrays because they need their size or more than one pass.

to_base, from_base, and base_convert support bases 2 through 36. to_base accepts non-negative ints and the full uint range. Numeric comparison and aggregate helpers such as min, max, mean, and median accept uints. sum keeps its signed inputs; float-only functions still require float.

The namespace defines integer and float limits plus NAN, INF, E, and PI. Read each limit by its full name: positive minima and lowest signed values use different constants. UINT_MIN and UINT_MAX are 0u and 18_446_744_073_709_551_615u.

Whim\Refine\Uint8, Uint16, and Uint32 accept uints within their bit widths: 0u..=255u, 0u..=65_535u, and 0u..=4_294_967_295u. NonZero<uint> excludes 0u. These types do not accept signed ints. Use uint for the full unsigned 64-bit range.

Ranges

Whim\Range represents full, lower-bound, upper-bound, and two-bound integer ranges. full, from, to, and between build them. Range objects expose their bounds and can create an iterator.

These objects are useful when a runtime value must carry a range. Type ranges such as 1..=10 remain part of the type system.

Binary encoding

Whim\Binary reads and writes signed and unsigned integers of 8, 16, 32, and 64 bits, plus 32-bit and 64-bit floats. Multi-byte functions require Endianness::Big or Endianness::Little.

One-shot encode_* functions return bytes; decode_* functions read bytes and check their exact width. MemoryReader, MemoryWriter, HandleReader, and HandleWriter provide moving cursors. Buffered readers report remaining data; buffered writers return their bytes through toString().

Unsigned decoders and reader methods always return uint, including for zero and small values. Cast the result to int when a signed API requires it; values above INT_MAX fail that cast. Unsigned encoders and writer methods require uints within the chosen width, including the 64-bit methods. All reject values that do not fit. Reader byte counts, skips, cursors, lengths, and remaining-byte counts also use uint.

Use binary APIs for protocol fields and file formats. Do not reverse byte strings by hand.