Strings and Collections

String Types

Introduction

String is the primary string type used throughout the library, defined as U8String. It stores an owning, read-only UTF-8 value with copy-on-write storage.

Use StringEditor as a local mutable working value for explicit in-place editing or small construction tasks. For parameters, read-only storage, and ordinary transformations, prefer String and its copy-returning operations.

The practical workflow and allocation trade-offs are described in Text in Erbsland Core, Transforming Strings, and Editing Strings in Place.

For a full description of the underlying type, see the string-width variants below.

String Width Variants

Indexed Character Access

The UTF-8 and UTF-16 read-only and editor types support direct character access by native data index and by unit::CpIndex. Native data-index access reads from the given byte or UTF-16 data position. unit::CpIndex access is a convenience for small offsets and may be slow for large strings, because the implementation must iterate from the start to find the requested character position.

All indexed character access follows the charAt signal behavior: the exact end position returns Char::endOfData(), invalid or past-end positions return Char::noCodePoint(), and malformed encoded data is decoded as Char::replacement().

Indexed Sequential Reads

readCharAndAdvance(index) reads the character at a native data index and advances the index to the position after the decoded character. At the exact end position, it returns Char::endOfData() and leaves the index unchanged. For noIndex or a past-end index, it returns Char::noCodePoint() and leaves the index unchanged.

Malformed encoding is returned as Char::replacement() and advances according to the tolerant decoding rules. Call isValidUtf8() before the read loop when a UTF-8-only parser must reject malformed internal text.

readCharAndRetreat(index) treats the index as the position after the character to read. It reads the previous character and retreats the index to that character’s start. This works with an index initialized from indexAt(StringSide::Back) to read backwards from the end of a string. At zero, it returns Char::endOfData() and leaves the index unchanged. For noIndex or a past-end index, it returns Char::noCodePoint() and leaves the index unchanged. Unlike retreat(index), this method does not clamp a past-end index to the end before reading.

Character-Indexed Slices

The UTF-8, UTF-16 and UTF-32 read-only and editor types support direct slicing by unit::CpRange and by StringSide with unit::CpLength. For UTF-8 and UTF-16, character-indexed slices return ranges aligned to decoded code-point boundaries, while the native ByteRange and U16DataRange overloads remain available for raw data-unit slices. Trailing character slices are found from the back of the native data, so requesting the last few code points does not require counting the entire string first. Zero-length, invalid, or out-of-bounds ranges return empty strings. Side-based slices with zero length return an empty string, while infinite length returns the entire string.

Display Width

displayWidth() returns the approximate display width of a string by summing the decoded Char display widths. Unicode control characters, including line breaks, contribute 0.

This is intentionally a simple per-code-point measurement. It does not perform line layout, grapheme-cluster shaping, bidirectional reordering, emoji ZWJ sequence handling, or terminal/font-specific corrections. For text containing line breaks, the result is usually not the width of any rendered line.

Unicode Normalization

The read-only and editor types for all three widths support NFC, NFD, NFKC, and NFKD normalization through an explicit NormalizationForm argument. Read Normalizing Unicode Strings for guidance about choosing a form, compatibility-changing behavior, malformed input, storage reuse, and concatenation.

normalized(form) returns a read-only value of the same width and is the preferred operation in application code. Editors also expose normalize(form) for an explicit in-place editing workflow. They should remain local mutable working values rather than default parameter or read-only storage types. When valid text is already in the requested form, these methods preserve the original shared allocation. Normalization uses constant bounded working memory and creates replacement storage only after the first changed sequence. After decomposition, a canonical sequence with more than 30 consecutive non-starters is replaced completely with one U+FFFD as a defensive input limit.

Sensitive UTF-8 Storage

U8String and U8StringEditor can mark their shared allocation with markAsSensitive(). The mark is one-way and is visible to every alias of the same allocation. Copies, slices, trims, and same-string modified results preserve it, while inserting marked text into an ordinary destination does not change that destination. Conversions to another string width, encoded data, standard-library strings, escaped text, formatted text, and diagnostics produce ordinary unmarked results.

Marking a non-empty literal first materializes shared storage. Storage-less empty strings remain unmarked. Marked allocations are securely erased when replaced or finally released. This facility is best-effort storage hygiene rather than a high-security container or information-flow policy.

Searching

All string find... overloads that accept a start or end position treat a no-index position as invalid input and return the matching noIndex() value immediately.

Boolean Conversion

Every read-only and editor string width provides toBoolean(defaultValue) and toBooleanOrThrow(). Both recognize the complete ASCII-case-insensitive ELCL literals true, on, yes, enabled, false, off, no, and disabled. Empty input, surrounding whitespace, partial matches, and all other text are invalid. toBoolean() returns its supplied default for invalid text, while toBooleanOrThrow() raises ParseError.

String Literals

Introduction

The literal helpers in erbsland::text::literals are the preferred way to write static UTF-8 text in Erbsland Core code. They keep the type of the literal visible, avoid unsafe pointer-and-size pairs in user code, and let read-only APIs refer directly to the original literal storage.

using namespace erbsland::text::literals;

constexpr auto label = u8"Status"_el;        // U8StringLiteral<char8_t>
auto labelText = el::U8String{label};         // owning read-only value
auto labelEditor = el::U8StringEditor{label}; // begin an explicit mutable workflow
labelEditor.append(u8": ready"_el);

Use "_el" when you want a constexpr-capable U8StringLiteral. Pass the literal directly when an API accepts it. Otherwise construct U8String explicitly. Construct U8StringEditor when the literal begins an explicit in-place edit or local construction workflow.

Any String Builder

Introduction

AnyStringBuilder builds UTF-8, UTF-16, or UTF-32 strings through one decoded-character API. It is useful for low-level algorithms that should not care which final string encoding is requested.

The builder stores one owning string internally. The target encoding is selected with StringKind. A default builder uses StringKind::U8, matching the library’s default String encoding.

Basic Usage

Choose the target kind when you create the builder, append decoded characters or Erbsland Core strings, and convert the final result to the string type you need. Single decoded code points can be appended as either Char or char32_t.

auto builder = el::AnyStringBuilder{el::StringKind::U16};

builder.append(U'4');
builder.append(U'2');
builder.append(u8" cafés"_el);

auto result = builder.toU16String();

length() returns the cached decoded code-point length. It is therefore independent of the target encoding’s byte or code-unit size.

Choosing Kind and Capacity

Use the static factories when the target kind should be visible at the creation site. The factories without a capacity are equivalent to the matching StringKind constructor.

auto u8 = el::AnyStringBuilder::u8();
auto u16 = el::AnyStringBuilder::u16();
auto u32 = el::AnyStringBuilder::u32();

When the final size is known approximately, choose the capacity factory once before appending. The encoding-specific factories use the native storage unit of the target string.

auto bytes = el::AnyStringBuilder::u8(el::ByteLength{1024});
auto words = el::AnyStringBuilder::u16(el::U16DataLength{512});
auto codePoints = el::AnyStringBuilder::u32(el::CpLength{256});

withCapacity() is the generic form for code that only has a StringKind. Its capacity is a decoded code-point count. For UTF-8 it reserves up to four bytes per code point, and for UTF-16 it reserves up to two code units per code point. This can reserve more storage than eventually needed, but it keeps the kind-erased API safe and unambiguous.

Appending Text

append() accepts Char, repeated Char values, Erbsland Core string views, and Erbsland Core string literals.

When the source encoding matches the builder kind, the builder uses the existing owning string append operation. This preserves the same behavior as U8StringEditor::append(), U16StringEditor::append(), and U32StringEditor::append().

When the source encoding differs from the builder kind, the source is decoded tolerantly and appended character by character. Malformed encoded data becomes Char::replacement() during this cross-encoding append.

Appending Integers

appendInteger() appends an integer using IntegerFormat. It uses the same formatting implementation as U8String::fromInteger(), U16String::fromInteger(), and U32String::fromInteger().

auto builder = el::AnyStringBuilder{};
builder.appendInteger(255, el::IntegerFormat::hexadecimal().setFlags(el::IntegerFormatFlag::BasePrefix));

Appending Byte Blocks

appendByteBlock() appends a ByteBlock as hexadecimal text. It uses ByteFormat for compact hash strings, separated byte lists, or multi-line memory dumps.

auto builder = el::AnyStringBuilder{};
builder.appendByteBlock(hashBytes);
builder.append(U'\n');
builder.appendByteBlock(memory, el::ByteFormat::memoryDump());

Taking or Copying the Result

The unsuffixed to*String() methods return a completed read-only value and keep the builder usable. For a matching target kind this is a cheap copy-on-write string value.

The unsuffixed take*String() methods return a completed read-only value and reset the builder to an empty string of its original kind. When the requested result matches the builder kind, the internal storage is moved out.

Use an explicit to*StringEditor() or take*StringEditor() method only when the caller intentionally continues with in-place editing or local mutable construction.

Copying Builders

Copying a builder copies the builder state. The copied builders may initially share copy-on-write string storage, but later append operations are independent.

auto first = el::AnyStringBuilder{};
first.append(u8"Hei"_el);

auto second = first;
second.append(U'!');

auto a = first.toU8String();  // "Hei"
auto b = second.toU8String(); // "Hei!"

String Collections

String Width Collections

String Iterators

String Tree

Standard Library Compatibility

Interface

class AnyString

A wrapper that stores a read-only string of any supported width.

Public Functions

AnyString() = default

Create an empty string of an undefined type.

template<impl::AnyStringType tString>
inline AnyString(tString str) noexcept

Create a string of the given type.

inline AnyString(const U8StringLiteral<char> &str) noexcept

Create a read-only string sharing a narrow UTF-8 literal.

inline AnyString(const U8StringLiteral<char8_t> &str) noexcept

Create a read-only string sharing a UTF-8 literal.

inline AnyString(const U16StringLiteral &str) noexcept

Create a read-only string sharing a UTF-16 literal.

inline AnyString(const U32StringLiteral &str) noexcept

Create a read-only string sharing a UTF-32 literal.

inline AnyString(const U8StringEditor &str) noexcept

Create a read-only string from a UTF-8 editor.

inline AnyString(const U16StringEditor &str) noexcept

Create a read-only string from a UTF-16 editor.

inline AnyString(const U32StringEditor &str) noexcept

Create a read-only string from a UTF-32 editor.

AnyString(const AnyStringEditor &str) noexcept

Create a read-only string from an AnyStringEditor.

std::strong_ordering operator<=>(const AnyString &other) const noexcept

Compare two strings by decoded code point.

inline AnyString &operator=(const U8String &str)

Copy UTF-8 string storage into this value.

inline AnyString &operator=(U8String &&str)

Move UTF-8 string storage into this value.

inline AnyString &operator=(const U16String &str)

Copy UTF-16 string storage into this value.

inline AnyString &operator=(U16String &&str)

Move UTF-16 string storage into this value.

inline AnyString &operator=(const U32String &str)

Copy UTF-32 string storage into this value.

inline AnyString &operator=(U32String &&str)

Move UTF-32 string storage into this value.

