# Types

> StringZilla for C#

`using StringZilla;`

## Sz

Core StringZilla operations: search, compare, hash, and memory primitives.

```csharp
class Sz
```

## SegmentKind

A tiling segmentation: every byte lands in exactly one segment.

```csharp
enum SegmentKind
```

- `Graphemes`
- `Words`
- `Sentences`
- `LineBreaks`

## NormalForm

Unicode normalization forms, NfkcCasefold being NFKC with full case folding and without default-ignorable codepoints, the Unicode toNFKC_Casefold that caseless keys match on.

```csharp
enum NormalForm
```

- `Nfd` = `0`
- `Nfc` = `1`
- `Nfkd` = `2`
- `Nfkc` = `3`
- `NfkcCasefold` = `4`

## IndexOf

First byte offset of _needle_  in _haystack_ , or -1.

```csharp
long IndexOf(ReadOnlySpan<byte> haystack, ReadOnlySpan<byte> needle);
```

```csharp
long IndexOf(ReadOnlySpan<byte> haystack, byte needle);
```

Like IndexOf(ReadOnlySpan<byte>, ReadOnlySpan<byte>), for a single byte: the first offset of _needle_ , or -1.

Like System.MemoryExtensions.IndexOf<T>(System.ReadOnlySpan<T>,System.ReadOnlySpan<T>), SIMD-accelerated for large inputs. Keywords: find, search, substring, indexof.

## LastIndexOf

Like IndexOf(ReadOnlySpan<byte>, ReadOnlySpan<byte>) from the end: the last byte offset of _needle_ , or -1.

```csharp
long LastIndexOf(
    ReadOnlySpan<byte> haystack,
    ReadOnlySpan<byte> needle);
```

```csharp
long LastIndexOf(ReadOnlySpan<byte> haystack, byte needle);
```

Like LastIndexOf(ReadOnlySpan<byte>, ReadOnlySpan<byte>), for a single byte: the last offset of _needle_ , or -1.

## IndexOfAny

First offset of any byte present in _set_ , or -1.

```csharp
long IndexOfAny(ReadOnlySpan<byte> haystack, ref Byteset set);
```

## LastIndexOfAny

Last offset of any byte present in _set_ , or -1.

```csharp
long LastIndexOfAny(ReadOnlySpan<byte> haystack, ref Byteset set);
```

## Equal

Byte-wise equality.

```csharp
bool Equal(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b);
```

Like System.MemoryExtensions.SequenceEqual<T>(System.ReadOnlySpan<T>,System.ReadOnlySpan<T>).

## Compare

Lexicographic byte comparison: -1, 0, or 1.

```csharp
int Compare(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b);
```

Like System.MemoryExtensions.SequenceCompareTo<T>(System.ReadOnlySpan<T>,System.ReadOnlySpan<T>).

## Hash

Fast 64-bit AES-based hash (SMHasher-quality), with optional _seed_ .

```csharp
ulong Hash(ReadOnlySpan<byte> data, ulong seed = 0);
```

Unlike string.GetHashCode(), this is stable across runs/processes and identical across all StringZilla bindings. For cryptographic hashing use Sha256.

## ByteSum

Sum of all byte values in _data_  as an unsigned 64-bit integer.

```csharp
ulong ByteSum(ReadOnlySpan<byte> data);
```

## CountRunes

Counts Unicode scalar values (codepoints) in UTF-8 _text_ .

```csharp
long CountRunes(ReadOnlySpan<byte> text);
```

Like counting System.Text.Runes, but SIMD-accelerated over UTF-8 bytes with no UTF-16 transcode. Keywords: codepoint, rune count, length.

`CountRunes("你好世界"u8)` is 4; `CountRunes("Hello🌍"u8)` is 6 — the astral emoji is a single scalar.

## SeekRune

Byte offset of the _index_ -th codepoint (0-based), or -1 if fewer exist.

```csharp
long SeekRune(ReadOnlySpan<byte> text, long index);
```

