std::codecvt<InternT,ExternT,StateT>::out, do_out
Определено в заголовочном файле <locale> | ||
|---|---|---|
public:
result out( StateT& state,
const InternT* from,
const InternT* from_end,
const InternT*& from_next,
ExternT* to,
ExternT* to_end,
ExternT*& to_next ) const;
| (1) | |
protected:
virtual result do_out( StateT& state,
const InternT* from,
const InternT* from_end,
const InternT*& from_next,
ExternT* to,
ExternT* to_end,
ExternT*& to_next ) const;
| (2) |
do_out наиболее производного класса.codecvt определяет преобразование, преобразует внутренние символы из исходного диапазона [from, from_end) во внешние символы, помещая результаты в последующие позиции, начиная с to. Преобразует не более from_end - from внутренних символов и записывает не более to_end - to внешних символов. Оставляет from_next и to_next указывающими на позицию сразу за последним успешно преобразованным элементом.Если этот фасет codecvt не определяет преобразование, символы не преобразуются. to_next устанавливается равным to, state не изменяется, а функция возвращает std::codecvt_base::noconv.
do_out(state, from, from + 1, from_next, to, to_end, to_next) должен возвращать ok, если
- этот фасет
codecvtиспользуется вbasic_filebuf, и -
do_out(state, from, from_end, from_next, to, to_end, to_next)возвращал быok, когдаfrom != from_end.
Возвращаемое значение
Значение типа std::codecvt_base::result, указывающее статус выполнения следующим образом:
ok | преобразование завершено |
partial | недостаточно места в выходном буфере или неожиданный конец исходного буфера |
error | обнаружен символ, который не удалось преобразовать |
noconv | этот фасет не выполняет преобразование, данные не записаны |
Специализация без преобразования std::codecvt<char, char, std::mbstate_t> всегда возвращает std::codecvt_base::noconv.
Примечания
Требуется, чтобы from <= from_end && to <= to_end и чтобы state находилось либо в начальном состоянии сдвига, либо было получено преобразованием предшествующих символов последовательности.
Хотя codecvt поддерживает преобразования N:M (например, из UTF-16 в UTF-8, где для определения выходных символов могут потребоваться два внутренних символа), std::basic_filebuf может использовать только фасеты codecvt, определяющие преобразование 1:N; то есть при записи в файл он должен уметь обрабатывать по одному внутреннему символу за раз.
При выполнении преобразований N:M эта функция может вернуть std::codecvt_base::partial после считывания всех исходных символов (from_next == from_end). Это означает, что для завершения преобразования требуется ещё один внутренний символ (например, при преобразовании из UTF-16 в UTF-8, если последний символ в исходном буфере — старший суррогат).
Воздействие на state намеренно не определено. В стандартных фасетах он используется для поддержания состояния сдвига, как при вызове std::wcsrtombs, и поэтому обновляется с учётом состояния сдвига после последнего успешно преобразованного символа. Однако пользовательский фасет может использовать его для поддержания любого другого состояния, например для подсчёта числа встреченных специальных символов.
Пример
#include <iostream>
#include <locale>
#include <string>
int main()
{
std::locale::global(std::locale("en_US.utf8"));
auto& f = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(std::locale());
std::wstring internal = L"z\u00df\u6c34\U0001f34c"; // L"zß水🍌"
// note that the following can be done with wstring_convert
std::mbstate_t mb{}; // initial shift state
std::string external(internal.size() * f.max_length(), '\0');
const wchar_t* from_next;
char* to_next;
f.out(mb, &internal[0], &internal[internal.size()], from_next,
&external[0], &external[external.size()], to_next);
// error checking skipped for brevity
external.resize(to_next - &external[0]);
std::cout << "The string in narrow multibyte encoding: " << external << '\n';
}
Вывод:
The string in narrow multibyte encoding: zß水🍌
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были ретроактивно применены к ранее опубликованным стандартам C++.
| DR | Применяется к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 76 | C++98 | было неясно, должно ли преобразование поддерживать обработку по одному внутреннему символу за раз | требуется только при использовании в basic_filebuf |
См. также
|
[virtual] | записывает символы в связанный файл из области записи (виртуальная защищённая функция-член std::basic_filebuf<CharT,Traits>) |
| преобразует широкую строку в байтовую строку (открытая функция-член std::wstring_convert<Codecvt,Elem,Wide_alloc,Byte_alloc>) |
|
| преобразует широкую строку в узкую многобайтовую строку символов с учётом состояния (функция) |
|
|
[virtual] | преобразует строку из ExternT в InternT, например при чтении из файла (виртуальная защищённая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/locale/codecvt/out