1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___LOCALE_DIR_UTF8_CONVERSIONS_H
10#define _LIBCPP___LOCALE_DIR_UTF8_CONVERSIONS_H
11
12#include <__config>
13
14#if _LIBCPP_HAS_LOCALIZATION
15
16# include <__cstddef/size_t.h>
17# include <__locale_dir/codecvt.h>
18# include <__std_mbstate_t.h>
19# include <stdexcept>
20
21# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22# pragma GCC system_header
23# endif
24
25_LIBCPP_BEGIN_NAMESPACE_STD
26_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
27
28template <size_t _Np>
29struct __narrow_to_utf8 {
30 template <class _OutputIterator, class _CharT>
31 _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
32};
33
34template <>
35struct __narrow_to_utf8<8> {
36 template <class _OutputIterator, class _CharT>
37 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
38 for (; __wb < __we; ++__wb, ++__s)
39 *__s = *__wb;
40 return __s;
41 }
42};
43
44_LIBCPP_SUPPRESS_DEPRECATED_PUSH
45template <>
46struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
47 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
48 _LIBCPP_SUPPRESS_DEPRECATED_POP
49
50 ~__narrow_to_utf8() override;
51
52 template <class _OutputIterator, class _CharT>
53 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
54 result __r = ok;
55 mbstate_t __mb;
56 while (__wb < __we && __r != error) {
57 const int __sz = 32;
58 char __buf[__sz];
59 char* __bn;
60 const char16_t* __wn = (const char16_t*)__wb;
61 __r = do_out(st&: __mb, frm: (const char16_t*)__wb, frm_end: (const char16_t*)__we, frm_nxt&: __wn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn);
62 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
63 std::__throw_runtime_error("locale not supported");
64 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
65 *__s = *__p;
66 __wb = (const _CharT*)__wn;
67 }
68 return __s;
69 }
70};
71
72_LIBCPP_SUPPRESS_DEPRECATED_PUSH
73template <>
74struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
75 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
76 _LIBCPP_SUPPRESS_DEPRECATED_POP
77
78 ~__narrow_to_utf8() override;
79
80 template <class _OutputIterator, class _CharT>
81 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
82 result __r = ok;
83 mbstate_t __mb;
84 while (__wb < __we && __r != error) {
85 const int __sz = 32;
86 char __buf[__sz];
87 char* __bn;
88 const char32_t* __wn = (const char32_t*)__wb;
89 __r = do_out(st&: __mb, frm: (const char32_t*)__wb, frm_end: (const char32_t*)__we, frm_nxt&: __wn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn);
90 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
91 std::__throw_runtime_error("locale not supported");
92 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
93 *__s = *__p;
94 __wb = (const _CharT*)__wn;
95 }
96 return __s;
97 }
98};
99
100template <size_t _Np>
101struct __widen_from_utf8 {
102 template <class _OutputIterator>
103 _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
104};
105
106template <>
107struct __widen_from_utf8<8> {
108 template <class _OutputIterator>
109 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
110 for (; __nb < __ne; ++__nb, ++__s)
111 *__s = *__nb;
112 return __s;
113 }
114};
115
116_LIBCPP_SUPPRESS_DEPRECATED_PUSH
117template <>
118struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
119 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
120 _LIBCPP_SUPPRESS_DEPRECATED_POP
121
122 ~__widen_from_utf8() override;
123
124 template <class _OutputIterator>
125 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
126 result __r = ok;
127 mbstate_t __mb;
128 while (__nb < __ne && __r != error) {
129 const int __sz = 32;
130 char16_t __buf[__sz];
131 char16_t* __bn;
132 const char* __nn = __nb;
133 __r = do_in(st&: __mb, frm: __nb, frm_end: __ne - __nb > __sz ? __nb + __sz : __ne, frm_nxt&: __nn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn);
134 if (__r == codecvt_base::error || __nn == __nb)
135 std::__throw_runtime_error("locale not supported");
136 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
137 *__s = *__p;
138 __nb = __nn;
139 }
140 return __s;
141 }
142};
143
144_LIBCPP_SUPPRESS_DEPRECATED_PUSH
145template <>
146struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
147 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
148 _LIBCPP_SUPPRESS_DEPRECATED_POP
149
150 ~__widen_from_utf8() override;
151
152 template <class _OutputIterator>
153 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
154 result __r = ok;
155 mbstate_t __mb;
156 while (__nb < __ne && __r != error) {
157 const int __sz = 32;
158 char32_t __buf[__sz];
159 char32_t* __bn;
160 const char* __nn = __nb;
161 __r = do_in(st&: __mb, frm: __nb, frm_end: __ne - __nb > __sz ? __nb + __sz : __ne, frm_nxt&: __nn, to: __buf, to_end: __buf + __sz, to_nxt&: __bn);
162 if (__r == codecvt_base::error || __nn == __nb)
163 std::__throw_runtime_error("locale not supported");
164 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
165 *__s = *__p;
166 __nb = __nn;
167 }
168 return __s;
169 }
170};
171
172_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
173_LIBCPP_END_NAMESPACE_STD
174
175#endif // _LIBCPP_HAS_LOCALIZATION
176
177#endif // _LIBCPP___LOCALE_DIR_UTF8_CONVERSIONS_H
178