Analogous to string.EnumerateRunes positioning, on UTF-8 bytes.

## Decode

Decodes UTF-8 codepoints into _destination_  (one Int32 scalar each; ill-formed or truncated sequences become U+FFFD).

```csharp
int Decode(ReadOnlySpan<byte> text, Span<int> destination);
```

```csharp
int Decode(
    ReadOnlySpan<byte> text,
    Span<int> destination,
    out long bytesConsumed);
```

As Decode(System.ReadOnlySpan<byte>,System.Span<int>), also reporting how many input bytes were consumed so callers can resume.

Returns the count written, stopping early only when _destination_  fills.

Like System.Text.Rune.DecodeFromUtf8 in bulk, SIMD-accelerated. Emitted values are valid Unicode scalars (incl. U+FFFD): wrap with `new Rune(cp)`.

## DecodeAll

Allocates and returns all codepoints of _text_  as Int32 scalars.

```csharp
int[] DecodeAll(ReadOnlySpan<byte> text);
```

## Segment

Writes the byte lengths of the next segments of _text_  into the caller's _lengths_  and returns the count written.

```csharp
int Segment(
    ReadOnlySpan<byte> text,
    SegmentKind kind,
    Span<long> lengths);
```

Allocation-free. Segments tile the text, each starting where the previous one ended, so resume at the sum of the lengths; only an empty text yields 0.

Graphemes ≈ System.Globalization.StringInfo / System.Globalization.TextElementEnumerator; words/sentences/lines follow UAX-29 / UAX-14. SIMD-accelerated, deterministic, over UTF-8 bytes (no locale, no transcode). Keywords: grapheme, word break, sentence, line break, TextElement, BreakIterator.

Segmentation tiles the text — every byte lands in exactly one segment. By SegmentKind.Graphemes, the flag 🇺🇸 is one cluster spanning two codepoints and "e"+U+0301 (a decomposed é) is one cluster spanning two; by SegmentKind.Words, "Hello, 世界" splits the Latin run from the CJK run.

## CaseFold

Folds into the caller's _destination_  (must hold ≥ text.Length*3 bytes) and returns the bytes written.

```csharp
int CaseFold(ReadOnlySpan<byte> text, Span<byte> destination);
```

```csharp
byte[] CaseFold(ReadOnlySpan<byte> text);
```

