Spec-Zone.ru › D

std.utf

Кодирование и декодирование строк UTF-8, UTF-16 и UTF-32.

Поддержка символов UTF ограничена '\u0000' <= character <= '\U0010FFFF'.

Категория Функции
Декодирование decode decodeFront
Ленивое декодирование byCodeUnit byChar byWchar byDchar byUTF
Кодирование encode toUTF8 toUTF16 toUTF32 toUTFz toUTF16z
Длина codeLength count stride strideBack
Индекс toUCSindex toUTFindex
Проверка isValidDchar validate
Разное replacementDchar UseReplacementDchar UTFException

См. также:
Википедия
http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
Лицензия:
Лицензия Boost 1.0.
Авторы:
Уолтер Брайт и Джоонатан М. Дэвис
Источник
std/utf.d
END_OF_DOCUMENT_MARKER
class UTFException: core.exception.UnicodeException;

Исключение, выбрасываемое при ошибках в функциях std.utf.

Примеры:
import std.exception : assertThrown;

char[4] buf;
assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));
assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF));
assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00));
assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF));
assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));
pure nothrow @nogc @safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null);

pure nothrow @safe this(string msg, size_t index, string file = __FILE__, size_t line = __LINE__, Throwable next = null);

Стандартные конструкторы исключений.

const string toString();
Возвращает:
Строку, подробно описывающую недействительную последовательность UTF.
pure nothrow @nogc @safe bool isValidDchar(dchar c);

Проверяет, является ли заданный Юникод-код точкой действительным.

Параметры:
dchar c код точки для проверки
Возвращает:
true тогда и только тогда, когда c является действительной Юникод-кодовой точкой
Примечание
'\uFFFE' и '\uFFFF' считаются действительными isValidDchar, так как они разрешены для внутреннего использования приложением, но не допускаются для обмена по стандарту Юникод.
Примеры:
assert( isValidDchar(cast(dchar) 0x41));
assert( isValidDchar(cast(dchar) 0x00));
assert(!isValidDchar(cast(dchar) 0xD800));
assert(!isValidDchar(cast(dchar) 0x11FFFF));
uint stride(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(char)));

uint stride(S)(auto ref S str)
Constraints: if (is(S : const(char[])) || isInputRange!S && is(immutable(ElementType!S) == immutable(char)));

uint stride(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(wchar[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(wchar)));

pure @safe uint stride(S)(auto ref S str)
Constraints: if (is(S : const(wchar[])));

uint stride(S)(auto ref S str)
Constraints: if (isInputRange!S && is(immutable(ElementType!S) == immutable(wchar)) && !is(S : const(wchar[])));

uint stride(S)(auto ref S str, size_t index = 0)
Constraints: if (is(S : const(dchar[])) || isInputRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar)));

Вычисляет длину последовательности UTF, начинающейся с index в str.

Параметры:
S str диапазон ввода единиц кода UTF. Должен быть диапазоном с произвольным доступом, если index передается
size_t index начальный индекс последовательности UTF (по умолчанию: 0)
Возвращает:
Количество единиц кода в последовательности UTF. Для UTF-8 это значение от 1 до 4 (согласно RFC 3629, раздел 3). Для UTF-16 это либо 1, либо 2. Для UTF-32 всегда 1.
Выбрасывает:
Может выбросить исключение UTFException, если str[index] не является началом действительной последовательности UTF.
Примечание
stride будет анализировать только первый str[index] элемент. Она не будет полностью проверять действительность последовательности UTF, а также не будет проверять присутствие последовательности: не будет гарантировать, что index + stride(str, index) <= str.length.
Примеры:
writeln("a".stride); // 1
writeln("λ".stride); // 2
writeln("aλ".stride); // 1
writeln("aλ".stride(1)); // 2
writeln("𐐷".stride); // 4
uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(char)));

uint strideBack(S)(auto ref S str)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && hasLength!S && is(immutable(ElementType!S) == immutable(char)));

uint strideBack(S)(auto ref S str)
Constraints: if (isBidirectionalRange!S && is(immutable(ElementType!S) == immutable(char)) && !isRandomAccessRange!S);

uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(wchar[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(wchar)));

uint strideBack(S)(auto ref S str)
Constraints: if (is(S : const(wchar[])) || isBidirectionalRange!S && is(immutable(ElementType!S) == immutable(wchar)));

uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (isRandomAccessRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar)));

uint strideBack(S)(auto ref S str)
Constraints: if (isBidirectionalRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar)));

Вычисляет длину последовательности UTF, заканчивающейся за единицей кода до index в str.

Параметры:
S str двунаправленный диапазон единиц кода UTF. Должен быть диапазоном с произвольным доступом, если index передается
size_t index индекс, следующий за концом последовательности UTF (по умолчанию: str.length)
Возвращает:
Количество единиц кода в последовательности UTF. Для UTF-8 это значение от 1 до 4 (согласно RFC 3629, раздел 3). Для UTF-16 это либо 1, либо 2. Для UTF-32 всегда 1.
Выбрасывает:
Может выбросить исключение UTFException, если str[index] не находится за концом действительной последовательности UTF.
Примечание
strideBack будет анализировать только элемент в str[index - 1] элементе. Она не будет полностью проверять действительность последовательности UTF, а также не будет проверять присутствие последовательности: не будет гарантировать, что strideBack(str, index) <= index.
Примеры:
writeln("a".strideBack); // 1
writeln("λ".strideBack); // 2
writeln("aλ".strideBack); // 2
writeln("aλ".strideBack(1)); // 1
writeln("𐐷".strideBack); // 4
pure @safe size_t toUCSindex(C)(const(C)[] str, size_t index)
Constraints: if (isSomeChar!C);

Учитывая index в str и предполагая, что index находится в начале последовательности UTF, toUCSindex определяет количество символов UCS до index. Таким образом, index является индексом единицы кода в начале кодовой точки, а возвращаемое значение показывает, сколько кодовых точек в строке находится в этой кодовой точке.

Примеры:
writeln(toUCSindex(`hello world`, 7)); // 7
writeln(toUCSindex(`hello world`w, 7)); // 7
writeln(toUCSindex(`hello world`d, 7)); // 7

writeln(toUCSindex(`Ma Chérie`, 7)); // 6
writeln(toUCSindex(`Ma Chérie`w, 7)); // 7
writeln(toUCSindex(`Ma Chérie`d, 7)); // 7

writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`, 9)); // 3
writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`w, 9)); // 9
writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`d, 9)); // 9
pure @safe size_t toUTFindex(C)(const(C)[] str, size_t n)
Constraints: if (isSomeChar!C);

Учитывая индекс UCS n в str, возвращает индекс UTF. Таким образом, n показывает, сколько кодовых точек в строке находится в кодовой точке, и возвращается индекс массива единицы кода.

Примеры:
writeln(toUTFindex(`hello world`, 7)); // 7
writeln(toUTFindex(`hello world`w, 7)); // 7
writeln(toUTFindex(`hello world`d, 7)); // 7

writeln(toUTFindex(`Ma Chérie`, 6)); // 7
writeln(toUTFindex(`Ma Chérie`w, 7)); // 7
writeln(toUTFindex(`Ma Chérie`d, 7)); // 7

writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`, 3)); // 9
writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`w, 9)); // 9
writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`d, 9)); // 9
alias UseReplacementDchar = std.typecons.Flag!"useReplacementDchar".Flag;

Указывает, следует ли заменять недействительный UTF на replacementDchar

dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)
Constraints: if (!isSomeString!S && isRandomAccessRange!S && hasSlicing!S && hasLength!S && isSomeChar!(ElementType!S));

pure @trusted dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)
Constraints: if (isSomeString!S);

Декодирует и возвращает кодовую точку, начинающуюся с str[index]. index смещается на позицию после декодированной кодовой точки. Если кодовая точка не соответствует формату, выбрасывается исключение UTFException, а index остается неизменным.

decode будет работать только со строками и диапазонами произвольного доступа с кодовыми единицами с длиной и возможностью нарезки, в то время как decodeFront будет работать с любым диапазоном ввода кодовых единиц.

Параметры:
useReplacementDchar если недействительный UTF, возвращает replacementDchar вместо выброса исключения
S str входная строка или индексируемый диапазон
size_t index начальный индекс в s[]; увеличивается на количество обработанных единиц кода
Возвращает:
декодированный символ
Выбрасывает:
UTFException если str[index] не является началом действительной последовательности UTF и useReplacementDchar равен No.useReplacementDchar
Примеры:
size_t i;

