Grapheme

A structure designed to effectively pack $(CHARACTERS) of a $(CLUSTER).

Grapheme has value semantics so 2 copies of a Grapheme always refer to distinct objects. In most actual scenarios a Grapheme fits on the stack and avoids memory allocation overhead for all but quite long clusters.

Constructors

this
this(C[] chars)
this(Input seq)

Ctor

Destructor

A destructor is present on this object, but not explicitly documented in the source.

Postblit

A postblit is present on this object, but not explicitly documented in the source.

Members

Functions

opIndex
dchar opIndex(size_t index)

Gets a $(CODEPOINT) at the given index in this cluster.

opIndexAssign
void opIndexAssign(dchar ch, size_t index)

Writes a $(CODEPOINT) ch at given index in this cluster.

opOpAssign
ref opOpAssign(dchar ch)

Append $(CHARACTER) ch to this grapheme. Warning: Use of this facility may invalidate grapheme cluster, see also valid.

opOpAssign
ref opOpAssign(Input inp)

Append all $(CHARACTERS) from the input range inp to this Grapheme.

opSlice
SliceOverIndexed!Grapheme opSlice(size_t a, size_t b)
SliceOverIndexed!Grapheme opSlice()

Random-access range over Grapheme's $(CHARACTERS).

Properties

length
size_t length [@property getter]

Grapheme cluster length in $(CODEPOINTS).

valid
bool valid [@property getter]

True if this object contains valid extended grapheme cluster. Decoding primitives of this module always return a valid Grapheme.

Examples

import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter;
import std.range : isRandomAccessRange;

string bold = "ku\u0308hn";

// note that decodeGrapheme takes parameter by ref
auto first = decodeGrapheme(bold);

assert(first.length == 1);
assert(first[0] == 'k');

// the next grapheme is 2 characters long
auto wideOne = decodeGrapheme(bold);
// slicing a grapheme yields a random-access range of dchar
assert(wideOne[].equal("u\u0308"));
assert(wideOne.length == 2);
static assert(isRandomAccessRange!(typeof(wideOne[])));

// all of the usual range manipulation is possible
assert(wideOne[].filter!isMark().equal("\u0308"));

auto g = Grapheme("A");
assert(g.valid);
g ~= '\u0301';
assert(g[].equal("A\u0301"));
assert(g.valid);
g ~= "B";
// not a valid grapheme cluster anymore
assert(!g.valid);
// still could be useful though
assert(g[].equal("A\u0301B"));

See Also

Meta