std::strong_ordering compare(const AnyString &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed encoding with Char::replacement().

The original string widths are preserved and no converted strings are created.

Parameters:
  • other – The string to compare with.

  • compareFn – The optional character comparison function.

Returns:

A three-way comparison result.

inline bool isEmpty() const noexcept

Test if this read-only string is empty.

inline bool noConversionForKind(const StringKind kind) const noexcept

Test if this read-only string does not require conversion to the given target kind.

inline std::optional<StringKind> kind() const noexcept

Get the kind of the underlying read-only string.

Returns no value for empty read-only strings.

inline unit::CpLength characterLength() const noexcept

Count the number of valid and replacement code points in the read-only string.

inline bool isEncodingValid() const noexcept

Test if the underlying read-only string contains only valid code points for its encoding.

inline U8String toU8String() const

Get or convert this read-only string in U8 format.

inline String toString() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline U16String toU16String() const

Get or convert this read-only string in U16 format.

inline U32String toU32String() const

Get or convert this read-only string in U32 format.

class AnyStringBuilder

A decoded-character builder for all string encodings.

The builder creates UTF-8, UTF-16, or UTF-32 strings through one API. Copies keep an independent builder state.

See: Strings and Collections

Public Functions

AnyStringBuilder()

Create an empty UTF-8 string builder.

explicit AnyStringBuilder(StringKind kind)

Create an empty string builder for the requested string kind.

StringKind kind() const noexcept

Get the target string kind.

unit::CpLength length() const noexcept

Get the current decoded code-point length.

bool isEmpty() const noexcept

Test if this builder is empty.

void clear() noexcept

Clear all built text while keeping the target kind.

AnyStringBuilder &append(Char character)

Append one Unicode code point.

AnyStringBuilder &append(char32_t codePoint)

Append one Unicode code point.

AnyStringBuilder &append(Char character, unit::CpLength count)

Append one Unicode code point multiple times.

AnyStringBuilder &append(const U8String &text)

Append a UTF-8 read-only string.

AnyStringBuilder &append(const U8String &text, unit::ItemCount count)

Append a UTF-8 read-only string multiple times.

AnyStringBuilder &append(const U16String &text)

Append a UTF-16 read-only string.

AnyStringBuilder &append(const U16String &text, unit::ItemCount count)

Append a UTF-16 read-only string multiple times.

AnyStringBuilder &append(const U32String &text)

Append a UTF-32 read-only string.

AnyStringBuilder &append(const U32String &text, unit::ItemCount count)

Append a UTF-32 read-only string multiple times.

AnyStringBuilder &append(const U8StringLiteral<char> &text)

Append a UTF-8 char string literal.

AnyStringBuilder &append(const U8StringLiteral<char8_t> &text)

Append a UTF-8 char8_t string literal.

AnyStringBuilder &append(const U16StringLiteral &text)

Append a UTF-16 string literal.

AnyStringBuilder &append(const U32StringLiteral &text)

Append a UTF-32 string literal.

AnyStringBuilder &appendAny(const AnyString &text)

Append an “any” read-only string.

AnyStringBuilder &appendAny(const AnyStringEditor &text)

Append an “any” string.

template<math::AnyIntegerType T>
AnyStringBuilder &appendInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Append an integer using the given format.

template<impl::AnyFloatType T>
AnyStringBuilder &appendFloat(T value, FloatFormat format = FloatFormat::defaultFormat())

Append a floating point number using the given format.

AnyStringBuilder &appendByteBlock(const mem::ByteBlock &bytes, const ByteFormat &format = ByteFormat::defaultFormat())

Append a byte block as hexadecimal text using the given format.

U8String toU8String() const

Create a UTF-8 string copy.

String toString() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

U16String toU16String() const

Create a UTF-16 string copy.

U32String toU32String() const

Create a UTF-32 string copy.

AnyString toAnyString() const

Create an “any” string copy.

U8StringEditor toU8StringEditor() const

Create an editable UTF-8 string copy.

StringEditor toStringEditor() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

U16StringEditor toU16StringEditor() const

Create an editable UTF-16 string copy.

U32StringEditor toU32StringEditor() const

Create an editable UTF-32 string copy.

AnyStringEditor toAnyStringEditor() const

Create an editable type-erased string copy.

template<typename T>
T toEditor() const = delete

Convert the builder content to one of the supported editable string types.

U8String takeU8String()

Move out a UTF-8 string and reset this builder.

String takeString()

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

U16String takeU16String()

Move out a UTF-16 string and reset this builder.

U32String takeU32String()

Move out a UTF-32 string and reset this builder.

AnyString takeAnyString()

Move out “any” string and reset this builder.

U8StringEditor takeU8StringEditor()

Move out an editable UTF-8 string and reset this builder.

StringEditor takeStringEditor()

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

U16StringEditor takeU16StringEditor()

Move out an editable UTF-16 string and reset this builder.

U32StringEditor takeU32StringEditor()

Move out an editable UTF-32 string and reset this builder.

AnyStringEditor takeAnyStringEditor()

Move out an editable type-erased string and reset this builder.

template<>
U8StringEditor toEditor() const

Convert this builder to a UTF-8 string.

template<>
U16StringEditor toEditor() const

Convert this builder to a UTF-16 string.

template<>
U32StringEditor toEditor() const

Convert this builder to a UTF-32 string.

Public Static Functions

static AnyStringBuilder u8()

Create an empty UTF-8 string builder.

static AnyStringBuilder u8(unit::ByteLength capacity)

Create an empty UTF-8 string builder with the given initial byte capacity.

static AnyStringBuilder u16()

Create an empty UTF-16 string builder.

static AnyStringBuilder u16(unit::U16DataLength capacity)

Create an empty UTF-16 string builder with the given initial UTF-16 code-unit capacity.

static AnyStringBuilder u32()

Create an empty UTF-32 string builder.

static AnyStringBuilder u32(unit::CpLength capacity)

Create an empty UTF-32 string builder with the given initial code-point capacity.

static AnyStringBuilder withCapacity(StringKind kind, unit::CpLength capacity)

Create an empty string builder with the given decoded code-point capacity.

static AnyStringBuilder basedOn(const U8String &initial, unit::ByteLength additionalCapacity = {})

Create a UTF-8 builder initialized with text and additional native capacity.

static AnyStringBuilder basedOn(const U16String &initial, unit::U16DataLength additionalCapacity = {})

Create a UTF-16 builder initialized with text and additional native capacity.

static AnyStringBuilder basedOn(const U32String &initial, unit::CpLength additionalCapacity = {})

Create a UTF-32 builder initialized with text and additional native capacity.

class AnyStringEditor

A wrapper that stores a mutable string editor of any supported width.

Converts its contents to a requested read-only string width when needed.

Public Functions

AnyStringEditor() = default

Create an empty string of an undefined type.

template<impl::AnyStringEditorType tString>
inline constexpr AnyStringEditor(tString str)

Create a string of the given type.

inline AnyStringEditor &operator=(const U8StringEditor &str)

Copy an editable UTF-8 string into this value.

inline AnyStringEditor &operator=(U8StringEditor &&str)

Move an editable UTF-8 string into this value.

inline AnyStringEditor &operator=(const U16StringEditor &str)

Copy an editable UTF-16 string into this value.

inline AnyStringEditor &operator=(U16StringEditor &&str)

Move an editable UTF-16 string into this value.

inline AnyStringEditor &operator=(const U32StringEditor &str)

Copy an editable UTF-32 string into this value.

inline AnyStringEditor &operator=(U32StringEditor &&str)

Move an editable UTF-32 string into this value.

inline bool isEmpty() const noexcept

Test if this string is empty.

inline bool noConversionForKind(const StringKind kind) const noexcept

Test if this string does not require conversion to the given target kind.

inline std::optional<StringKind> kind() const noexcept

Get the kind of the underlying string.

Returns no value for empty strings.

inline unit::CpLength characterLength() const noexcept

Count the number of valid and replacement code points in the string.

inline bool isEncodingValid() const noexcept

Test if the underlying string contains only valid code points for its encoding.

inline AnyString toAnyString() const noexcept

Create an owning read-only value sharing the stored editor contents.

inline U8String toU8String() const

Get or convert this string in U8 format.

inline String toString() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline U16String toU16String() const

Get or convert this string in U16 format.

inline U32String toU32String() const

Get or convert this string in U32 format.

constexpr U8StringLiteral<char> erbsland::text::literals::operator""_el(const char *data, const std::size_t size) noexcept

Create a U8StringLiteral from a string literal.

constexpr U8StringLiteral<char8_t> erbsland::text::literals::operator""_el(const char8_t *data, const std::size_t size) noexcept

Create a U8StringLiteral from a string literal.

constexpr U16StringLiteral erbsland::text::literals::operator""_el(const char16_t *data, const std::size_t size) noexcept

Create a U16StringLiteral from a UTF-16 string literal.

constexpr U32StringLiteral erbsland::text::literals::operator""_el(const char32_t *data, const std::size_t size) noexcept

Create a U32StringLiteral from a UTF-32 string literal.

enum class erbsland::text::NormalizationForm : uint8_t

Select a Unicode normalization form.

See: Normalizing Unicode Strings

Values:

enumerator Nfc

Canonical decomposition followed by canonical composition.

enumerator Nfd

Canonical decomposition without composition.

enumerator Nfkc

Compatibility decomposition followed by canonical composition.

enumerator Nfkd

Compatibility decomposition without composition.

typedef U8String erbsland::text::String

The common read-only string used in the library.

enum class erbsland::text::StringBomMode : uint8_t

The mode for handling byte order marks (BOM) at encoded-data boundaries.

Only an initial encoded signature is handled as a BOM. Any subsequent encoded U+FEFF is invalid text content and is handled using the selected EncodingMode.

Values:

enumerator Automatic

Accepts a BOM at the start of decoded byte data.

For StringEncoding::Utf16 and StringEncoding::Utf32 change the byte order if a BOM is found, if no BOM is found, expect little endian byte order. For the StringEncoding::Utf16LittleEndian, StringEncoding::Utf16BigEndian, StringEncoding::Utf32LittleEndian, StringEncoding::Utf32BigEndian modes, throw an exception if a BOM is found with the opposite byte order. Never add a BOM when encoding UTF-8 strings, always add a BOM when encoding UTF-16 and UTF-32 strings.

enumerator Require

Require a BOM at the start of decoded byte data.

Throw an exception if no BOM is found. For StringEncoding::Utf16 and StringEncoding::Utf32 change the byte order if a BOM is found, For the StringEncoding::Utf16LittleEndian, StringEncoding::Utf16BigEndian, StringEncoding::Utf32LittleEndian, StringEncoding::Utf32BigEndian modes, throw an exception if a BOM is found with the opposite byte order. Always add a BOM when encoding strings.

enumerator Reject

Reject a BOM at the start of decoded byte data.

Throw an exception if a BOM is found. Never add a BOM when encoding strings.

template<typename tValue>
using erbsland::text::StringCIHashMap = U8StringCIHashMap<tValue>

The common UTF-8 string-keyed hash map type with case-insensitive key hashing and equality.

typedef U8StringCIHashSet erbsland::text::StringCIHashSet

The common UTF-8 string-keyed hash set type with case-insensitive key hashing and equality.

template<typename tValue>
using erbsland::text::StringCIMap = U8StringCIMap<tValue>

The common UTF-8 string-keyed ordered map type with case-insensitive key comparison.

typedef U8StringCISet erbsland::text::StringCISet

The common UTF-8 string-keyed ordered set type with case-insensitive key comparison.

typedef U8StringEditor erbsland::text::StringEditor

The common UTF-8 editor for explicit in-place editing and local construction tasks.

The common string type used in the library.

Use String for parameters, read-only storage, and ordinary copy-returning transformations.

typedef U8StringEditorList erbsland::text::StringEditorList

The common UTF-8 string list type.

template<typename tValue>
using erbsland::text::StringHashMap = U8StringHashMap<tValue>

The common UTF-8 string-keyed hash map type.

typedef U8StringHashSet erbsland::text::StringHashSet

The common UTF-8 string-keyed hash set type.

typedef U8StringList erbsland::text::StringList

The common UTF-8 read-only string list type.

typedef U8StringLiteral<char> erbsland::text::StringLiteral

The common string literal type.

template<typename tValue>
using erbsland::text::StringMap = U8StringMap<tValue>

The common UTF-8 string-keyed ordered map type.

typedef U8StringSet erbsland::text::StringSet

The common UTF-8 string-keyed ordered set type.

class StringTree

A small structured text tree for diagnostics and debug views.

Public Functions

StringTree()

Create an empty tree.

explicit StringTree(String title)

Create a tree with a title.

bool isEmpty() const noexcept

Test if this tree has no title and no entries.

String title() const noexcept

Access the title.

StringTree &setTitle(String title)

Set the tree title.

StringTree &append(String text)

Append one text line.

StringTree &append(String label, String value)

Append a labeled string value.

StringTree &append(String label, bool value)

Append a labeled boolean value.

template<math::AnyIntegerType T>
StringTree &append(String label, T value, IntegerFormat format = IntegerFormat::defaultFormat())

Append a labeled integer value.

StringTree &append(String label, const StringTree &tree)

Append a labeled subtree.

StringTree &append(String label, StringTree &&tree)

Append a labeled subtree.

StringTree &append(const StringTree &tree)

Append all entries from another tree.

template<std::ranges::input_range Range, typename Convert>
StringTree &appendList(String label, Range &&range, Convert convert)

Append an indexed list.

auto toString(unit::CpLength indentWidth = unit::CpLength{4U}, unit::CpLength initialIndentWidth = unit::CpLength::zero()) const -> String

Convert the tree into formatted text.

class U16String

An owning UTF-16 read-only string with copy-on-write semantics for sequential code-point access.

Use it to store, read and pass string parameters. A U16StringEditor and U16StringLiteral are implicitly convertible to a U16String, no copy involved. Copy, move, slicing, trimming are fast and copy-free operations. Use String for most use cases and U16String only if you need random access to code points or require UTF-16 encoding.

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U16StringConstIterator

The const iterator type for decoded UTF-16 code points.

Public Functions

explicit U16String(std::u16string_view stdString)

Create an owning read-only value by copying a UTF-16 string.

U16String(const U16StringEditor &str) noexcept

Create an owning read-only value sharing data from a UTF-16 string.

U16String(const U16StringLiteral &str) noexcept

Create an owning read-only value sharing a UTF-16 string literal.

std::strong_ordering operator<=>(const U16String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::U16DataIndex index) const noexcept

Access the character at the given start code-unit position.

Convenience call to charAt(unit::U16DataIndex).

Parameters:

index – The UTF-16 data index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char operator[](unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex). This operation may be slow for large strings, as the position must be found by iterating over the string.

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-16 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isValidUtf16() const noexcept

Test if this string is valid UTF-16.

bool startsWith(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U16String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Malformed UTF-16 never matches an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

U16String copy() const

Create a compact copy of this string.

unit::U16DataLength length() const noexcept

Get the UTF-16 code-unit length of this string.

unit::CpLength characterLength() const noexcept

Get the character length of this string.

This method provides the number of code points in the string. Counting follows the tolerant UTF-16 index movement rule documented by U16StringEditor.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::U16DataIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::U16DataIndex startIndex) const noexcept

Access the character at the given start code-unit position.

See: Indexed Character Access

Parameters:

startIndex – The UTF-16 data index to access the character at.

Returns:

The character at the given code-unit position, or a null character if no character can be read there.

Char readCharAndAdvance(unit::U16DataIndex &index) const noexcept

Read the character at the given UTF-16 data index and advance the index.

See: Indexed Character Access

Parameters:

index – The UTF-16 data index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::U16DataIndex &index) const noexcept