assert("a".decode(i) == 'a' && i == 1);
i = 0;
assert("å".decode(i) == 'å' && i == 2);
i = 1;
assert("aå".decode(i) == 'å' && i == 3);
i = 0;
assert("å"w.decode(i) == 'å' && i == 1);

// ë as a multi-code point grapheme
i = 0;
assert("e\u0308".decode(i) == 'e' && i == 1);
// ë as a single code point grapheme
i = 0;
assert("ë".decode(i) == 'ë' && i == 2);
i = 0;
assert("ë"w.decode(i) == 'ë' && i == 1);
dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (!isSomeString!S && isInputRange!S && isSomeChar!(ElementType!S));

pure @trusted dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (isSomeString!S);

dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
Constraints: if (isInputRange!S && isSomeChar!(ElementType!S));

decodeFront — это вариант decode, который специально декодирует первую кодовую точку. В отличие от decode, decodeFront принимает любой диапазон входных единиц кода (а не только строку или диапазон с произвольным доступом). Он также получает диапазон по ref и удаляет элементы по мере их декодирования. Если numCodeUnits передаётся, он устанавливается в число единиц кода, входящих в декодированную кодовую точку.

Параметры:
useReplacementDchar если UTF недействителен, возвращает replacementDchar вместо исключения
S str строка-вход или индексируемый диапазон
size_t numCodeUnits устанавливается в число обработанных единиц кода
Возвращает:
декодированный символ
Выбрасывает:
UTFException, если str.front не является началом допустимой последовательности UTF. Если исключение выброшено, то нет гарантии относительно числа удаленных единиц кода, поскольку это зависит от типа используемого диапазона и того, сколько единиц кода нужно было удалить, прежде чем кодовая точка была определена как недопустимая.
Примеры:
import std.range.primitives;
string str = "Hello, World!";

assert(str.decodeFront == 'H' && str == "ello, World!");
str = "å";
assert(str.decodeFront == 'å' && str.empty);
str = "å";
size_t i;
assert(str.decodeFront(i) == 'å' && i == 2 && str.empty);
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (isSomeString!S);

dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (!isSomeString!S && isSomeChar!(ElementType!S) && isBidirectionalRange!S && (isRandomAccessRange!S && hasLength!S || !isRandomAccessRange!S));

dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
Constraints: if (isSomeString!S || isRandomAccessRange!S && hasLength!S && isSomeChar!(ElementType!S) || !isRandomAccessRange!S && isBidirectionalRange!S && isSomeChar!(ElementType!S));

decodeBack — это вариант decode, который специально декодирует последнюю кодовую точку. В отличие от decode, decodeBack принимает любой двунаправленный диапазон единиц кода (а не только строку или диапазон с произвольным доступом). Он также получает диапазон по ref и удаляет элементы по мере их декодирования. Если numCodeUnits передаётся, он устанавливается в число единиц кода, входящих в декодированную кодовую точку.

Параметры:
useReplacementDchar если UTF недействителен, возвращает replacementDchar вместо исключения
S str строка-вход или двунаправленный диапазон
size_t numCodeUnits указывает число обработанных единиц кода
Возвращает:
Декодированный символ UTF.
Выбрасывает:
UTFException, если str.back не является концом допустимой последовательности UTF. Если исключение выброшено, то сам str остаётся неизменным, но нет гарантии относительно значения numCodeUnits (при передаче).
Примеры:
import std.range.primitives;
string str = "Hello, World!";

assert(str.decodeBack == '!' && str == "Hello, World");
str = "å";
assert(str.decodeBack == 'å' && str.empty);
str = "å";
size_t i;
assert(str.decodeBack(i) == 'å' && i == 2 && str.empty);
pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out char[4] buf, dchar c);

pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out wchar[2] buf, dchar c);

pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out dchar[1] buf, dchar c);

Кодирует c в статический массив buf и возвращает фактическую длину закодированного символа (число между 1 и 4 для буферов char[4] и число между 1 и 2 для буферов wchar[2]).

Выбрасывает:
UTFException если c не является допустимой кодовой точкой UTF.
Примеры:
import std.exception : assertThrown;
import std.typecons : Yes;

char[4] buf;

assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
assert(encode(buf, '\u007F') == 1 && buf[0 .. 1] == "\u007F");
assert(encode(buf, '\u0080') == 2 && buf[0 .. 2] == "\u0080");
assert(encode(buf, '\uE000') == 3 && buf[0 .. 3] == "\uE000");
assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == "\xEF\xBF\xBE");
assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));

encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
auto slice = buf[];
writeln(slice.decodeFront); // replacementDchar
Примеры:
import std.exception : assertThrown;
import std.typecons : Yes;

wchar[2] buf;

assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000");
assert(encode(buf, '\uD7FF') == 1 && buf[0 .. 1] == "\uD7FF");
assert(encode(buf, '\uE000') == 1 && buf[0 .. 1] == "\uE000");
assert(encode(buf, '\U00010000') == 2 && buf[0 .. 2] == "\U00010000");
assert(encode(buf, '\U0010FFFF') == 2 && buf[0 .. 2] == "\U0010FFFF");
assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));

encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
auto slice = buf[];
writeln(slice.decodeFront); // replacementDchar
Примеры:
import std.exception : assertThrown;
import std.typecons : Yes;

dchar[1] buf;

assert(encode(buf, '\u0000') == 1 && buf[0] == '\u0000');
assert(encode(buf, '\uD7FF') == 1 && buf[0] == '\uD7FF');
assert(encode(buf, '\uE000') == 1 && buf[0] == '\uE000');
assert(encode(buf, '\U0010FFFF') == 1 && buf[0] == '\U0010FFFF');
assertThrown!UTFException(encode(buf, cast(dchar) 0xD800));

encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000);
writeln(buf[0]); // replacementDchar
pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref char[] str, dchar c);

pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref wchar[] str, dchar c);

pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref dchar[] str, dchar c);

Кодирует c в кодировке str и добавляет её в str.

Выбрасывает:
UTFException если c не является допустимой кодовой точкой UTF.
Примеры:
char[] s = "abcd".dup;
dchar d1 = 'a';
dchar d2 = 'ø';

encode(s, d1);
writeln(s.length); // 5
writeln(s); // "abcda"
encode(s, d2);
writeln(s.length); // 7
writeln(s); // "abcdaø"
pure nothrow @nogc @safe ubyte codeLength(C)(dchar c)
Constraints: if (isSomeChar!C);

Возвращает число единиц кода, необходимых для кодирования кодовой точки c при использовании типа символа C для её кодирования.

Примеры:
writeln(codeLength!char('a')); // 1
writeln(codeLength!wchar('a')); // 1
writeln(codeLength!dchar('a')); // 1

writeln(codeLength!char('\U0010FFFF')); // 4
writeln(codeLength!wchar('\U0010FFFF')); // 2
writeln(codeLength!dchar('\U0010FFFF')); // 1
size_t codeLength(C, InputRange)(InputRange input)
Constraints: if (isInputRange!InputRange && !isInfinite!InputRange && isSomeChar!(ElementType!InputRange));

Возвращает число единиц кода, необходимых для кодирования str в строке, тип символа которой — C. Это особенно полезно при извлечении одной строки с длиной другой, если типы двух строк используют разные типы символов.

Параметры:
C тип символа для получения длины кодирования
InputRange input диапазон ввода для вычисления длины кодирования
Возвращает:
Число единиц кода в input при кодировании в C.
Примеры:
assert(codeLength!char("hello world") ==
       "hello world".length);
assert(codeLength!wchar("hello world") ==
       "hello world"w.length);
assert(codeLength!dchar("hello world") ==
       "hello world"d.length);

assert(codeLength!char(`プログラミング`) ==
       `プログラミング`.length);
assert(codeLength!wchar(`プログラミング`) ==
       `プログラミング`w.length);
assert(codeLength!dchar(`プログラミング`) ==
       `プログラミング`d.length);

string haystack = `Être sans la verité, ça, ce ne serait pas bien.`;
wstring needle = `Être sans la verité`;
assert(haystack[codeLength!char(needle) .. $] ==
       `, ça, ce ne serait pas bien.`);
pure @safe void validate(S)(in S str)
Constraints: if (isSomeString!S);

Проверяет, является ли str правильно сформированным Unicode.