Full Unicode case folding (UAX #21, one-to-many, e.g.

Allocation-free.

## UncasedIndexOf

Case-insensitive (full-fold) search: byte offset of the first match, or -1; sets _matchedLength_  (may differ from needle length due to folding).

```csharp
long UncasedIndexOf(
    ReadOnlySpan<byte> haystack,
    ReadOnlySpan<byte> needle,
    out long matchedLength);
```

Fills a gap: no .NET caseless UTF-8 substring search. For repeated searches with the same needle, prefer UncasedNeedle.

## UncasedCompare

Case-insensitive (full-fold) lexicographic comparison: -1, 0, or 1.

```csharp
int UncasedCompare(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b);
```

Fills a gap: no .NET Unicode case-folded ordinal comparison.

## HashMultiseed

Hashes _data_  under each seed, writing results into _hashes_  (must hold ≥ seeds.Length entries).

```csharp
void HashMultiseed(
    ReadOnlySpan<byte> data,
    ReadOnlySpan<ulong> seeds,
    Span<ulong> hashes);
```

```csharp
ulong[] HashMultiseed(
    ReadOnlySpan<byte> data,
    ReadOnlySpan<ulong> seeds);
```

Allocating convenience: returns a fresh array of one hash per seed.

Allocation-free.

## FillRandom

Fills _buffer_  with deterministic pseudo-random bytes derived from _nonce_  (AES-CTR-style; reproducible for the same nonce).

```csharp
void FillRandom(Span<byte> buffer, ulong nonce);
```

## Lookup

Byte-wise table transform: destination[i] = lut[source[i]].

```csharp
void Lookup(
    Span<byte> destination,
    ReadOnlySpan<byte> source,
    ReadOnlySpan<byte> lut);
```

_lut_  must be exactly 256 bytes.

## Normalize

Normalizes into the caller's _destination_  (must hold ≥ text.Length*18 bytes) and returns the bytes written.

```csharp
int Normalize(
    ReadOnlySpan<byte> text,
    NormalForm form,
    Span<byte> destination);
```

```csharp
byte[] Normalize(ReadOnlySpan<byte> text, NormalForm form);
```

Normalizes UTF-8 _text_  to the given form.

Allocation-free.

## IsNormalized

True if _text_  is already in the given normalization form.

```csharp
bool IsNormalized(ReadOnlySpan<byte> text, NormalForm form);
```

Equivalent to string.IsNormalized(System.Text.NormalizationForm).

## ArgSort

Writes the sorting permutation of _items_  into _order_  (must hold ≥ items.Count entries) and returns the count of sorted indices (_top_  if > 0, else items.Count).

```csharp
int ArgSort(
    IReadOnlyList<byte[]> items,
    Span<long> order,
    bool reverse = false,
    long top = 0,
    bool uncased = false);
```

```csharp
long[] ArgSort(
    IReadOnlyList<byte[]> items,
    bool reverse = false,
    long top = 0,
    bool uncased = false);
```

Allocating convenience: returns a fresh permutation array.

```csharp
int ArgSort(
    ReadOnlySpan<byte> text,
    ReadOnlySpan<long> starts,
    ReadOnlySpan<long> lengths,
    Span<long> order,
    bool reverse = false,
    long top = 0,
    bool uncased = false);
```

Sorts the segments of a single buffer in place — given per-segment _starts_  and _lengths_  (as produced by the split iterators), writes their sorting permutation into _order_  and returns the count.

Allocation-free for the result.

Like System.Array.Sort(System.Array) with System.StringComparer.Ordinal, but returns indices and runs over UTF-8 bytes.

## Intersect

Inner-joins two de-duplicated sequences, writing matching index pairs into _firstPositions_  / _secondPositions_  (each must hold ≥ min(a.Count, b.Count) entries) and returns the match count.

```csharp
int Intersect(
    IReadOnlyList<byte[]> a,
    IReadOnlyList<byte[]> b,
    Span<long> firstPositions,
    Span<long> secondPositions,
    ulong seed = 0);
```

Allocation-free for the result.

## EnumerateRunes

Lazily enumerates the Unicode codepoints of _text_  as System.Text.Runes (ill-formed sequences yield U+FFFD).

```csharp
RuneEnumerable EnumerateRunes(ReadOnlySpan<byte> text);
```

Like string.EnumerateRunes, over UTF-8 bytes; batches 64 per native call. Allocation-free; synchronous `foreach` only (the enumerator is a ref struct).

## EnumerateWords

Lazily enumerates UAX-29 word segments as byte-slice views (tiling; no empty segments).

```csharp
SegmentEnumerable EnumerateWords(ReadOnlySpan<byte> text);
```

Like iterating System.Globalization.StringInfo word elements, but over UTF-8 bytes.

## EnumerateGraphemes

Lazily enumerates UAX-29 grapheme clusters as byte-slice views (tiling).

```csharp
SegmentEnumerable EnumerateGraphemes(ReadOnlySpan<byte> text);
```

Like System.Globalization.StringInfo.GetTextElementEnumerator(string), over UTF-8 bytes.

## EnumerateSentences

Lazily enumerates UAX-29 sentences as byte-slice views (tiling).

```csharp
SegmentEnumerable EnumerateSentences(ReadOnlySpan<byte> text);
```

## EnumerateLineBreaks

Lazily enumerates UAX-14 line-break units as byte-slice views (tiling).

```csharp
SegmentEnumerable EnumerateLineBreaks(ReadOnlySpan<byte> text);
```

## Split

Lazily splits _text_  on each occurrence of _separator_ , yielding the segments between separators as byte-slice views.

```csharp
SplitEnumerable Split(
    ReadOnlySpan<byte> text,
    ReadOnlySpan<byte> separator);
```

Empty segments are kept by default (like string.Split(string[],System.StringSplitOptions)); chain `.SkipEmpty()`, `.KeepSeparator()`, or `.WithMaxSplit(n)` to change behaviour.

## RSplit

As Split but scanning from the end; yields the last segment first.

```csharp
SplitEnumerable RSplit(
    ReadOnlySpan<byte> text,
    ReadOnlySpan<byte> separator);
```

## SplitAny

Lazily splits on any byte in _separators_  (like splitting on a character set).

```csharp
SplitEnumerable SplitAny(ReadOnlySpan<byte> text, Byteset separators);
```

## RSplitAny

As SplitAny but scanning from the end.

```csharp
SplitEnumerable RSplitAny(ReadOnlySpan<byte> text, Byteset separators);
```

## EnumerateMatches

Lazily enumerates the byte offsets of every (non-overlapping) match of _needle_  in _haystack_ ; chain `.Overlapping()` for overlaps.

```csharp
MatchEnumerable EnumerateMatches(
    ReadOnlySpan<byte> haystack,
    ReadOnlySpan<byte> needle);
```

Counting the result is the occurrence count. An empty needle matches at every offset, the end included.

## SplitNewlines

Lazily splits on Unicode newline runs, yielding the lines between them.

```csharp
TokenSplitEnumerable SplitNewlines(ReadOnlySpan<byte> text);
```

Chain `.WithSeparators()` for a lossless interleave or `.SkipEmpty()` to drop blanks.

## SplitWhitespaces

Lazily splits on Unicode whitespace runs, yielding the fields between them.

```csharp
TokenSplitEnumerable SplitWhitespaces(ReadOnlySpan<byte> text);
```

## SplitDelimiters

Lazily splits on Unicode delimiter runs (punctuation/symbols/separators).

```csharp
TokenSplitEnumerable SplitDelimiters(ReadOnlySpan<byte> text);
```

## EnumerateUncasedMatches

Lazily enumerates case-insensitive (full-fold) matches of _needle_ , yielding each match's offset and matched length (which may differ from the needle length due to folding, e.g.

```csharp
UncasedMatchEnumerable EnumerateUncasedMatches(
    ReadOnlySpan<byte> haystack,
    ReadOnlySpan<byte> needle);
```

"ß" matching "SS"). Chain `.Overlapping()` for overlapping matches. An empty needle matches at every codepoint boundary, the end included.