Read the character before the given UTF-16 data index and retreat the index.

See: Indexed Character Access

Parameters:

index – The index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

Char charAt(unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

This operation may be slow for large strings, as the position must be found by iterating over the string.

See: Indexed Character Access

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

bool advance(unit::U16DataIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given UTF-16 data index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::U16DataIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given UTF-16 data index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::U16DataIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start UTF-16 data index of the character at a given code-point index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-16 index movement rule documented by U16StringEditor.

Parameters:

index – The code-point index to get the UTF-16 data index for.

Returns:

The start UTF-16 data index of the character at the given code-point index.

unit::CpIndex toCharIndex(unit::U16DataIndex index) const noexcept

Slow: Get the code-point index from a UTF-16 data index.

See: Indexed Character Access

Parameters:

index – The UTF-16 data index to get the code-point index for.

Returns:

The code-point index at the given UTF-16 data index.

U16String slice(unit::U16DataRange range) const noexcept

Return a slice of this string.

Returns a string with a UTF-16 code-unit-based slice of this string. No UTF-16 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The UTF-16 data range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U16String slice(unit::CpRange range) const noexcept

Return a character-indexed slice of this string.

Returns a string with a code-point-based slice of this string. Malformed UTF-16 is decoded according to the tolerant UTF-16 index movement rule documented by U16StringEditor.

Parameters:

range – The code-point range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U16String slice(StringSide side, unit::U16DataLength length) const noexcept

Get the initial or trailing UTF-16 data portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of UTF-16 data units to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U16String slice(StringSide side, unit::U16DataIndex index) const noexcept

Get the UTF-16 data-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. U16DataIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The UTF-16 data index where the back portion starts.

Returns:

The sliced string.

U16String slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing code-point-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of code points to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U16String slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U16String> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U16String, U16String> splitAt(unit::U16DataIndex index) const noexcept

Split this read-only string at a UTF-16 data index.

U16DataIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The UTF-16 data index where the second returned string starts.

Returns:

The two strings before and after the split point.

std::pair<U16String, U16String> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The code-point index where the second returned string starts.

Returns:

The two strings before and after the split point.

U16String trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a string without leading and trailing ASCII whitespace or selected characters.

unit::U16DataIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findFirstOf(const CharSet &characters, unit::U16DataIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-16 data index of the first non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findFirstNotOf(const CharSet &characters, unit::U16DataIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the first non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-16 data index of the last match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findLastOf(const CharSet &characters, unit::U16DataIndex end) const noexcept

Find the last decoded character contained in the given set before the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive UTF-16 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the last match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-16 data index of the last non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findLastNotOf(const CharSet &characters, unit::U16DataIndex end) const noexcept

Find the last decoded character not contained in the given set before the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive UTF-16 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the last non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex find(const U16String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this read-only string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

auto find(const U16String &text, unit::U16DataIndex start, CharCompareFn compareFn = {}) const noexcept -> unit::U16DataIndex

Find text in this read-only string starting at a UTF-16 data index.

Parameters:
  • text – The text to find.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

U16String removed(unit::U16DataRange range) const

Return a copy with a UTF-16 data range removed.

U16String removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U16String removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U16String removedAll(const U16String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-16 text removed.

U16String removedFirst(const U16String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-16 text removed.

U16String kept(unit::U16DataRange range) const

Return a copy keeping only a UTF-16 data range.

U16String kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U16String inserted(unit::U16DataIndex index, const U16String &text) const

Return a copy with text inserted at a UTF-16 data index.

U16String inserted(unit::CpIndex index, const U16String &text) const

Return a copy with text inserted at a character index.

U16String replaced(unit::U16DataRange range, const U16String &text) const

Return a copy with a UTF-16 data range replaced by text.

U16String replaced(unit::CpRange range, const U16String &text) const

Return a copy with a character-based range replaced by text.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

U16String transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U16String normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U16String truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U16String truncated(unit::CpLength maximumWidth, TruncateMode mode, const U16String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U16String aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U16String toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

U16String replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U16String replacedAll(const CharSet &characters, const U16String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {}) const -> U16String

Return a copy with all occurrences of decoded UTF-16 text replaced.

auto replacedFirst(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {}) const -> U16String

Return a copy with the first occurrence of decoded UTF-16 text replaced.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::U16DataLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U16String toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U16String fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U16String fromJoined(std::initializer_list<U16String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-16 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U16String fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U16String fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U16String fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U16String

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U16String &first, U16String &second) noexcept

Swap two strings.

template<typename tValue>
using erbsland::text::U16StringCIHashMap = impl::StringHashMap<U16String, tValue, true>

A UTF-16 string-keyed hash map with case-insensitive key hashing and equality.

typedef impl::StringHashSet<U16String, true> erbsland::text::U16StringCIHashSet

A UTF-16 string-keyed hash set with case-insensitive key hashing and equality.

template<typename tValue>
using erbsland::text::U16StringCIMap = impl::StringMap<U16String, tValue, true>

A UTF-16 string-keyed ordered map with case-insensitive key comparison.

typedef impl::StringSet<U16String, true> erbsland::text::U16StringCISet

A UTF-16 string-keyed ordered set with case-insensitive key comparison.

class U16StringConstIterator

A minimal const iterator for UTF-16 encoded strings.

Public Types

using iterator_category = std::forward_iterator_tag

Standard iterator category for this iterator.

using value_type = Char

Value type returned by dereferencing this iterator.

using difference_type = std::ptrdiff_t

Difference type required by the iterator interface.

using pointer = const Char*

Pointer type used by operator->.

using reference = Char

Reference type used by operator*.

Public Functions

U16StringConstIterator()

Create an invalid iterator that does not point to any string.

bool operator==(const U16StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool operator!=(const U16StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool isValid() const noexcept

Test if this iterator is valid.

Char operator*() const

Access the character at the current position.

This returns Char::null() if the iterator is invalid.

U16StringConstIterator &operator++()

Increment this iterator to the next position.

U16StringConstIterator operator++(int)

Post-increment this iterator to the next position.

const Char *operator->() const

Access the character at the current position through pointer semantics.

This returns nullptr if the iterator is invalid.

class U16StringEditor

An owning UTF-16 string editor with copy-on-write semantics for sequential code-point access.

Use it as a local mutable working value for UTF-16 construction and multi-step editing. Use U16String for storage, read-only access and copy-based transformations. Always creates a copy of the data when constructed from a read-only string. Use U16StringEditor only when the mutable workflow requires UTF-16 encoding.

See: Strings and Collections

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U16StringConstIterator

The const iterator type for decoded UTF-16 code points.

Public Functions

explicit U16StringEditor(std::u16string_view stdString)

Create a copy of the given UTF-16 string.

Parameters:

stdString – The string to copy.

explicit U16StringEditor(const U16StringLiteral &literal)

Create a copy of the given string literal.

Parameters:

literal – The string literal to copy.

explicit U16StringEditor(const U16String &view)

Create a copy of the given read-only string.

The copied data is not shared with the original string.

Parameters:

view – The read-only string to copy.

std::strong_ordering operator<=>(const U16String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::U16DataIndex index) const noexcept

Access the character at the given start code-unit position.

Convenience call to charAt(unit::U16DataIndex).

Parameters:

index – The UTF-16 data index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char operator[](unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex). This operation may be slow for large strings, as the position must be found by iterating over the string.

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-16 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isValidUtf16() const noexcept

Test if this string is valid UTF-16.

bool startsWith(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U16String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U16String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Malformed UTF-16 never matches an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

unit::U16DataLength length() const noexcept

Get the UTF-16 code-unit length of this string.

unit::CpLength characterLength() const noexcept

Get the character length of this string.

This method provides the number of code points in the string. Counting follows the tolerant UTF-16 index movement rule documented by U16StringEditor.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::U16DataIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::U16DataIndex startIndex) const noexcept

Access the character at the given start code-unit position.

See: Indexed Character Access

Parameters:

startIndex – The UTF-16 data index to access the character at.

Returns:

The character at the given code-unit position, or a null character if no character can be read there.

Char readCharAndAdvance(unit::U16DataIndex &index) const noexcept

Read the character at the given UTF-16 data index and advance the index.

See: Indexed Character Access

Parameters:

index – The UTF-16 data index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::U16DataIndex &index) const noexcept

Read the character before the given UTF-16 data index and retreat the index.

See: Indexed Character Access

Parameters:

index – The index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

Char charAt(unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

This operation may be slow for large strings, as the position must be found by iterating over the string.

See: Indexed Character Access

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

bool advance(unit::U16DataIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given UTF-16 data index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::U16DataIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given UTF-16 data index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::U16DataIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start UTF-16 data index of the character at a given code-point index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-16 index movement rule documented by U16StringEditor.

Parameters:

index – The code-point index to get the UTF-16 data index for.

Returns:

The start UTF-16 data index of the character at the given code-point index.

unit::CpIndex toCharIndex(unit::U16DataIndex index) const noexcept

Slow: Get the code-point index from a UTF-16 data index.

See: Indexed Character Access

Parameters:

index – The UTF-16 data index to get the code-point index for.

Returns:

The code-point index at the given UTF-16 data index.

U16StringEditor slice(unit::U16DataRange range) const noexcept

Return a slice of this string.

Returns a string with a UTF-16 code-unit-based slice of this string. No UTF-16 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The UTF-16 data range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U16StringEditor slice(unit::CpRange range) const noexcept

Return a character-indexed slice of this string.

Returns a string with a code-point-based slice of this string. Malformed UTF-16 is decoded according to the tolerant UTF-16 index movement rule documented by U16StringEditor.

Parameters:

range – The code-point range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U16StringEditor slice(StringSide side, unit::U16DataLength length) const noexcept

Get the initial or trailing UTF-16 data portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of UTF-16 data units to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U16StringEditor slice(StringSide side, unit::U16DataIndex index) const noexcept

Get the UTF-16 data-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. U16DataIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The UTF-16 data index where the back portion starts.

Returns:

The sliced string.

U16StringEditor slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing code-point-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of code points to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U16StringEditor slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U16StringEditor> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U16StringEditor, U16StringEditor> splitAt(unit::U16DataIndex index) const noexcept

Split this read-only string at a UTF-16 data index.

U16DataIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The UTF-16 data index where the second returned string starts.

Returns:

The two strings before and after the split point.

std::pair<U16StringEditor, U16StringEditor> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The code-point index where the second returned string starts.

Returns:

The two strings before and after the split point.

U16StringEditor &trim(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {})

Remove leading and trailing ASCII whitespace or selected characters.

U16StringEditor trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a copy without leading and trailing ASCII whitespace or selected characters.

unit::U16DataIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findFirstOf(const CharSet &characters, unit::U16DataIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-16 data index of the first non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findFirstNotOf(const CharSet &characters, unit::U16DataIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the first non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-16 data index of the last match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findLastOf(const CharSet &characters, unit::U16DataIndex end) const noexcept

Find the last decoded character contained in the given set before the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive UTF-16 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the last match, or U16DataIndex::noIndex() if there is no match.

unit::U16DataIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-16 data index of the last non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex findLastNotOf(const CharSet &characters, unit::U16DataIndex end) const noexcept

Find the last decoded character not contained in the given set before the given UTF-16 data index.

Malformed UTF-16 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive UTF-16 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-16 data index of the last non-matching character, or U16DataIndex::noIndex() if there is none.

unit::U16DataIndex find(const U16String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

auto find(const U16String &text, unit::U16DataIndex start, CharCompareFn compareFn = {}) const noexcept -> unit::U16DataIndex

Find text in this string starting at a UTF-16 data index.

Parameters:
  • text – The text to find.

  • start – The UTF-16 data index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The UTF-16 data index of the first match, or U16DataIndex::noIndex() if there is no match.

U16StringEditor &clear() noexcept

Remove all characters from the string.

StringEditor capacity is not changed.

void reset() noexcept

Reset the string to its initial state, clearing all characters and resetting capacity to default.

U16StringEditor &append(const U16String &text, unit::ItemCount count = unit::ItemCount::one())

Append a UTF-16 read-only string one or more times.

U16StringEditor &append(Char character, unit::CpLength count = unit::CpLength::one())

Append one Unicode code point one or more times.

U16StringEditor &remove(unit::U16DataRange range)

Remove a UTF-16 data range.

U16StringEditor &remove(unit::CpRange range)

Remove a character-based range.

U16StringEditor &removeAll(const CharSet &characters)

Remove all characters contained in the set.

U16StringEditor &removeAll(const U16String &text, CharCompareFn compareFn = {})

Remove all occurrences of the given decoded UTF-16 text.

U16StringEditor &removeFirst(const U16String &text, CharCompareFn compareFn = {})

Remove the first occurrence of the given decoded UTF-16 text.

U16StringEditor &keep(unit::U16DataRange range)

Keep only a UTF-16 data range.

U16StringEditor &keep(unit::CpRange range)

Keep only a character-based range.

U16StringEditor &insert(unit::U16DataIndex index, const U16String &text)

Insert text at a UTF-16 data index.

U16StringEditor &insert(unit::CpIndex index, const U16String &text)

Insert text at a character index.

U16StringEditor &replace(unit::U16DataRange range, const U16String &text)

Replace a UTF-16 data range with text.

U16StringEditor &replace(unit::CpRange range, const U16String &text)

Replace a character-based range with text.

U16StringEditor &replaceFirst(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {})

Replace the first occurrence of decoded UTF-16 text.

U16StringEditor &replaceAll(const CharSet &characters, Char replacement)

Replace all characters contained in the set with one character.

U16StringEditor &replaceAll(const CharSet &characters, const U16String &replacement)

Replace all characters contained in the set with text.

U16StringEditor &replaceAll(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {})

Replace all occurrences of decoded UTF-16 text.

U16StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End)

Truncate this string to a maximum decoded code-point width.

U16StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode, const U16String &ellipsis)

Truncate this string to a maximum decoded code-point width, inserting an optional ellipsis.

U16StringEditor removed(unit::U16DataRange range) const

Return a copy with a UTF-16 data range removed.

U16StringEditor removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U16StringEditor removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U16StringEditor removedAll(const U16String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-16 text removed.

U16StringEditor removedFirst(const U16String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-16 text removed.

U16StringEditor kept(unit::U16DataRange range) const

Return a copy keeping only a UTF-16 data range.

U16StringEditor kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U16StringEditor inserted(unit::U16DataIndex index, const U16String &text) const

Return a copy with text inserted at a UTF-16 data index.

U16StringEditor inserted(unit::CpIndex index, const U16String &text) const

Return a copy with text inserted at a character index.

U16StringEditor replaced(unit::U16DataRange range, const U16String &text) const

Return a copy with a UTF-16 data range replaced by text.

U16StringEditor replaced(unit::CpRange range, const U16String &text) const

Return a copy with a character-based range replaced by text.

auto replacedFirst(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {}) const -> U16StringEditor

Return a copy with the first occurrence of decoded UTF-16 text replaced.

U16StringEditor replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U16StringEditor replacedAll(const CharSet &characters, const U16String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U16String &text, const U16String &replacement, CharCompareFn compareFn = {}) const -> U16StringEditor

Return a copy with all occurrences of decoded UTF-16 text replaced.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

U16StringEditor transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U16StringEditor &normalize(NormalizationForm form)

Normalize this string in place using the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Storage is untouched if no change is required.

Parameters:

form – The explicit normalization form to apply.

Returns:

This editor for chaining.

See: Normalizing Unicode Strings

U16StringEditor normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U16StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U16StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode, const U16String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U16StringEditor aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U16StringEditor toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::U16DataLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U16StringEditor toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

void reserve(unit::U16DataLength capacity)

Reserve capacity for this string.

See: Indexed Character Access

void shrinkToFit()

Try to free memory by shrinking the memory to the actual used size.

See: Indexed Character Access

unit::U16DataLength capacity() const noexcept

Get the current storage capacity in UTF-16 code units.

This function returns the reserved capacity available for the string data.

Returns:

The reserved capacity in UTF-16 code units.

unit::ByteLength memoryUsage() const noexcept

Get the current memory usage in bytes.

This function returns an estimation of the actual memory usage, including required management data and alignment. Use this function if you need to monitor memory usage (e.g. for caching). Be aware that through fragmentation and other factors, the actual memory usage may be higher than reported.

Returns:

The estimated memory usage in bytes.

void detach()

Detach the string data.

After a call of this method, you have exclusive access to the string data. Detach is managed automatically, only use this method if you need manual control.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U16StringEditor fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U16StringEditor fromJoined(std::initializer_list<U16String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-16 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U16StringEditor fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U16StringEditor fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U16StringEditor fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U16StringEditor

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U16StringEditor &first, U16StringEditor &second) noexcept

Swap two strings.

typedef impl::StringList<U16StringEditor> erbsland::text::U16StringEditorList

A list of UTF-16 strings.

template<typename tValue>
using erbsland::text::U16StringHashMap = impl::StringHashMap<U16String, tValue, false>

A UTF-16 string-keyed hash map.

typedef impl::StringHashSet<U16String, false> erbsland::text::U16StringHashSet

A UTF-16 string-keyed hash set.

typedef impl::StringList<U16String> erbsland::text::U16StringList

A list of UTF-16 read-only strings.

class U16StringLiteral

A thin wrapper around a UTF-16 string literal.

This class provides a safe and efficient way to work with UTF-16 string literals. It allows work with literals that are only copied if a modification is required.

Public Functions

template<std::size_t N>
inline explicit consteval U16StringLiteral(const char16_t (&data)[N]) noexcept

Create a new U16StringCharLiteral from a UTF-16 string char16_t literal.

inline bool isEmpty() const noexcept

Test if this string is empty.

inline bool isValidUtf16() const noexcept

Test if this string is valid UTF-16.

inline unit::U16DataLength length() const noexcept

Get the UTF-16 code-unit length of this string.

inline unit::CpLength characterLength() const noexcept

Get the code-point length of this string.

inline unit::U16DataIndex indexAt(const StringSide side) const noexcept

Get the index for one side of the string.

template<typename tValue>
using erbsland::text::U16StringMap = impl::StringMap<U16String, tValue, false>

A UTF-16 string-keyed ordered map.

typedef impl::StringSet<U16String, false> erbsland::text::U16StringSet

A UTF-16 string-keyed ordered set.

class U32String

An owning UTF-32 read-only string with copy-on-write semantics for random code-point access.

Use it to store, read and pass string parameters. A U32StringEditor and U32StringLiteral are implicitly convertible to a U32String, no copy involved. Copy, move, slicing, trimming are fast and copy-free operations. Use String for most use cases and U32String only if you need random access to code points or require UTF-32 encoding.

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U32StringConstIterator

The const iterator type for decoded UTF-32 code points.

Public Functions

explicit U32String(std::u32string_view stdString)

Create an owning read-only value by copying a UTF-32 string.

U32String(const U32StringEditor &str) noexcept

Create an owning read-only value sharing data from a UTF-32 string.

U32String(const U32StringLiteral &str) noexcept

Create an owning read-only value sharing a UTF-32 string literal.

std::strong_ordering operator<=>(const U32String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::CpIndex index) const noexcept

Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex).

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-32 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isValidUtf32() const noexcept

Test if this string is valid UTF-32.

bool startsWith(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U32String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Invalid Unicode values never match an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

U32String copy() const

Create a compact copy of this string.

unit::CpLength length() const noexcept

Get the UTF-32 code-unit length of this string.

unit::CpLength characterLength() const noexcept

Get the UTF-32 code-unit length of this string.

This is an alias for length() to allow using characterLength() in templates.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::CpIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::CpIndex startIndex) const noexcept

Access the character at the given start code-unit position.

See: Indexed Character Access

Parameters:

startIndex – The UTF-32 data index to access the character at.

Returns:

The character at the given code-unit position, or a null character if no character can be read there.

Char readCharAndAdvance(unit::CpIndex &index) const noexcept

Read the character at the given UTF-32 data index and advance the index.

See: Indexed Character Access

Parameters:

index – The UTF-32 data index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::CpIndex &index) const noexcept

Read the character before the given UTF-32 data index and retreat the index.

See: Indexed Character Access

Parameters:

index – The index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

bool advance(unit::CpIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given UTF-32 data index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::CpIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given UTF-32 data index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::CpIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start UTF-32 data index of the character at a given code-point index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-32 index movement rule documented by U32StringEditor.

Parameters:

index – The code-point index to get the UTF-32 data index for.

Returns:

The start UTF-32 data index of the character at the given code-point index.

unit::CpIndex toCharIndex(unit::CpIndex index) const noexcept

Slow: Get the code-point index from a UTF-32 data index.

See: Indexed Character Access

Parameters:

index – The UTF-32 data index to get the code-point index for.

Returns:

The code-point index at the given UTF-32 data index.

U32String slice(unit::CpRange range) const noexcept

Return a slice of this string.

Returns a string with a UTF-32 code-unit-based slice of this string. No UTF-32 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The UTF-32 data range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U32String slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing UTF-32 data portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of UTF-32 data units to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U32String slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U32String> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U32String, U32String> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a UTF-32 data/code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The index where the second returned string starts.

Returns:

The two strings before and after the split point.

U32String trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a string without leading and trailing ASCII whitespace or selected characters.

unit::CpIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-32 data index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findFirstOf(const CharSet &characters, unit::CpIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The UTF-32 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-32 data index of the first non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findFirstNotOf(const CharSet &characters, unit::CpIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The UTF-32 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the first non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-32 data index of the last match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findLastOf(const CharSet &characters, unit::CpIndex end) const noexcept

Find the last decoded character contained in the given set before the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive UTF-32 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the last match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-32 data index of the last non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findLastNotOf(const CharSet &characters, unit::CpIndex end) const noexcept

Find the last decoded character not contained in the given set before the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive UTF-32 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the last non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex find(const U32String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this read-only string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The code point index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex find(const U32String &text, unit::CpIndex start, CharCompareFn compareFn = {}) const noexcept

Find text in this read-only string starting at a code point index.

Parameters:
  • text – The text to find.

  • start – The code point index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The code point index of the first match, or CpIndex::noIndex() if there is no match.

U32String removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U32String removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U32String removedAll(const U32String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-32 text removed.

U32String removedFirst(const U32String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-32 text removed.

U32String kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U32String inserted(unit::CpIndex index, const U32String &text) const

Return a copy with text inserted at a character index.

U32String replaced(unit::CpRange range, const U32String &text) const

Return a copy with a character-based range replaced by text.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

U32String transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U32String normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U32String truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U32String truncated(unit::CpLength maximumWidth, TruncateMode mode, const U32String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U32String aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U32String toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

U32String replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U32String replacedAll(const CharSet &characters, const U32String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {}) const -> U32String

Return a copy with all occurrences of decoded UTF-32 text replaced.

auto replacedFirst(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {}) const -> U32String

Return a copy with the first occurrence of decoded UTF-32 text replaced.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::CpLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U32String toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U32String fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U32String fromJoined(std::initializer_list<U32String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-32 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U32String fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U32String fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U32String fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U32String

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U32String &first, U32String &second) noexcept

Swap two strings.

template<typename tValue>
using erbsland::text::U32StringCIHashMap = impl::StringHashMap<U32String, tValue, true>

A UTF-32 string-keyed hash map with case-insensitive key hashing and equality.

typedef impl::StringHashSet<U32String, true> erbsland::text::U32StringCIHashSet

A UTF-32 string-keyed hash set with case-insensitive key hashing and equality.

template<typename tValue>
using erbsland::text::U32StringCIMap = impl::StringMap<U32String, tValue, true>

A UTF-32 string-keyed ordered map with case-insensitive key comparison.

typedef impl::StringSet<U32String, true> erbsland::text::U32StringCISet

A UTF-32 string-keyed ordered set with case-insensitive key comparison.

class U32StringConstIterator

A minimal const iterator for UTF-32 encoded strings.

Public Types

using iterator_category = std::forward_iterator_tag

Standard iterator category for this iterator.

using value_type = Char

Value type returned by dereferencing this iterator.

using difference_type = std::ptrdiff_t

Difference type required by the iterator interface.

using pointer = const Char*

Pointer type used by operator->.

using reference = Char

Reference type used by operator*.

Public Functions

U32StringConstIterator()

Create an invalid iterator that does not point to any string.

bool operator==(const U32StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool operator!=(const U32StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool isValid() const noexcept

Test if this iterator is valid.

Char operator*() const

Access the character at the current position.

This returns Char::null() if the iterator is invalid.

U32StringConstIterator &operator++()

Increment this iterator to the next position.

U32StringConstIterator operator++(int)

Post-increment this iterator to the next position.

const Char *operator->() const

Access the character at the current position through pointer semantics.

This returns nullptr if the iterator is invalid.

class U32StringEditor

An owning UTF-32 string editor with copy-on-write semantics for random code-point access.

Use it as a local mutable working value for UTF-32 construction and multi-step editing. Use U32String for storage, read-only access and copy-based transformations. Always creates a copy of the data when constructed from a read-only string. Use U32StringEditor only when the mutable workflow requires UTF-32 encoding.

See: Strings and Collections

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U32StringConstIterator

The const iterator type for decoded UTF-32 code points.

Public Functions

explicit U32StringEditor(std::u32string_view stdString)

Create a copy of the given UTF-32 string.

Parameters:

stdString – The string to copy.

explicit U32StringEditor(const U32StringLiteral &literal)

Create a copy of the given string literal.

Parameters:

literal – The string literal to copy.

explicit U32StringEditor(const U32String &view)

Create a copy of the given read-only string.

The copied data is not shared with the original string.

Parameters:

view – The read-only string to copy.

std::strong_ordering operator<=>(const U32String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::CpIndex index) const noexcept

Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex).

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-32 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isValidUtf32() const noexcept

Test if this string is valid UTF-32.

bool startsWith(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U32String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U32String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Invalid Unicode values never match an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

unit::CpLength length() const noexcept

Get the UTF-32 code-unit length of this string.

unit::CpLength characterLength() const noexcept

Get the UTF-32 code-unit length of this string.

This is an alias for length() to allow using characterLength() in templates.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::CpIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::CpIndex startIndex) const noexcept

Access the character at the given start code-unit position.

See: Indexed Character Access

Parameters:

startIndex – The UTF-32 data index to access the character at.

Returns:

The character at the given code-unit position, or a null character if no character can be read there.

Char readCharAndAdvance(unit::CpIndex &index) const noexcept

Read the character at the given UTF-32 data index and advance the index.

See: Indexed Character Access

Parameters:

index – The UTF-32 data index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::CpIndex &index) const noexcept

Read the character before the given UTF-32 data index and retreat the index.

See: Indexed Character Access

Parameters:

index – The index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

bool advance(unit::CpIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given UTF-32 data index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::CpIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given UTF-32 data index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::CpIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start UTF-32 data index of the character at a given code-point index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-32 index movement rule documented by U32StringEditor.

Parameters:

index – The code-point index to get the UTF-32 data index for.

Returns:

The start UTF-32 data index of the character at the given code-point index.

unit::CpIndex toCharIndex(unit::CpIndex index) const noexcept

Slow: Get the code-point index from a UTF-32 data index.

See: Indexed Character Access

Parameters:

index – The UTF-32 data index to get the code-point index for.

Returns:

The code-point index at the given UTF-32 data index.

U32StringEditor slice(unit::CpRange range) const noexcept

Return a slice of this string.

Returns a string with a UTF-32 code-unit-based slice of this string. No UTF-32 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The UTF-32 data range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U32StringEditor slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing UTF-32 data portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of UTF-32 data units to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U32StringEditor slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U32StringEditor> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U32StringEditor, U32StringEditor> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a UTF-32 data/code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The index where the second returned string starts.

Returns:

The two strings before and after the split point.

U32StringEditor &trim(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {})

Remove leading and trailing ASCII whitespace or selected characters.

U32StringEditor trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a copy without leading and trailing ASCII whitespace or selected characters.

unit::CpIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-32 data index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findFirstOf(const CharSet &characters, unit::CpIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The UTF-32 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-32 data index of the first non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findFirstNotOf(const CharSet &characters, unit::CpIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The UTF-32 data index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the first non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The UTF-32 data index of the last match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findLastOf(const CharSet &characters, unit::CpIndex end) const noexcept

Find the last decoded character contained in the given set before the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive UTF-32 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the last match, or CpIndex::noIndex() if there is no match.

unit::CpIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The UTF-32 data index of the last non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex findLastNotOf(const CharSet &characters, unit::CpIndex end) const noexcept

Find the last decoded character not contained in the given set before the given UTF-32 data index.

Malformed UTF-32 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive UTF-32 data index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The UTF-32 data index of the last non-matching character, or CpIndex::noIndex() if there is none.

unit::CpIndex find(const U32String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The code point index of the first match, or CpIndex::noIndex() if there is no match.

unit::CpIndex find(const U32String &text, unit::CpIndex start, CharCompareFn compareFn = {}) const noexcept

Find text in this string starting at a code point index.

Parameters:
  • text – The text to find.

  • start – The code point index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The code point index of the first match, or CpIndex::noIndex() if there is no match.

U32StringEditor &clear() noexcept

Remove all characters from the string.

StringEditor capacity is not changed.

void reset() noexcept

Reset the string to its initial state, clearing all characters and resetting capacity to default.

U32StringEditor &append(const U32String &text, unit::ItemCount count = unit::ItemCount::one())

Append a UTF-32 read-only string one or more times.

U32StringEditor &append(Char character, unit::CpLength count = unit::CpLength::one())

Append one Unicode code point one or more times.

U32StringEditor &remove(unit::CpRange range)

Remove a character-based range.

U32StringEditor &removeAll(const CharSet &characters)

Remove all characters contained in the set.

U32StringEditor &removeAll(const U32String &text, CharCompareFn compareFn = {})

Remove all occurrences of the given decoded UTF-32 text.

U32StringEditor &removeFirst(const U32String &text, CharCompareFn compareFn = {})

Remove the first occurrence of the given decoded UTF-32 text.

U32StringEditor &keep(unit::CpRange range)

Keep only a character-based range.

U32StringEditor &insert(unit::CpIndex index, const U32String &text)

Insert text at a character index.

U32StringEditor &replace(unit::CpRange range, const U32String &text)

Replace a character-based range with text.

U32StringEditor &replaceFirst(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {})

Replace the first occurrence of decoded UTF-32 text.

U32StringEditor &replaceAll(const CharSet &characters, Char replacement)

Replace all characters contained in the set with one character.

U32StringEditor &replaceAll(const CharSet &characters, const U32String &replacement)

Replace all characters contained in the set with text.

U32StringEditor &replaceAll(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {})

Replace all occurrences of decoded UTF-32 text.

U32StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End)

Truncate this string to a maximum decoded code-point width.

U32StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode, const U32String &ellipsis)

Truncate this string to a maximum decoded code-point width, inserting an optional ellipsis.

U32StringEditor removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U32StringEditor removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U32StringEditor removedAll(const U32String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-32 text removed.

U32StringEditor removedFirst(const U32String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-32 text removed.

U32StringEditor kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U32StringEditor inserted(unit::CpIndex index, const U32String &text) const

Return a copy with text inserted at a character index.

U32StringEditor replaced(unit::CpRange range, const U32String &text) const

Return a copy with a character-based range replaced by text.

auto replacedFirst(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {}) const -> U32StringEditor

Return a copy with the first occurrence of decoded UTF-32 text replaced.

U32StringEditor replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U32StringEditor replacedAll(const CharSet &characters, const U32String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U32String &text, const U32String &replacement, CharCompareFn compareFn = {}) const -> U32StringEditor

Return a copy with all occurrences of decoded UTF-32 text replaced.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

U32StringEditor transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U32StringEditor &normalize(NormalizationForm form)

Normalize this string in place using the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Storage is untouched if no change is required.

Parameters:

form – The explicit normalization form to apply.

Returns:

This editor for chaining.

See: Normalizing Unicode Strings

U32StringEditor normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U32StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U32StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode, const U32String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U32StringEditor aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U32StringEditor toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::CpLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U32StringEditor toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

void reserve(unit::CpLength capacity)

Reserve capacity for this string.

See: Indexed Character Access

void shrinkToFit()

Try to free memory by shrinking the memory to the actual used size.

See: Indexed Character Access

unit::CpLength capacity() const noexcept

Get the current storage capacity in UTF-32 code units.

This function returns the reserved capacity available for the string data.

Returns:

The reserved capacity in UTF-32 code units.

unit::ByteLength memoryUsage() const noexcept

Get the current memory usage in bytes.

This function returns an estimation of the actual memory usage, including required management data and alignment. Use this function if you need to monitor memory usage (e.g. for caching). Be aware that through fragmentation and other factors, the actual memory usage may be higher than reported.

Returns:

The estimated memory usage in bytes.

void detach()

Detach the string data.

After a call of this method, you have exclusive access to the string data. Detach is managed automatically, only use this method if you need manual control.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U32StringEditor fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U32StringEditor fromJoined(std::initializer_list<U32String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-32 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U32StringEditor fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U32StringEditor fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U32StringEditor fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U32StringEditor

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U32StringEditor &first, U32StringEditor &second) noexcept

Swap two strings.

typedef impl::StringList<U32StringEditor> erbsland::text::U32StringEditorList

A list of UTF-32 strings.

template<typename tValue>
using erbsland::text::U32StringHashMap = impl::StringHashMap<U32String, tValue, false>

A UTF-32 string-keyed hash map.

typedef impl::StringHashSet<U32String, false> erbsland::text::U32StringHashSet

A UTF-32 string-keyed hash set.

typedef impl::StringList<U32String> erbsland::text::U32StringList

A list of UTF-32 read-only strings.

class U32StringLiteral

A thin wrapper around a UTF-32 string literal.

This class provides a safe and efficient way to work with UTF-32 string literals. It allows work with literals that are only copied if a modification is required.

Public Functions

template<std::size_t N>
inline explicit consteval U32StringLiteral(const char32_t (&data)[N]) noexcept

Create a new U32StringCharLiteral from a UTF-32 string char32_t literal.

inline bool isEmpty() const noexcept

Test if this string is empty.

inline bool isValidUtf32() const noexcept

Test if this string is valid UTF-32.

inline unit::CpLength length() const noexcept

Get the UTF-32 code-unit length of this string.

inline unit::CpLength characterLength() const noexcept

Get the UTF-32 code-unit length of this string.

inline unit::CpIndex indexAt(const StringSide side) const noexcept

Get the index for one side of the string.

template<typename tValue>
using erbsland::text::U32StringMap = impl::StringMap<U32String, tValue, false>

A UTF-32 string-keyed ordered map.

typedef impl::StringSet<U32String, false> erbsland::text::U32StringSet

A UTF-32 string-keyed ordered set.

class U8String

An owning UTF-8 read-only string with copy-on-write semantics for sequential code-point access.

Use it to store, read and pass string parameters. Use the String alias in user code and only U8String if UTF-8 encoding matters. A StringEditor and StringLiteral are implicitly convertible to a String, no copy involved. Copy, move, slicing, trimming are fast and copy-free operations.

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U8StringConstIterator

The const iterator type for decoded UTF-8 code points.

Public Functions

explicit U8String(std::string_view stdString)

Create an owning read-only value by copying a narrow UTF-8 string.

explicit U8String(std::u8string_view stdString)

Create an owning read-only value by copying a UTF-8 string.

U8String(const U8StringEditor &str) noexcept

Create an owning read-only value sharing data from a UTF-8 string.

U8String(const U8StringLiteral<char> &str) noexcept

Create an owning read-only value sharing a narrow UTF-8 string literal.

U8String(const U8StringLiteral<char8_t> &str) noexcept

Create an owning read-only value sharing a UTF-8 string literal.

std::strong_ordering operator<=>(const U8String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::ByteIndex index) const noexcept

Access the character at the given start byte position.

Convenience call to charAt(unit::ByteIndex).

Parameters:

index – The byte index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char operator[](unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex). This operation may be slow for large strings, as the position must be found by iterating over the string.

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-8 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isSensitive() const noexcept

Test if this string’s shared UTF-8 allocation is marked as sensitive.

void markAsSensitive() noexcept

Mark this string’s complete shared UTF-8 allocation as sensitive.

This mark is one-way and is observed by every string sharing the allocation.

bool isValidUtf8() const noexcept

Test if this string is valid UTF-8.

bool startsWith(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U8String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Malformed UTF-8 never matches an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

U8String copy() const

Create a compact copy of this string.

unit::ByteLength length() const noexcept

Get the byte length of this string.

unit::CpLength characterLength() const noexcept

Get the character length of this string.

This method provides the number of code points in the string. Counting follows the tolerant UTF-8 index movement rule documented by U8StringEditor.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::ByteIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::ByteIndex startIndex) const noexcept

Access the character at the given start byte position.

See: Indexed Character Access

Parameters:

startIndex – The byte index to access the character at.

Returns:

The character at the given index, or a null character if no character can be read there.

Char readCharAndAdvance(unit::ByteIndex &index) const noexcept

Read the character at the given byte index and advance the index.

See: Indexed Character Access

Parameters:

index – The byte index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::ByteIndex &index) const noexcept

Read the character before the given byte index and retreat the index.

See: Indexed Character Access

Parameters:

index – The byte index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

Char charAt(unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

This operation may be slow for large strings, as the position must be found by iterating over the string.

See: Indexed Character Access

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

bool advance(unit::ByteIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given byte index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::ByteIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given byte index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::ByteIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start byte index of the character at a given char index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-8 index movement rule documented by U8StringEditor.

Parameters:

index – The char index to get the byte index for.

Returns:

The start byte index of the character at the given char index.

unit::CpIndex toCharIndex(unit::ByteIndex index) const noexcept

Slow: Get the character index from a byte index.

See: Indexed Character Access

Parameters:

index – The byte index to get the character index for.

Returns:

The character index at the given byte index.

U8String slice(unit::ByteRange range) const noexcept

Return a slice of this string.

Returns a string with a byte-based slice of this string. No UTF-8 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The byte range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U8String slice(unit::CpRange range) const noexcept

Return a character-indexed slice of this string.

Returns a string with a code-point-based slice of this string. Malformed UTF-8 is decoded according to the tolerant UTF-8 index movement rule documented by U8StringEditor.

Parameters:

range – The code-point range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U8String slice(StringSide side, unit::ByteLength length) const noexcept

Get the initial or trailing byte-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of bytes to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U8String slice(StringSide side, unit::ByteIndex index) const noexcept

Get the byte-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. ByteIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The byte index where the back portion starts.

Returns:

The sliced string.

U8String slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing code-point-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of bytes to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U8String slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U8String> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U8String, U8String> splitAt(unit::ByteIndex index) const noexcept

Split this read-only string at a byte index.

ByteIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The byte index where the second returned string starts.

Returns:

The two strings before and after the split point.

std::pair<U8String, U8String> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The code-point index where the second returned string starts.

Returns:

The two strings before and after the split point.

U8String trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a string without leading and trailing ASCII whitespace or selected characters.

unit::ByteIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findFirstOf(const CharSet &characters, unit::ByteIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The byte index of the first non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findFirstNotOf(const CharSet &characters, unit::ByteIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The byte index of the first non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The byte index of the last match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findLastOf(const CharSet &characters, unit::ByteIndex end) const noexcept

Find the last decoded character contained in the given set before the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive byte index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The byte index of the last match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The byte index of the last non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findLastNotOf(const CharSet &characters, unit::ByteIndex end) const noexcept

Find the last decoded character not contained in the given set before the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive byte index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The byte index of the last non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex find(const U8String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this read-only string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex find(const U8String &text, unit::ByteIndex start, CharCompareFn compareFn = {}) const noexcept

Find text in this read-only string starting at a byte index.

Parameters:
  • text – The text to find.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

U8String removed(unit::ByteRange range) const

Return a copy with a byte-based range removed.

U8String removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U8String removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U8String removedAll(const U8String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-8 text removed.

U8String removedFirst(const U8String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-8 text removed.

U8String kept(unit::ByteRange range) const

Return a copy keeping only a byte-based range.

U8String kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U8String inserted(unit::ByteIndex index, const U8String &text) const

Return a copy with text inserted at a byte index.

U8String inserted(unit::CpIndex index, const U8String &text) const

Return a copy with text inserted at a character index.

U8String replaced(unit::ByteRange range, const U8String &text) const

Return a copy with a byte-based range replaced by text.

U8String replaced(unit::CpRange range, const U8String &text) const

Return a copy with a character-based range replaced by text.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

util::LoopResult forEach(const ProcessCharacterWithCpIndexFn &function) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

U8String transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U8String normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U8String truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U8String truncated(unit::CpLength maximumWidth, TruncateMode mode, const U8String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U8String aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U8String toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

U8String replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U8String replacedAll(const CharSet &characters, const U8String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {}) const -> U8String

Return a copy with all occurrences of decoded UTF-8 text replaced.

auto replacedFirst(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {}) const -> U8String

Return a copy with the first occurrence of decoded UTF-8 text replaced.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::ByteLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U8String toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U8String fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U8String fromJoined(std::initializer_list<U8String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-8 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U8String fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U8String fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U8String fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U8String

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U8String &first, U8String &second) noexcept

Swap two strings.

template<typename tValue>
using erbsland::text::U8StringCIHashMap = impl::StringHashMap<U8String, tValue, true>

A UTF-8 string-keyed hash map with case-insensitive key hashing and equality.

typedef impl::StringHashSet<U8String, true> erbsland::text::U8StringCIHashSet

A UTF-8 string-keyed hash set with case-insensitive key hashing and equality.

template<typename tValue>
using erbsland::text::U8StringCIMap = impl::StringMap<U8String, tValue, true>

A UTF-8 string-keyed ordered map with case-insensitive key comparison.

typedef impl::StringSet<U8String, true> erbsland::text::U8StringCISet

A UTF-8 string-keyed ordered set with case-insensitive key comparison.

class U8StringConstIterator

A minimal const iterator for UTF-8 encoded strings.

Public Types

using iterator_category = std::forward_iterator_tag

Standard iterator category for this iterator.

using value_type = Char

Value type returned by dereferencing this iterator.

using difference_type = std::ptrdiff_t

Difference type required by the iterator interface.

using pointer = const Char*

Pointer type used by operator->.

using reference = Char

Reference type used by operator*.

Public Functions

U8StringConstIterator()

Create an invalid iterator that does not point to any string.

bool operator==(const U8StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool operator!=(const U8StringConstIterator &other) const noexcept

Test if this iterator points to the same position as another iterator.

bool isValid() const noexcept

Test if this iterator is valid.

Char operator*() const

Access the character at the current position.

This returns Char::null() if the iterator is invalid.

U8StringConstIterator &operator++()

Increment this iterator to the next position.

U8StringConstIterator operator++(int)

Post-increment this iterator to the next position.

const Char *operator->() const

Access the character at the current position through pointer semantics.

This returns nullptr if the iterator is invalid.

class U8StringEditor

An owning UTF-8 string editor with copy-on-write semantics for sequential code-point access.

Use it as a local mutable working value for UTF-8 construction and multi-step editing. Use the StringEditor alias in user code and only U8StringEditor if UTF-8 encoding matters. Use String/U8String for storage, read-only access and copy-based transformations. Always creates a copy of the data when constructed from a read-only string.

See: Strings and Collections

Public Types

using value_type = Char

The value returned by this string’s const iterator.

using const_iterator = U8StringConstIterator

The const iterator type for decoded UTF-8 code points.

Public Functions

explicit U8StringEditor(std::string_view stdString)

Create a copy of the given string.

Parameters:

stdString – The string to copy.

explicit U8StringEditor(std::u8string_view stdString)

Create a copy of the given string.

Parameters:

stdString – The string to copy.

explicit U8StringEditor(const U8StringLiteral<char> &literal)

Create a copy of the given string literal.

Parameters:

literal – The string literal to copy.

explicit U8StringEditor(const U8StringLiteral<char8_t> &literal)

Create a copy of the given string literal.

Parameters:

literal – The string literal to copy.

explicit U8StringEditor(const U8String &view)

Create a copy of the given read-only string.

The copied data is not shared with the original string.

Parameters:

view – The read-only string to copy.

std::strong_ordering operator<=>(const U8String &other) const noexcept

Compare two strings by decoded code point.

Char operator[](unit::ByteIndex index) const noexcept

Access the character at the given start byte position.

Convenience call to charAt(unit::ByteIndex).

Parameters:

index – The byte index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char operator[](unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

Convenience call to charAt(unit::CpIndex). This operation may be slow for large strings, as the position must be found by iterating over the string.

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

std::strong_ordering compare(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Compare two strings by decoded code point, replacing malformed UTF-8 with Char::replacement().

std::size_t toHash() const noexcept

Create a hash value from the decoded code points.

std::size_t toHashCI() const noexcept

Create a hash value from the decoded code points after Unicode simple case folding.

bool isEmpty() const noexcept

Test if this string is empty.

bool isSensitive() const noexcept

Test if this string’s shared UTF-8 allocation is marked as sensitive.

void markAsSensitive() noexcept

Mark this string’s complete shared UTF-8 allocation as sensitive.

This mark is one-way and is observed by every string sharing the allocation.

bool isValidUtf8() const noexcept

Test if this string is valid UTF-8.

bool startsWith(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string starts with another one.

bool endsWith(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string ends with another one.

bool contains(const U8String &other, CharCompareFn compareFn = {}) const noexcept

Test if this string contains another one.

unit::ItemCount count(const U8String &text, CharCompareFn compareFn = {}) const noexcept

Count non-overlapping occurrences of another string.

Empty text counts as zero occurrences.

bool containsOneOf(const CharSet &characters) const noexcept

Test if this string contains any character from the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true if at least one decoded character is contained in characters.

bool containsOnly(const CharSet &characters) const noexcept

Test if this string only contains characters from the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

true all characters in the string are from the given set.

bool containsOnly(AsciiCategory category) const noexcept

Test if this string only contains characters from an ASCII category.

Malformed UTF-8 never matches an ASCII category.

Parameters:

category – The ASCII category to match.

Returns:

true if all characters in the string belong to category.

unit::ByteLength length() const noexcept

Get the byte length of this string.

unit::CpLength characterLength() const noexcept

Get the character length of this string.

This method provides the number of code points in the string. Counting follows the tolerant UTF-8 index movement rule documented by U8StringEditor.

int displayWidth() const noexcept

Get the approximate display width of this string.

This is a simple sum of decoded character display widths. Control characters, including line breaks, count as zero. Complex shaping, grapheme clusters, bidi layout, and terminal-specific behavior are not modeled.

unit::ByteIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

Char charAt(StringSide side) const noexcept

Get the first or last character in this string.

Char charAt(unit::ByteIndex startIndex) const noexcept

Access the character at the given start byte position.

See: Indexed Character Access

Parameters:

startIndex – The byte index to access the character at.

Returns:

The character at the given index, or a null character if no character can be read there.

Char readCharAndAdvance(unit::ByteIndex &index) const noexcept

Read the character at the given byte index and advance the index.

See: Indexed Character Access

Parameters:

index – The byte index to read from. Updated to the position after the read character on success.

Returns:

The character at the given index, or a signal character if no character can be read there.

Char readCharAndRetreat(unit::ByteIndex &index) const noexcept

Read the character before the given byte index and retreat the index.

See: Indexed Character Access

Parameters:

index – The byte index after the character to read. Updated to the start of the read character on success.

Returns:

The character before the given index, or a signal character if no character can be read there.

Char charAt(unit::CpIndex index) const noexcept

Slow: Access the character at the given code-point position.

This operation may be slow for large strings, as the position must be found by iterating over the string.

See: Indexed Character Access

Parameters:

index – The code-point index to access the character at.

Returns:

The character at the given index, or a signal character if no character can be read there.

bool advance(unit::ByteIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Advance the given byte index to the start of the next character.

See: Indexed Character Access

Parameters:
  • index – The index to advance.

  • count – The number of characters to advance.

Returns:

true if the index was advanced, false if it wasn’t advanced.

bool retreat(unit::ByteIndex &index, unit::CpLength count = unit::CpLength::one()) const noexcept

Retreat the given byte index to the start of the previous character.

See: Indexed Character Access

Parameters:
  • index – The index to retreat.

  • count – The number of characters to retreat.

Returns:

true if the index was retreated, false if it was already at the start or was “no index”.

unit::ByteIndex indexAt(unit::CpIndex index) const noexcept

Slow: Get the start byte index of the character at a given char index.

Sequentially iterates over characters until the target char index is reached. Seeking follows the tolerant UTF-8 index movement rule documented by U8StringEditor.

Parameters:

index – The char index to get the byte index for.

Returns:

The start byte index of the character at the given char index.

unit::CpIndex toCharIndex(unit::ByteIndex index) const noexcept

Slow: Get the character index from a byte index.

See: Indexed Character Access

Parameters:

index – The byte index to get the character index for.

Returns:

The character index at the given byte index.

U8StringEditor slice(unit::ByteRange range) const noexcept

Return a slice of this string.

Returns a string with a byte-based slice of this string. No UTF-8 validation is performed, if you slice in the middle of a character, the result contains encoding errors at the start or end of the resulting string.

Parameters:

range – The byte range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U8StringEditor slice(unit::CpRange range) const noexcept

Return a character-indexed slice of this string.

Returns a string with a code-point-based slice of this string. Malformed UTF-8 is decoded according to the tolerant UTF-8 index movement rule documented by U8StringEditor.

Parameters:

range – The code-point range to slice. If you pass a zero-length, invalid or out-of-bounds range, an empty string is returned.

Returns:

The sliced string.

U8StringEditor slice(StringSide side, unit::ByteLength length) const noexcept

Get the initial or trailing byte-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of bytes to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U8StringEditor slice(StringSide side, unit::ByteIndex index) const noexcept

Get the byte-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. ByteIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The byte index where the back portion starts.

Returns:

The sliced string.

U8StringEditor slice(StringSide side, unit::CpLength length) const noexcept

Get the initial or trailing code-point-based portion of this string.

Parameters:
  • side – The side of the string to slice from.

  • length – The number of bytes to slice. If you pass a zero-length, an empty string is returned. If you pass an infinite-length, the entire string is returned.

Returns:

The sliced string.

U8StringEditor slice(StringSide side, unit::CpIndex index) const noexcept

Get the code-point-indexed portion before or after a split point.

StringSide::Front returns the text before the index, StringSide::Back returns the text from the index. CpIndex::noIndex() and indexes at or beyond the end return the full string for front and an empty string for back.

Parameters:
  • side – The side of the split point to keep.

  • index – The code-point index where the back portion starts.

Returns:

The sliced string.

std::tuple<Char, U8StringEditor> slice(StringSide side) const noexcept

Slice one decoded character from the given side and return it with the remaining string.

Parameters:

side – The side of the string to slice from.

Returns:

The sliced character and the remaining string.

std::pair<U8StringEditor, U8StringEditor> splitAt(unit::ByteIndex index) const noexcept

Split this read-only string at a byte index.

ByteIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The byte index where the second returned string starts.

Returns:

The two strings before and after the split point.

std::pair<U8StringEditor, U8StringEditor> splitAt(unit::CpIndex index) const noexcept

Split this read-only string at a code-point index.

CpIndex::noIndex() and indexes at or beyond the end return the full string followed by an empty string.

Parameters:

index – The code-point index where the second returned string starts.

Returns:

The two strings before and after the split point.

U8StringEditor &trim(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {})

Remove leading and trailing ASCII whitespace or selected characters.

U8StringEditor trimmed(const std::optional<CharSet> &characters = {}, std::optional<StringSide> side = {}) const

Return a copy without leading and trailing ASCII whitespace or selected characters.

unit::ByteIndex findFirstOf(const CharSet &characters) const noexcept

Find the first decoded character contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findFirstOf(const CharSet &characters, unit::ByteIndex start) const noexcept

Find the first decoded character contained in the given set at or after the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findFirstNotOf(const CharSet &characters) const noexcept

Find the first decoded character not contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The byte index of the first non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findFirstNotOf(const CharSet &characters, unit::ByteIndex start) const noexcept

Find the first decoded character not contained in the given set at or after the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

Returns:

The byte index of the first non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findLastOf(const CharSet &characters) const noexcept

Find the last decoded character contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to match.

Returns:

The byte index of the last match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findLastOf(const CharSet &characters, unit::ByteIndex end) const noexcept

Find the last decoded character contained in the given set before the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to match.

  • end – The exclusive byte index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The byte index of the last match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex findLastNotOf(const CharSet &characters) const noexcept

Find the last decoded character not contained in the given set.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:

characters – The character set to exclude.

Returns:

The byte index of the last non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex findLastNotOf(const CharSet &characters, unit::ByteIndex end) const noexcept

Find the last decoded character not contained in the given set before the given byte index.

Malformed UTF-8 is decoded as Char::replacement().

Parameters:
  • characters – The character set to exclude.

  • end – The exclusive byte index where the reverse search starts. If end is no-index, this function returns no-index immediately.

Returns:

The byte index of the last non-matching character, or ByteIndex::noIndex() if there is none.

unit::ByteIndex find(const U8String &text, CharCompareFn compareFn = {}) const noexcept

Find text in this string.

Parameters:
  • text – The text to find.

  • compareFn – Optional character comparison function.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

unit::ByteIndex find(const U8String &text, unit::ByteIndex start, CharCompareFn compareFn = {}) const noexcept

Find text in this string starting at a byte index.

Parameters:
  • text – The text to find.

  • start – The byte index where the search starts. If start is no-index, this function returns no-index immediately.

  • compareFn – Optional character comparison function.

Returns:

The byte index of the first match, or ByteIndex::noIndex() if there is no match.

U8StringEditor &clear() noexcept

Remove all characters from the string.

StringEditor capacity is not changed.

void reset() noexcept

Reset the string to its initial state, clearing all characters and resetting capacity to default.

U8StringEditor &append(const U8String &text, unit::ItemCount count = unit::ItemCount::one())

Append a UTF-8 read-only string one or more times.

U8StringEditor &append(Char character, unit::CpLength count = unit::CpLength::one())

Append one Unicode code point one or more times.

U8StringEditor &remove(unit::ByteRange range)

Remove a byte-based range.

U8StringEditor &remove(unit::CpRange range)

Remove a character-based range.

U8StringEditor &removeAll(const CharSet &characters)

Remove all characters contained in the set.

U8StringEditor &removeAll(const U8String &text, CharCompareFn compareFn = {})

Remove all occurrences of the given decoded UTF-8 text.

U8StringEditor &removeFirst(const U8String &text, CharCompareFn compareFn = {})

Remove the first occurrence of the given decoded UTF-8 text.

U8StringEditor &keep(unit::ByteRange range)

Keep only a byte-based range.

U8StringEditor &keep(unit::CpRange range)

Keep only a character-based range.

U8StringEditor &insert(unit::ByteIndex index, const U8String &text)

Insert text at a byte index.

U8StringEditor &insert(unit::CpIndex index, const U8String &text)

Insert text at a character index.

U8StringEditor &replace(unit::ByteRange range, const U8String &text)

Replace a byte-based range with text.

U8StringEditor &replace(unit::CpRange range, const U8String &text)

Replace a character-based range with text.

U8StringEditor &replaceFirst(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {})

Replace the first occurrence of decoded UTF-8 text.

U8StringEditor &replaceAll(const CharSet &characters, Char replacement)

Replace all characters contained in the set with one character.

U8StringEditor &replaceAll(const CharSet &characters, const U8String &replacement)

Replace all characters contained in the set with text.

U8StringEditor &replaceAll(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {})

Replace all occurrences of decoded UTF-8 text.

U8StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End)

Truncate this string to a maximum decoded code-point width.

U8StringEditor &truncate(unit::CpLength maximumWidth, TruncateMode mode, const U8String &ellipsis)

Truncate this string to a maximum decoded code-point width, inserting an optional ellipsis.

U8StringEditor removed(unit::ByteRange range) const

Return a copy with a byte-based range removed.

U8StringEditor removed(unit::CpRange range) const

Return a copy with a character-based range removed.

U8StringEditor removedAll(const CharSet &characters) const

Return a copy with all characters from the set removed.

U8StringEditor removedAll(const U8String &text, CharCompareFn compareFn = {}) const

Return a copy with all occurrences of decoded UTF-8 text removed.

U8StringEditor removedFirst(const U8String &text, CharCompareFn compareFn = {}) const

Return a copy with the first occurrence of decoded UTF-8 text removed.

U8StringEditor kept(unit::ByteRange range) const

Return a copy keeping only a byte-based range.

U8StringEditor kept(unit::CpRange range) const

Return a copy keeping only a character-based range.

U8StringEditor inserted(unit::ByteIndex index, const U8String &text) const

Return a copy with text inserted at a byte index.

U8StringEditor inserted(unit::CpIndex index, const U8String &text) const

Return a copy with text inserted at a character index.

U8StringEditor replaced(unit::ByteRange range, const U8String &text) const

Return a copy with a byte-based range replaced by text.

U8StringEditor replaced(unit::CpRange range, const U8String &text) const

Return a copy with a character-based range replaced by text.

auto replacedFirst(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {}) const -> U8StringEditor

Return a copy with the first occurrence of decoded UTF-8 text replaced.

U8StringEditor replacedAll(const CharSet &characters, Char replacement) const

Return a copy with all characters from the set replaced by one character.

U8StringEditor replacedAll(const CharSet &characters, const U8String &replacement) const

Return a copy with all characters from the set replaced by text.

auto replacedAll(const U8String &text, const U8String &replacement, CharCompareFn compareFn = {}) const -> U8StringEditor

Return a copy with all occurrences of decoded UTF-8 text replaced.

util::LoopResult forEach(const ProcessCharacterFn &function) const

Call a function for every decoded code point, stopping early if the function requests it.

U8StringEditor transformed(TransformCharacterFn function) const

Return a string where every decoded code point is mapped through the given function.

U8StringEditor &normalize(NormalizationForm form)

Normalize this string in place using the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Storage is untouched if no change is required.

Parameters:

form – The explicit normalization form to apply.

Returns:

This editor for chaining.

See: Normalizing Unicode Strings

U8StringEditor normalized(NormalizationForm form) const

Return this string in the selected Unicode normalization form.

Malformed UTF-8 is replaced with U+FFFD. Unchanged valid text retains its original storage.

Parameters:

form – The explicit normalization form to apply.

Returns:

The normalized string, sharing this storage if no change is required.

See: Normalizing Unicode Strings

U8StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode = TruncateMode::End) const

Return a string truncated to a maximum decoded code-point width.

U8StringEditor truncated(unit::CpLength maximumWidth, TruncateMode mode, const U8String &ellipsis) const

Return a string truncated to a maximum decoded code-point width, inserting an optional ellipsis.

U8StringEditor aligned(unit::CpLength length, geometry::Alignment alignment, Char fill = U' ') const

Return a string padded to the requested decoded code-point length.

U8StringEditor toSafeString(unit::CpLength maximumWidth, SafeStringFlags flags = SafeStringFlag::Defaults) const

Return a bounded representation that is safe for logs and debug output.

bool toBoolean(bool defaultValue = {}) const noexcept

Convert an ASCII-case-insensitive ELCL boolean literal, or return a default for unsupported text.

Parameters:

defaultValue – The value returned for invalid, incomplete, padded, or empty text.

Returns:

The recognized boolean value, or defaultValue.

bool toBooleanOrThrow() const

Convert an ASCII-case-insensitive ELCL boolean literal.

Throws:

err::ParseError – if the complete text is not a supported literal.

Returns:

The recognized boolean value.

template<math::AnyIntegerType T>
auto toInteger(T defaultValue = {}, IntegerParseOptions options = IntegerParseOptions::stringDefault()) const noexcept -> T

Convert this string to an integer, or return the given default value on error.

template<math::AnyIntegerType T>
T toIntegerOrThrow(IntegerParseOptions options = IntegerParseOptions::stringDefault()) const

Convert this string to an integer or throw on parse errors and overflow.

template<impl::AnyFloatType T>
auto toFloat(T defaultValue = {}, FloatParseOptions options = FloatParseOptions::defaultOptions()) const noexcept -> T

Convert this string to a floating point value, or return the given default value on error.

template<impl::AnyFloatType T>
T toFloatOrThrow(FloatParseOptions options = FloatParseOptions::defaultOptions()) const

Convert this string to a floating point value or throw on parse errors and overflow.

unit::ByteLength escapedSize(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const noexcept

Get the size of the escaped string.

U8StringEditor toEscaped(EscapeFormat format, EscapeAmount amount = EscapeAmount::Balanced) const

Escape this string according to the given format and amount.

Parameters:
  • format – The target format for the escaping.

  • amount – The amount of escaping to perform.

mem::StorageIdentifier storageId() const noexcept

Get a unique identifier for the visible storage range.

The identifier changes when the string detaches, reallocates, or when a string selects a different range.

void reserve(unit::ByteLength capacity)

Reserve capacity for this string.

See: Indexed Character Access

void shrinkToFit()

Try to free memory by shrinking the memory to the actual used size.

See: Indexed Character Access

unit::ByteLength capacity() const noexcept

Get the current memory capacity in bytes.

This function returns the reserved capacity available for the string data.

Returns:

The reserved capacity in bytes.

unit::ByteLength memoryUsage() const noexcept

Get the current memory usage in bytes.

This function returns an estimation of the actual memory usage, including required management data and alignment. Use this function if you need to monitor memory usage (e.g. for caching). Be aware that through fragmentation and other factors, the actual memory usage may be higher than reported.

Returns:

The estimated memory usage in bytes.

void detach()

Detach the string data.

After a call of this method, you have exclusive access to the string data. Detach is managed automatically, only use this method if you need manual control.

const_iterator begin() const noexcept

Get an iterator to the first decoded character.

const_iterator end() const noexcept

Get an iterator pointing after the last decoded character.

Public Static Functions

static U8StringEditor fromCharacter(Char character, unit::CpLength count = unit::CpLength::one())

Create a string from one Unicode code point repeated one or more times.

static U8StringEditor fromJoined(std::initializer_list<U8String> parts)

Create a string by joining all parts without a separator.

Parameters:

parts – The UTF-8 read-only strings to join.

Returns:

The joined string.

template<math::AnyIntegerType T>
static U8StringEditor fromInteger(T value, IntegerFormat format = IntegerFormat::defaultFormat())

Create a string from an integer using the given format.

static U8StringEditor fromFloat(double value, FloatFormat format = FloatFormat::defaultFormat())

Create a string from a floating point value using the given format.

static U8StringEditor fromBoolean(bool value, BooleanFormat format = BooleanFormat::defaultFormat())

Create a string from a boolean value using the given format.

static auto fromByteBlock(const mem::ByteBlock &bytes, ByteFormat format = ByteFormat::defaultFormat()) -> U8StringEditor

Create a hexadecimal string from a byte block using the given format.

Friends

friend void swap(U8StringEditor &first, U8StringEditor &second) noexcept

Swap two strings.

typedef impl::StringList<U8StringEditor> erbsland::text::U8StringEditorList

A list of UTF-8 strings.

template<typename tValue>
using erbsland::text::U8StringHashMap = impl::StringHashMap<U8String, tValue, false>

A UTF-8 string-keyed hash map.

typedef impl::StringHashSet<U8String, false> erbsland::text::U8StringHashSet

A UTF-8 string-keyed hash set.

typedef impl::StringList<U8String> erbsland::text::U8StringList

A list of UTF-8 read-only strings.

template<typename tChar>
class U8StringLiteral

A thin wrapper around a UTF-8 string literal.

This class provides a safe and efficient way to work with UTF-8 string literals. It allows work with literals that are only copied if a modification is required.

Public Functions

template<std::size_t N>
inline explicit consteval U8StringLiteral(const tChar (&data)[N]) noexcept

Create a new U8StringCharLiteral from a UTF-8 string char literal.

constexpr bool isEmpty() const noexcept

Test if this string is empty.

bool isValidUtf8() const noexcept

Test if this string is valid UTF-8.

constexpr unit::ByteLength length() const noexcept

Get the byte length of this string.

unit::CpLength characterLength() const noexcept

Get the code-point length of this string.

constexpr unit::ByteIndex indexAt(StringSide side) const noexcept

Get the native data index for one side of the string.

template<typename tValue>
using erbsland::text::U8StringMap = impl::StringMap<U8String, tValue, false>

A UTF-8 string-keyed ordered map.

typedef impl::StringSet<U8String, false> erbsland::text::U8StringSet

A UTF-8 string-keyed ordered set.