Выбрасывает:
UTFException если str не является правильно сформированным.
Примеры:
import std.exception : assertThrown;
char[] a = [167, 133, 175];
assertThrown!UTFException(validate(a));
string toUTF8(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S));

Кодирует элементы s в UTF-8 и возвращает новую строку с элементами.

Параметры:
S s строка для кодирования
Возвращает:
строка UTF-8
См. также:
Для ленивой, не выделяющей памяти версии этих функций, см. byUTF.
Примеры:
import std.algorithm.comparison : equal;

// The ö is represented by two UTF-8 code units
assert("Hellø"w.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8]));

// 𐐷 is four code units in UTF-8
assert("𐐷"d.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));
wstring toUTF16(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S));

Кодирует элементы s в UTF-16 и возвращает новый GC-выделенный wstring элементов.

Параметры:
S s диапазон для кодирования
Возвращает:
строка UTF-16
См. также:
Для ленивой, не выделяющей памяти версии этих функций, см. byUTF.
Примеры:
import std.algorithm.comparison : equal;

// these graphemes are two code units in UTF-16 and one in UTF-32
writeln("𤭢"d.length); // 1
writeln("𐐷"d.length); // 1

assert("𤭢"d.toUTF16.equal([0xD852, 0xDF62]));
assert("𐐷"d.toUTF16.equal([0xD801, 0xDC37]));
dstring toUTF32(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S));

Кодирует элементы s в UTF-32 и возвращает новый GC-выделенный dstring элементов.

Параметры:
S s диапазон для кодирования
Возвращает:
строка UTF-32
См. также:
Для ленивой, не выделяющей памяти версии этих функций, см. byUTF.
Примеры:
import std.algorithm.comparison : equal;

// these graphemes are two code units in UTF-16 and one in UTF-32
writeln("𤭢"w.length); // 2
writeln("𐐷"w.length); // 2

assert("𤭢"w.toUTF32.equal([0x00024B62]));
assert("𐐷"w.toUTF32.equal([0x00010437]));
template toUTFz(P) if (isPointer!P && isSomeChar!(typeof(*P.init)))

Возвращает строку в стиле C с нулевым завершением, эквивалентную str. str не должна содержать вложенных '\0' символов, так как любая функция C будет рассматривать первый встреченный '\0' как конец строки. Если str.empty равно true, то возвращается строка, содержащая только '\0'.

toUTFz принимает любой тип строки и шаблонизируется по типу указателя на символ, который вы хотите преобразовать. Она будет избегать выделения новой строки, если это возможно, но есть неплохая вероятность, что ей придётся выделить новую строку — особенно при работе с типами символов, отличными от char.

Предупреждение 1: Если результат toUTFz равен str.ptr, то если что-либо изменит символ, следующий за концом str (который является завершающим символом '\0' строки), то строка больше не будет завершаться нулём. Наиболее вероятные сценарии для этого — если вы добавляете к str символы, и не происходит перевыделения, или когда str является фрагментом более крупного массива, и вы изменяете символ в большем массиве, который находится в позиции за концом str. Ещё один случай, когда это может произойти, — если у вас есть изменяемый массив символов непосредственно после str в памяти (например, если это переменные-члены в определённом пользователем типе, где один объявлен сразу после другого), и этот массив символов случайно начинался с '\0'. Такие сценарии никогда не возникнут, если вы немедленно используете строку с нулевым завершением после вызова toUTFz и функция C, использующая её, не хранит ссылку на неё. Также они маловероятны, даже если вы сохраните строку с нулевым завершением (приведённые выше случаи — лишь некоторые примеры, когда это может произойти). Однако, если вы сохранили строку с нулевым завершением и хотите быть абсолютно уверены, что строка останется завершённой нулём, то просто добавьте '\0' к строке и используйте её свойство ptr, а не вызывайте toUTFz.

Предупреждение 2: При передаче указателя на символ функции C, и функция C хранит его по какой-либо причине, убедитесь, что в вашем коде D хранится ссылка на него. В противном случае он может исчезнуть во время цикла сбора мусора, что приведёт к неприятной ошибке, когда C-код попытается его использовать.

Примеры:
auto p1 = toUTFz!(char*)("hello world");
auto p2 = toUTFz!(const(char)*)("hello world");
auto p3 = toUTFz!(immutable(char)*)("hello world");
auto p4 = toUTFz!(char*)("hello world"d);
auto p5 = toUTFz!(const(wchar)*)("hello world");
auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);
pure @safe const(wchar)* toUTF16z(C)(const(C)[] str)
Constraints: if (isSomeChar!C);