## Partition

Splits at the first occurrence of _separator_  into (before, separator, after) views; if absent, returns (_text_ , empty, empty).

```csharp
Partition Partition(
    ReadOnlySpan<byte> text,
    ReadOnlySpan<byte> separator);
```

## RPartition

As Partition but at the last occurrence; if absent, returns (empty, empty, _text_ ).

```csharp
Partition RPartition(
    ReadOnlySpan<byte> text,
    ReadOnlySpan<byte> separator);
```

## CapabilitiesName

Names the capabilities in _capabilities_ , comma-separated, like "serial,haswell".

```csharp
string CapabilitiesName(ulong capabilities);
```

## Byteset

A 256-bit set of byte values.

```csharp
struct Byteset
```

## Add

Adds _value_  to the set.

```csharp
void Add(byte value);
```

## AddRange

Adds every byte of _values_  to the set.

```csharp
void AddRange(ReadOnlySpan<byte> values);
```

## Contains

Returns true if _value_  is in the set.

```csharp
bool Contains(byte value);
```

## Invert

Replaces the set with its complement, so members become non-members and the reverse.

```csharp
void Invert();
```

## FromBytes

Creates a set holding every byte of _values_ .

```csharp
Byteset FromBytes(ReadOnlySpan<byte> values);
```

