Path: blob/main/contrib/llvm-project/libcxx/include/__locale_dir/wstring_convert.h
213766 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef _LIBCPP___LOCALE_DIR_WSTRING_CONVERT_H9#define _LIBCPP___LOCALE_DIR_WSTRING_CONVERT_H1011#include <__config>12#include <__locale>13#include <__memory/allocator.h>14#include <string>1516#if _LIBCPP_HAS_LOCALIZATION1718# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)19# pragma GCC system_header20# endif2122# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)2324_LIBCPP_PUSH_MACROS25# include <__undef_macros>2627_LIBCPP_BEGIN_NAMESPACE_STD2829template <class _Codecvt,30class _Elem = wchar_t,31class _WideAlloc = allocator<_Elem>,32class _ByteAlloc = allocator<char> >33class _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert {34public:35typedef basic_string<char, char_traits<char>, _ByteAlloc> byte_string;36typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string;37typedef typename _Codecvt::state_type state_type;38typedef typename wide_string::traits_type::int_type int_type;3940private:41byte_string __byte_err_string_;42wide_string __wide_err_string_;43_Codecvt* __cvtptr_;44state_type __cvtstate_;45size_t __cvtcount_;4647public:48# ifndef _LIBCPP_CXX03_LANG49_LIBCPP_HIDE_FROM_ABI wstring_convert() : wstring_convert(new _Codecvt) {}50_LIBCPP_HIDE_FROM_ABI explicit wstring_convert(_Codecvt* __pcvt);51# else52_LIBCPP_HIDE_FROM_ABI _LIBCPP_EXPLICIT_SINCE_CXX14 wstring_convert(_Codecvt* __pcvt = new _Codecvt);53# endif5455_LIBCPP_HIDE_FROM_ABI wstring_convert(_Codecvt* __pcvt, state_type __state);56_LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI57wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err = wide_string());58# ifndef _LIBCPP_CXX03_LANG59_LIBCPP_HIDE_FROM_ABI wstring_convert(wstring_convert&& __wc);60# endif61_LIBCPP_HIDE_FROM_ABI ~wstring_convert();6263wstring_convert(const wstring_convert& __wc) = delete;64wstring_convert& operator=(const wstring_convert& __wc) = delete;6566_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(char __byte) { return from_bytes(&__byte, &__byte + 1); }67_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __ptr) {68return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));69}70_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const byte_string& __str) {71return from_bytes(__str.data(), __str.data() + __str.size());72}73_LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last);7475_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(_Elem __wchar) {76return to_bytes(std::addressof(__wchar), std::addressof(__wchar) + 1);77}78_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __wptr) {79return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));80}81_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const wide_string& __wstr) {82return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());83}84_LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last);8586_LIBCPP_HIDE_FROM_ABI size_t converted() const _NOEXCEPT { return __cvtcount_; }87_LIBCPP_HIDE_FROM_ABI state_type state() const { return __cvtstate_; }88};8990_LIBCPP_SUPPRESS_DEPRECATED_PUSH91template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>92inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt)93: __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) {}94_LIBCPP_SUPPRESS_DEPRECATED_POP9596template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>97inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(_Codecvt* __pcvt, state_type __state)98: __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) {}99100template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>101wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(102const byte_string& __byte_err, const wide_string& __wide_err)103: __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), __cvtstate_(), __cvtcount_(0) {104__cvtptr_ = new _Codecvt;105}106107# ifndef _LIBCPP_CXX03_LANG108109template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>110inline wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wstring_convert(wstring_convert&& __wc)111: __byte_err_string_(std::move(__wc.__byte_err_string_)),112__wide_err_string_(std::move(__wc.__wide_err_string_)),113__cvtptr_(__wc.__cvtptr_),114__cvtstate_(__wc.__cvtstate_),115__cvtcount_(__wc.__cvtcount_) {116__wc.__cvtptr_ = nullptr;117}118119# endif // _LIBCPP_CXX03_LANG120121_LIBCPP_SUPPRESS_DEPRECATED_PUSH122template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>123wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert() {124delete __cvtptr_;125}126127template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>128typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string129wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::from_bytes(const char* __frm, const char* __frm_end) {130_LIBCPP_SUPPRESS_DEPRECATED_POP131__cvtcount_ = 0;132if (__cvtptr_ != nullptr) {133wide_string __ws(2 * (__frm_end - __frm), _Elem());134if (__frm != __frm_end)135__ws.resize(__ws.capacity());136codecvt_base::result __r = codecvt_base::ok;137state_type __st = __cvtstate_;138if (__frm != __frm_end) {139_Elem* __to = std::addressof(__ws[0]);140_Elem* __to_end = __to + __ws.size();141const char* __frm_nxt;142do {143_Elem* __to_nxt;144__r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);145__cvtcount_ += __frm_nxt - __frm;146if (__frm_nxt == __frm) {147__r = codecvt_base::error;148} else if (__r == codecvt_base::noconv) {149__ws.resize(__to - std::addressof(__ws[0]));150// This only gets executed if _Elem is char151__ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);152__frm = __frm_nxt;153__r = codecvt_base::ok;154} else if (__r == codecvt_base::ok) {155__ws.resize(__to_nxt - std::addressof(__ws[0]));156__frm = __frm_nxt;157} else if (__r == codecvt_base::partial) {158ptrdiff_t __s = __to_nxt - std::addressof(__ws[0]);159__ws.resize(2 * __s);160__to = std::addressof(__ws[0]) + __s;161__to_end = std::addressof(__ws[0]) + __ws.size();162__frm = __frm_nxt;163}164} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);165}166if (__r == codecvt_base::ok)167return __ws;168}169170if (__wide_err_string_.empty())171std::__throw_range_error("wstring_convert: from_bytes error");172173return __wide_err_string_;174}175176template <class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc>177typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string178wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::to_bytes(const _Elem* __frm, const _Elem* __frm_end) {179__cvtcount_ = 0;180if (__cvtptr_ != nullptr) {181byte_string __bs(2 * (__frm_end - __frm), char());182if (__frm != __frm_end)183__bs.resize(__bs.capacity());184codecvt_base::result __r = codecvt_base::ok;185state_type __st = __cvtstate_;186if (__frm != __frm_end) {187char* __to = std::addressof(__bs[0]);188char* __to_end = __to + __bs.size();189const _Elem* __frm_nxt;190do {191char* __to_nxt;192__r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);193__cvtcount_ += __frm_nxt - __frm;194if (__frm_nxt == __frm) {195__r = codecvt_base::error;196} else if (__r == codecvt_base::noconv) {197__bs.resize(__to - std::addressof(__bs[0]));198// This only gets executed if _Elem is char199__bs.append((const char*)__frm, (const char*)__frm_end);200__frm = __frm_nxt;201__r = codecvt_base::ok;202} else if (__r == codecvt_base::ok) {203__bs.resize(__to_nxt - std::addressof(__bs[0]));204__frm = __frm_nxt;205} else if (__r == codecvt_base::partial) {206ptrdiff_t __s = __to_nxt - std::addressof(__bs[0]);207__bs.resize(2 * __s);208__to = std::addressof(__bs[0]) + __s;209__to_end = std::addressof(__bs[0]) + __bs.size();210__frm = __frm_nxt;211}212} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);213}214if (__r == codecvt_base::ok) {215size_t __s = __bs.size();216__bs.resize(__bs.capacity());217char* __to = std::addressof(__bs[0]) + __s;218char* __to_end = __to + __bs.size();219do {220char* __to_nxt;221__r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);222if (__r == codecvt_base::noconv) {223__bs.resize(__to - std::addressof(__bs[0]));224__r = codecvt_base::ok;225} else if (__r == codecvt_base::ok) {226__bs.resize(__to_nxt - std::addressof(__bs[0]));227} else if (__r == codecvt_base::partial) {228ptrdiff_t __sp = __to_nxt - std::addressof(__bs[0]);229__bs.resize(2 * __sp);230__to = std::addressof(__bs[0]) + __sp;231__to_end = std::addressof(__bs[0]) + __bs.size();232}233} while (__r == codecvt_base::partial);234if (__r == codecvt_base::ok)235return __bs;236}237}238239if (__byte_err_string_.empty())240std::__throw_range_error("wstring_convert: to_bytes error");241242return __byte_err_string_;243}244245_LIBCPP_END_NAMESPACE_STD246247_LIBCPP_POP_MACROS248249# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)250251#endif // _LIBCPP_HAS_LOCALIZATION252253#endif // _LIBCPP___LOCALE_DIR_WSTRING_CONVERT_H254255256