toUTF16z — это вспомогательная функция для toUTFz!(const(wchar)*).

Кодирует строку s в UTF-16 и возвращает закодированную строку. toUTF16z подходит для вызова функций 'W' в Win32 API, которые принимают аргумент LPCWSTR.

Примеры:
string str = "Hello, World!";
const(wchar)* p = str.toUTF16z;
writeln(p[str.length]); // '\0'
pure nothrow @nogc @safe size_t count(C)(const(C)[] str)
Constraints: if (isSomeChar!C);

Возвращает общее количество кодовых точек, закодированных в str.

Заменяет
Эта функция заменяет toUCSindex.
Стандарты:
Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252
Исключения:
UTFException если str не соответствует формату.
Примеры:
writeln(count("")); // 0
writeln(count("a")); // 1
writeln(count("abc")); // 3
writeln(count("\u20AC100")); // 4
enum dchar replacementDchar;

Вставляется вместо недопустимых последовательностей UTF.

Ссылки
http://en.wikipedia.org/wiki/Replacement_character#Replacement_character
auto byCodeUnit(R)(R r)
Constraints: if (isConvertibleToString!R && !isStaticArray!R || isInputRange!R && isSomeChar!(ElementEncodingType!R));

Итерация по диапазону char, wchar или dchar по кодовым единицам.

Цель состоит в том, чтобы обойти специальный случай декодирования, который выполняет std.range.primitives.front для массивов символов. В результате, использование диапазонов с byCodeUnit может быть nothrow, в то время как std.range.primitives.front выбрасывает исключение при обнаружении недопустимых последовательностей Unicode.

Кодовая единица — это строительный блок кодировок UTF. Как правило, отдельная кодовая единица не представляет то, что воспринимается как полный символ (т.е. кластер графем в терминологии Unicode). Многие символы кодируются несколькими кодовыми единицами. Например, кодовые единицы UTF-8 для ø равны 0xC3 0xB8. Это означает, что отдельная единица byCodeUnit часто не образует символ сама по себе. Попытка обработать её как единый символ при итерации по полученному диапазону даст бессмысленные результаты.

Параметры:
R r диапазон ввода символов (включая строки) или тип, который неявно преобразуется в тип строки.
Возвращает:
Если r не является автоматически декодируемой строкой (т.е. узкой строкой или типом, определённым пользователем, который неявно преобразуется в тип строки), то возвращается r. В противном случае r преобразуется в соответствующий тип строки (если это не строка) и оборачивается в диапазон с произвольным доступом, где тип кодирования элемента строки (его кодовая единица) является типом элемента диапазона, и этот диапазон возвращается. Диапазон имеет срезы. Если r достаточно необычен, чтобы быть структурой или классом, который сам по себе является диапазоном ввода символов (т.е. у него есть API диапазона ввода как методы членов), и он неявно преобразуется в тип строки, то возвращается r, и не происходит неявного преобразования. Если r оборачивается в новый диапазон, то этот диапазон имеет свойство source для возвращения строки, которая в настоящее время содержится в этом диапазоне.
См. также:
См. документацию по std.uni для справочной информации по терминологии Unicode. Для диапазона, итерирующего по кластеру графем (написанному символу), см. std.uni.byGrapheme.
Примеры:
import std.range.primitives;
import std.traits : isAutodecodableString;

auto r = "Hello, World!".byCodeUnit();
static assert(hasLength!(typeof(r)));
static assert(hasSlicing!(typeof(r)));
static assert(isRandomAccessRange!(typeof(r)));
static assert(is(ElementType!(typeof(r)) == immutable char));

// contrast with the range capabilities of standard strings (with or
// without autodecoding enabled).
auto s = "Hello, World!";
static assert(isBidirectionalRange!(typeof(r)));
static if (isAutodecodableString!(typeof(s)))
{
    // with autodecoding enabled, strings are non-random-access ranges of
    // dchar.
    static assert(is(ElementType!(typeof(s)) == dchar));
    static assert(!isRandomAccessRange!(typeof(s)));
    static assert(!hasSlicing!(typeof(s)));
    static assert(!hasLength!(typeof(s)));
}
else
{
    // without autodecoding, strings are normal arrays.
    static assert(is(ElementType!(typeof(s)) == immutable char));
    static assert(isRandomAccessRange!(typeof(s)));
    static assert(hasSlicing!(typeof(s)));
    static assert(hasLength!(typeof(s)));
}
Примеры:
byCodeUnit не выполняет декодирование Unicode
string noel1 = "noe\u0308l"; // noël using e + combining diaeresis
assert(noel1.byCodeUnit[2] != 'ë');
writeln(noel1.byCodeUnit[2]); // 'e'

string noel2 = "no\u00EBl"; // noël using a precomposed ë character
// Because string is UTF-8, the code unit at index 2 is just
// the first of a sequence that encodes 'ë'
assert(noel2.byCodeUnit[2] != 'ë');
Примеры:
byCodeUnit предоставляет свойство source при обёртывании узких строк.
import std.algorithm.comparison : equal;
import std.range : popFrontN;
import std.traits : isAutodecodableString;
{
    auto range = byCodeUnit("hello world");
    range.popFrontN(3);
    assert(equal(range.save, "lo world"));
    static if (isAutodecodableString!string) // only enabled with autodecoding
    {
        string str = range.source;
        writeln(str); // "lo world"
    }
}
// source only exists if the range was wrapped
{
    auto range = byCodeUnit("hello world"d);
    static assert(!__traits(compiles, range.source));
}
alias byChar = byUTF!(char, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R));

alias byWchar = byUTF!(wchar, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R));

alias byDchar = byUTF!(dchar, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R));

Итерация по диапазону ввода символов по char, wchar или dchar. Эти псевдонимы просто перенаправляют на byUTF с соответствующим аргументом C.

Параметры:
R r диапазон ввода символов или массив символов
template byUTF(C, UseReplacementDchar useReplacementDchar = Yes.useReplacementDchar) if (isSomeChar!C)

Итерация по диапазону ввода символов по типу char C путём кодирования элементов диапазона.

Последовательности UTF, которые не могут быть преобразованы в указанную кодировку, либо заменяются U+FFFD в соответствии с «5.22 Лучшая практика для замены U+FFFD» стандарта Unicode 6.2, либо приводят к выбросу UTFException. Следовательно, byUTF не симметричен. Этот алгоритм ленивый и не выделяет память. @nogc, pure-ность, nothrow, и @safe-ность выводятся из параметра r.

Параметры:
C char, wchar, или dchar
useReplacementDchar UseReplacementDchar.yes означает заменить недопустимый UTF на replacementDchar, UseReplacementDchar.no означает выбросить UTFException для недопустимого UTF
Исключения:
UTFException если недопустимая последовательность UTF и useReplacementDchar установлено в UseReplacementDchar.yes
GC
Не использует GC, если useReplacementDchar установлено в UseReplacementDchar.no
Возвращает:
Векторный диапазон, если R является диапазоном и не является автоматически декодируемой строкой, как определено в std.traits.isAutodecodableString, и если базовый диапазон также является векторным диапазоном. Или, если R является диапазоном и он является автоматически декодируемой строкой и is(ElementEncodingType!typeof(r) == C), то диапазон передаётся в byCodeUnit. В противном случае — диапазон ввода символов.
Примеры:
import std.algorithm.comparison : equal;

// hellö as a range of `char`s, which are UTF-8
assert("hell\u00F6".byUTF!char().equal(['h', 'e', 'l', 'l', 0xC3, 0xB6]));

// `wchar`s are able to hold the ö in a single element (UTF-16 code unit)
assert("hell\u00F6".byUTF!wchar().equal(['h', 'e', 'l', 'l', 'ö']));

// 𐐷 is four code units in UTF-8, two in UTF-16, and one in UTF-32
assert("𐐷".byUTF!char().equal([0xF0, 0x90, 0x90, 0xB7]));
assert("𐐷".byUTF!wchar().equal([0xD801, 0xDC37]));
assert("𐐷".byUTF!dchar().equal([0x00010437]));
Примеры:
import std.algorithm.comparison : equal;
import std.exception : assertThrown;

assert("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.yes).equal("hello\uFFFDetty"));
assertThrown!UTFException("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.no).equal("hello betty"));

© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_utf.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API