1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include <__utility/no_destroy.h>
20 #include <type_traits>
25 #if _LIBCPP_HAS_WIDE_CHARACTERS
30 # include <sys/localedef.h> // for __lc_ctype_ptr
33 #if defined(_LIBCPP_MSVCRT)
34 # define _CTYPE_DISABLE_MACROS
37 #if __has_include("<langinfo.h>")
38 # include <langinfo.h>
41 #include "include/atomic_support.h"
42 #include "include/sso_allocator.h"
44 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
45 // lots of noise in the build log, but no bugs that I know of.
46 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
49 #include <__undef_macros>
51 _LIBCPP_BEGIN_NAMESPACE_STD
53 struct __libcpp_unique_locale
{
54 __libcpp_unique_locale(const char* nm
) : __loc_(__locale::__newlocale(LC_ALL_MASK
, nm
, 0)) {}
56 ~__libcpp_unique_locale() {
58 __locale::__freelocale(__loc_
);
61 explicit operator bool() const { return __loc_
; }
63 __locale::__locale_t
& get() { return __loc_
; }
65 __locale::__locale_t __loc_
;
68 __libcpp_unique_locale(__libcpp_unique_locale
const&);
69 __libcpp_unique_locale
& operator=(__libcpp_unique_locale
const&);
73 __locale::__locale_t
__cloc() {
74 // In theory this could create a race condition. In practice
75 // the race condition is non-fatal since it will just create
76 // a little resource leak. Better approach would be appreciated.
77 static __locale::__locale_t result
= __locale::__newlocale(LC_ALL_MASK
, "C", 0);
80 #endif // __cloc_defined
85 void operator()(locale::facet
* p
) { p
->__release_shared(); }
88 template <class T
, class... Args
>
89 T
& make(Args
... args
) {
90 alignas(T
) static std::byte buf
[sizeof(T
)];
91 auto* obj
= ::new (&buf
) T(args
...);
95 template <typename T
, size_t N
>
96 inline constexpr size_t countof(const T (&)[N
]) {
100 template <typename T
>
101 inline constexpr size_t countof(const T
* const begin
, const T
* const end
) {
102 return static_cast<size_t>(end
- begin
);
105 string
build_name(const string
& other
, const string
& one
, locale::category c
) {
106 if (other
== "*" || one
== "*")
108 if (c
== locale::none
|| other
== one
)
111 // FIXME: Handle the more complicated cases, such as when the locale has
112 // different names for different categories.
118 const locale::category
locale::none
;
119 const locale::category
locale::collate
;
120 const locale::category
locale::ctype
;
121 const locale::category
locale::monetary
;
122 const locale::category
locale::numeric
;
123 const locale::category
locale::time
;
124 const locale::category
locale::messages
;
125 const locale::category
locale::all
;
127 class _LIBCPP_HIDDEN
locale::__imp
: public facet
{
129 vector
<facet
*, __sso_allocator
<facet
*, N
> > facets_
;
133 explicit __imp(size_t refs
= 0);
134 explicit __imp(const string
& name
, size_t refs
= 0);
136 __imp(const __imp
&, const string
&, locale::category c
);
137 __imp(const __imp
& other
, const __imp
& one
, locale::category c
);
138 __imp(const __imp
&, facet
* f
, long id
);
141 const string
& name() const { return name_
; }
142 bool has_facet(long id
) const { return static_cast<size_t>(id
) < facets_
.size() && facets_
[static_cast<size_t>(id
)]; }
143 const locale::facet
* use_facet(long id
) const;
147 static __no_destroy
<__imp
> classic_locale_imp_
;
150 void install(facet
* f
, long id
);
153 install(f
, f
->id
.__get());
156 void install_from(const __imp
& other
);
159 locale::__imp::__imp(size_t refs
) : facet(refs
), facets_(N
), name_("C") {
161 install(&make
<std::collate
<char> >(1u));
162 #if _LIBCPP_HAS_WIDE_CHARACTERS
163 install(&make
<std::collate
<wchar_t> >(1u));
165 install(&make
<std::ctype
<char> >(nullptr, false, 1u));
166 #if _LIBCPP_HAS_WIDE_CHARACTERS
167 install(&make
<std::ctype
<wchar_t> >(1u));
169 install(&make
<codecvt
<char, char, mbstate_t> >(1u));
170 #if _LIBCPP_HAS_WIDE_CHARACTERS
171 install(&make
<codecvt
<wchar_t, char, mbstate_t> >(1u));
173 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
174 install(&make
<codecvt
<char16_t
, char, mbstate_t> >(1u));
175 install(&make
<codecvt
<char32_t
, char, mbstate_t> >(1u));
176 _LIBCPP_SUPPRESS_DEPRECATED_POP
177 #if _LIBCPP_HAS_CHAR8_T
178 install(&make
<codecvt
<char16_t
, char8_t
, mbstate_t> >(1u));
179 install(&make
<codecvt
<char32_t
, char8_t
, mbstate_t> >(1u));
181 install(&make
<numpunct
<char> >(1u));
182 #if _LIBCPP_HAS_WIDE_CHARACTERS
183 install(&make
<numpunct
<wchar_t> >(1u));
185 install(&make
<num_get
<char> >(1u));
186 #if _LIBCPP_HAS_WIDE_CHARACTERS
187 install(&make
<num_get
<wchar_t> >(1u));
189 install(&make
<num_put
<char> >(1u));
190 #if _LIBCPP_HAS_WIDE_CHARACTERS
191 install(&make
<num_put
<wchar_t> >(1u));
193 install(&make
<moneypunct
<char, false> >(1u));
194 install(&make
<moneypunct
<char, true> >(1u));
195 #if _LIBCPP_HAS_WIDE_CHARACTERS
196 install(&make
<moneypunct
<wchar_t, false> >(1u));
197 install(&make
<moneypunct
<wchar_t, true> >(1u));
199 install(&make
<money_get
<char> >(1u));
200 #if _LIBCPP_HAS_WIDE_CHARACTERS
201 install(&make
<money_get
<wchar_t> >(1u));
203 install(&make
<money_put
<char> >(1u));
204 #if _LIBCPP_HAS_WIDE_CHARACTERS
205 install(&make
<money_put
<wchar_t> >(1u));
207 install(&make
<time_get
<char> >(1u));
208 #if _LIBCPP_HAS_WIDE_CHARACTERS
209 install(&make
<time_get
<wchar_t> >(1u));
211 install(&make
<time_put
<char> >(1u));
212 #if _LIBCPP_HAS_WIDE_CHARACTERS
213 install(&make
<time_put
<wchar_t> >(1u));
215 install(&make
<std::messages
<char> >(1u));
216 #if _LIBCPP_HAS_WIDE_CHARACTERS
217 install(&make
<std::messages
<wchar_t> >(1u));
221 locale::__imp::__imp(const string
& name
, size_t refs
) : facet(refs
), facets_(N
), name_(name
) {
222 #if _LIBCPP_HAS_EXCEPTIONS
224 #endif // _LIBCPP_HAS_EXCEPTIONS
225 facets_
= locale::classic().__locale_
->facets_
;
226 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
228 facets_
[i
]->__add_shared();
229 install(new collate_byname
<char>(name_
));
230 #if _LIBCPP_HAS_WIDE_CHARACTERS
231 install(new collate_byname
<wchar_t>(name_
));
233 install(new ctype_byname
<char>(name_
));
234 #if _LIBCPP_HAS_WIDE_CHARACTERS
235 install(new ctype_byname
<wchar_t>(name_
));
237 install(new codecvt_byname
<char, char, mbstate_t>(name_
));
238 #if _LIBCPP_HAS_WIDE_CHARACTERS
239 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name_
));
241 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
242 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name_
));
243 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name_
));
244 _LIBCPP_SUPPRESS_DEPRECATED_POP
245 #if _LIBCPP_HAS_CHAR8_T
246 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name_
));
247 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name_
));
249 install(new numpunct_byname
<char>(name_
));
250 #if _LIBCPP_HAS_WIDE_CHARACTERS
251 install(new numpunct_byname
<wchar_t>(name_
));
253 install(new moneypunct_byname
<char, false>(name_
));
254 install(new moneypunct_byname
<char, true>(name_
));
255 #if _LIBCPP_HAS_WIDE_CHARACTERS
256 install(new moneypunct_byname
<wchar_t, false>(name_
));
257 install(new moneypunct_byname
<wchar_t, true>(name_
));
259 install(new time_get_byname
<char>(name_
));
260 #if _LIBCPP_HAS_WIDE_CHARACTERS
261 install(new time_get_byname
<wchar_t>(name_
));
263 install(new time_put_byname
<char>(name_
));
264 #if _LIBCPP_HAS_WIDE_CHARACTERS
265 install(new time_put_byname
<wchar_t>(name_
));
267 install(new messages_byname
<char>(name_
));
268 #if _LIBCPP_HAS_WIDE_CHARACTERS
269 install(new messages_byname
<wchar_t>(name_
));
271 #if _LIBCPP_HAS_EXCEPTIONS
273 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
275 facets_
[i
]->__release_shared();
278 #endif // _LIBCPP_HAS_EXCEPTIONS
281 locale::__imp::__imp(const __imp
& other
) : facets_(max
<size_t>(N
, other
.facets_
.size())), name_(other
.name_
) {
282 facets_
= other
.facets_
;
283 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
285 facets_
[i
]->__add_shared();
288 locale::__imp::__imp(const __imp
& other
, const string
& name
, locale::category c
)
289 : facets_(N
), name_(build_name(other
.name_
, name
, c
)) {
290 facets_
= other
.facets_
;
291 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
293 facets_
[i
]->__add_shared();
294 #if _LIBCPP_HAS_EXCEPTIONS
296 #endif // _LIBCPP_HAS_EXCEPTIONS
297 if (c
& locale::collate
) {
298 install(new collate_byname
<char>(name
));
299 #if _LIBCPP_HAS_WIDE_CHARACTERS
300 install(new collate_byname
<wchar_t>(name
));
303 if (c
& locale::ctype
) {
304 install(new ctype_byname
<char>(name
));
305 #if _LIBCPP_HAS_WIDE_CHARACTERS
306 install(new ctype_byname
<wchar_t>(name
));
308 install(new codecvt_byname
<char, char, mbstate_t>(name
));
309 #if _LIBCPP_HAS_WIDE_CHARACTERS
310 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name
));
312 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
313 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name
));
314 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name
));
315 _LIBCPP_SUPPRESS_DEPRECATED_POP
316 #if _LIBCPP_HAS_CHAR8_T
317 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name
));
318 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name
));
321 if (c
& locale::monetary
) {
322 install(new moneypunct_byname
<char, false>(name
));
323 install(new moneypunct_byname
<char, true>(name
));
324 #if _LIBCPP_HAS_WIDE_CHARACTERS
325 install(new moneypunct_byname
<wchar_t, false>(name
));
326 install(new moneypunct_byname
<wchar_t, true>(name
));
329 if (c
& locale::numeric
) {
330 install(new numpunct_byname
<char>(name
));
331 #if _LIBCPP_HAS_WIDE_CHARACTERS
332 install(new numpunct_byname
<wchar_t>(name
));
335 if (c
& locale::time
) {
336 install(new time_get_byname
<char>(name
));
337 #if _LIBCPP_HAS_WIDE_CHARACTERS
338 install(new time_get_byname
<wchar_t>(name
));
340 install(new time_put_byname
<char>(name
));
341 #if _LIBCPP_HAS_WIDE_CHARACTERS
342 install(new time_put_byname
<wchar_t>(name
));
345 if (c
& locale::messages
) {
346 install(new messages_byname
<char>(name
));
347 #if _LIBCPP_HAS_WIDE_CHARACTERS
348 install(new messages_byname
<wchar_t>(name
));
351 #if _LIBCPP_HAS_EXCEPTIONS
353 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
355 facets_
[i
]->__release_shared();
358 #endif // _LIBCPP_HAS_EXCEPTIONS
362 inline void locale::__imp::install_from(const locale::__imp
& one
) {
363 long id
= F::id
.__get();
364 install(const_cast<F
*>(static_cast<const F
*>(one
.use_facet(id
))), id
);
367 locale::__imp::__imp(const __imp
& other
, const __imp
& one
, locale::category c
)
368 : facets_(N
), name_(build_name(other
.name_
, one
.name_
, c
)) {
369 facets_
= other
.facets_
;
370 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
372 facets_
[i
]->__add_shared();
373 #if _LIBCPP_HAS_EXCEPTIONS
375 #endif // _LIBCPP_HAS_EXCEPTIONS
376 if (c
& locale::collate
) {
377 install_from
<std::collate
<char> >(one
);
378 #if _LIBCPP_HAS_WIDE_CHARACTERS
379 install_from
<std::collate
<wchar_t> >(one
);
382 if (c
& locale::ctype
) {
383 install_from
<std::ctype
<char> >(one
);
384 #if _LIBCPP_HAS_WIDE_CHARACTERS
385 install_from
<std::ctype
<wchar_t> >(one
);
387 install_from
<std::codecvt
<char, char, mbstate_t> >(one
);
388 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
389 install_from
<std::codecvt
<char16_t
, char, mbstate_t> >(one
);
390 install_from
<std::codecvt
<char32_t
, char, mbstate_t> >(one
);
391 _LIBCPP_SUPPRESS_DEPRECATED_POP
392 #if _LIBCPP_HAS_CHAR8_T
393 install_from
<std::codecvt
<char16_t
, char8_t
, mbstate_t> >(one
);
394 install_from
<std::codecvt
<char32_t
, char8_t
, mbstate_t> >(one
);
396 #if _LIBCPP_HAS_WIDE_CHARACTERS
397 install_from
<std::codecvt
<wchar_t, char, mbstate_t> >(one
);
400 if (c
& locale::monetary
) {
401 install_from
<moneypunct
<char, false> >(one
);
402 install_from
<moneypunct
<char, true> >(one
);
403 #if _LIBCPP_HAS_WIDE_CHARACTERS
404 install_from
<moneypunct
<wchar_t, false> >(one
);
405 install_from
<moneypunct
<wchar_t, true> >(one
);
407 install_from
<money_get
<char> >(one
);
408 #if _LIBCPP_HAS_WIDE_CHARACTERS
409 install_from
<money_get
<wchar_t> >(one
);
411 install_from
<money_put
<char> >(one
);
412 #if _LIBCPP_HAS_WIDE_CHARACTERS
413 install_from
<money_put
<wchar_t> >(one
);
416 if (c
& locale::numeric
) {
417 install_from
<numpunct
<char> >(one
);
418 #if _LIBCPP_HAS_WIDE_CHARACTERS
419 install_from
<numpunct
<wchar_t> >(one
);
421 install_from
<num_get
<char> >(one
);
422 #if _LIBCPP_HAS_WIDE_CHARACTERS
423 install_from
<num_get
<wchar_t> >(one
);
425 install_from
<num_put
<char> >(one
);
426 #if _LIBCPP_HAS_WIDE_CHARACTERS
427 install_from
<num_put
<wchar_t> >(one
);
430 if (c
& locale::time
) {
431 install_from
<time_get
<char> >(one
);
432 #if _LIBCPP_HAS_WIDE_CHARACTERS
433 install_from
<time_get
<wchar_t> >(one
);
435 install_from
<time_put
<char> >(one
);
436 #if _LIBCPP_HAS_WIDE_CHARACTERS
437 install_from
<time_put
<wchar_t> >(one
);
440 if (c
& locale::messages
) {
441 install_from
<std::messages
<char> >(one
);
442 #if _LIBCPP_HAS_WIDE_CHARACTERS
443 install_from
<std::messages
<wchar_t> >(one
);
446 #if _LIBCPP_HAS_EXCEPTIONS
448 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
450 facets_
[i
]->__release_shared();
453 #endif // _LIBCPP_HAS_EXCEPTIONS
456 locale::__imp::__imp(const __imp
& other
, facet
* f
, long id
)
457 : facets_(max
<size_t>(N
, other
.facets_
.size() + 1)), name_("*") {
459 unique_ptr
<facet
, releaser
> hold(f
);
460 facets_
= other
.facets_
;
461 for (unsigned i
= 0; i
< other
.facets_
.size(); ++i
)
463 facets_
[i
]->__add_shared();
464 install(hold
.get(), id
);
467 locale::__imp::~__imp() {
468 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
470 facets_
[i
]->__release_shared();
473 void locale::__imp::install(facet
* f
, long id
) {
475 unique_ptr
<facet
, releaser
> hold(f
);
476 if (static_cast<size_t>(id
) >= facets_
.size())
477 facets_
.resize(static_cast<size_t>(id
+ 1));
478 if (facets_
[static_cast<size_t>(id
)])
479 facets_
[static_cast<size_t>(id
)]->__release_shared();
480 facets_
[static_cast<size_t>(id
)] = hold
.release();
483 const locale::facet
* locale::__imp::use_facet(long id
) const {
486 return facets_
[static_cast<size_t>(id
)];
491 // We don't do reference counting on the classic locale.
492 // It's never destroyed anyway, but atomic reference counting may be very
493 // expensive in parallel applications. The classic locale is used by default
494 // in all streams. Note: if a new global locale is installed, then we lose
495 // the benefit of no reference counting.
496 constinit __no_destroy
<locale::__imp
>
497 locale::__imp::classic_locale_imp_(__uninitialized_tag
{}); // initialized below in classic()
499 const locale
& locale::classic() {
500 static const __no_destroy
<locale
> classic_locale(__private_constructor_tag
{}, [] {
501 // executed exactly once on first initialization of `classic_locale`
502 locale::__imp::classic_locale_imp_
.__emplace(1u);
503 return &locale::__imp::classic_locale_imp_
.__get();
505 return classic_locale
.__get();
508 locale
& locale::__global() {
509 static __no_destroy
<locale
> g(locale::classic());
513 void locale::__imp::acquire() {
514 if (this != &locale::__imp::classic_locale_imp_
.__get())
518 void locale::__imp::release() {
519 if (this != &locale::__imp::classic_locale_imp_
.__get())
523 locale::locale() noexcept
: __locale_(__global().__locale_
) { __locale_
->acquire(); }
525 locale::locale(const locale
& l
) noexcept
: __locale_(l
.__locale_
) { __locale_
->acquire(); }
527 locale::~locale() { __locale_
->release(); }
529 const locale
& locale::operator=(const locale
& other
) noexcept
{
530 other
.__locale_
->acquire();
531 __locale_
->release();
532 __locale_
= other
.__locale_
;
536 locale::locale(const char* name
)
537 : __locale_(name
? new __imp(name
) : (__throw_runtime_error("locale constructed with null"), nullptr)) {
538 __locale_
->acquire();
541 locale::locale(const string
& name
) : __locale_(new __imp(name
)) { __locale_
->acquire(); }
543 locale::locale(const locale
& other
, const char* name
, category c
)
544 : __locale_(name
? new __imp(*other
.__locale_
, name
, c
)
545 : (__throw_runtime_error("locale constructed with null"), nullptr)) {
546 __locale_
->acquire();
549 locale::locale(const locale
& other
, const string
& name
, category c
) : __locale_(new __imp(*other
.__locale_
, name
, c
)) {
550 __locale_
->acquire();
553 locale::locale(const locale
& other
, const locale
& one
, category c
)
554 : __locale_(new __imp(*other
.__locale_
, *one
.__locale_
, c
)) {
555 __locale_
->acquire();
558 string
locale::name() const { return __locale_
->name(); }
560 void locale::__install_ctor(const locale
& other
, facet
* f
, long facet_id
) {
562 __locale_
= new __imp(*other
.__locale_
, f
, facet_id
);
564 __locale_
= other
.__locale_
;
565 __locale_
->acquire();
568 locale
locale::global(const locale
& loc
) {
569 locale
& g
= __global();
573 setlocale(LC_ALL
, g
.name().c_str());
577 bool locale::has_facet(id
& x
) const { return __locale_
->has_facet(x
.__get()); }
579 const locale::facet
* locale::use_facet(id
& x
) const { return __locale_
->use_facet(x
.__get()); }
581 bool locale::operator==(const locale
& y
) const {
582 return (__locale_
== y
.__locale_
) || (__locale_
->name() != "*" && __locale_
->name() == y
.__locale_
->name());
587 locale::facet::~facet() {}
589 void locale::facet::__on_zero_shared() noexcept
{ delete this; }
593 constinit
int32_t locale::id::__next_id
= 0;
595 long locale::id::__get() {
596 call_once(__flag_
, [&] { __id_
= __libcpp_atomic_add(&__next_id
, 1); });
600 // template <> class collate_byname<char>
602 collate_byname
<char>::collate_byname(const char* n
, size_t refs
)
603 : collate
<char>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, n
, 0)) {
605 __throw_runtime_error(
606 ("collate_byname<char>::collate_byname"
607 " failed to construct for " +
612 collate_byname
<char>::collate_byname(const string
& name
, size_t refs
)
613 : collate
<char>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
.c_str(), 0)) {
615 __throw_runtime_error(
616 ("collate_byname<char>::collate_byname"
617 " failed to construct for " +
622 collate_byname
<char>::~collate_byname() { __locale::__freelocale(__l_
); }
624 int collate_byname
<char>::do_compare(
625 const char_type
* __lo1
, const char_type
* __hi1
, const char_type
* __lo2
, const char_type
* __hi2
) const {
626 string_type
lhs(__lo1
, __hi1
);
627 string_type
rhs(__lo2
, __hi2
);
628 int r
= __locale::__strcoll(lhs
.c_str(), rhs
.c_str(), __l_
);
636 collate_byname
<char>::string_type collate_byname
<char>::do_transform(const char_type
* lo
, const char_type
* hi
) const {
637 const string_type
in(lo
, hi
);
638 string_type
out(__locale::__strxfrm(0, in
.c_str(), 0, __l_
), char());
639 __locale::__strxfrm(const_cast<char*>(out
.c_str()), in
.c_str(), out
.size() + 1, __l_
);
643 // template <> class collate_byname<wchar_t>
645 #if _LIBCPP_HAS_WIDE_CHARACTERS
646 collate_byname
<wchar_t>::collate_byname(const char* n
, size_t refs
)
647 : collate
<wchar_t>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, n
, 0)) {
649 __throw_runtime_error(
650 ("collate_byname<wchar_t>::collate_byname(size_t refs)"
651 " failed to construct for " +
656 collate_byname
<wchar_t>::collate_byname(const string
& name
, size_t refs
)
657 : collate
<wchar_t>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
.c_str(), 0)) {
659 __throw_runtime_error(
660 ("collate_byname<wchar_t>::collate_byname(size_t refs)"
661 " failed to construct for " +
666 collate_byname
<wchar_t>::~collate_byname() { __locale::__freelocale(__l_
); }
668 int collate_byname
<wchar_t>::do_compare(
669 const char_type
* __lo1
, const char_type
* __hi1
, const char_type
* __lo2
, const char_type
* __hi2
) const {
670 string_type
lhs(__lo1
, __hi1
);
671 string_type
rhs(__lo2
, __hi2
);
672 int r
= __locale::__wcscoll(lhs
.c_str(), rhs
.c_str(), __l_
);
680 collate_byname
<wchar_t>::string_type
681 collate_byname
<wchar_t>::do_transform(const char_type
* lo
, const char_type
* hi
) const {
682 const string_type
in(lo
, hi
);
683 string_type
out(__locale::__wcsxfrm(0, in
.c_str(), 0, __l_
), wchar_t());
684 __locale::__wcsxfrm(const_cast<wchar_t*>(out
.c_str()), in
.c_str(), out
.size() + 1, __l_
);
687 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
689 const ctype_base::mask
ctype_base::space
;
690 const ctype_base::mask
ctype_base::print
;
691 const ctype_base::mask
ctype_base::cntrl
;
692 const ctype_base::mask
ctype_base::upper
;
693 const ctype_base::mask
ctype_base::lower
;
694 const ctype_base::mask
ctype_base::alpha
;
695 const ctype_base::mask
ctype_base::digit
;
696 const ctype_base::mask
ctype_base::punct
;
697 const ctype_base::mask
ctype_base::xdigit
;
698 const ctype_base::mask
ctype_base::blank
;
699 const ctype_base::mask
ctype_base::alnum
;
700 const ctype_base::mask
ctype_base::graph
;
702 // template <> class ctype<wchar_t>;
704 #if _LIBCPP_HAS_WIDE_CHARACTERS
705 constinit
locale::id ctype
<wchar_t>::id
;
707 ctype
<wchar_t>::~ctype() {}
709 bool ctype
<wchar_t>::do_is(mask m
, char_type c
) const {
710 return isascii(c
) ? (ctype
<char>::classic_table()[c
] & m
) != 0 : false;
713 const wchar_t* ctype
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const {
714 for (; low
!= high
; ++low
, ++vec
)
715 *vec
= static_cast<mask
>(isascii(*low
) ? ctype
<char>::classic_table()[*low
] : 0);
719 const wchar_t* ctype
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const {
720 for (; low
!= high
; ++low
)
721 if (isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
))
726 const wchar_t* ctype
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const {
727 for (; low
!= high
; ++low
)
728 if (!(isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
)))
733 wchar_t ctype
<wchar_t>::do_toupper(char_type c
) const {
734 # ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
735 return isascii(c
) ? _DefaultRuneLocale
.__mapupper
[c
] : c
;
736 # elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
737 return isascii(c
) ? ctype
<char>::__classic_upper_table()[c
] : c
;
739 return (isascii(c
) && __locale::__iswlower(c
, _LIBCPP_GET_C_LOCALE
)) ? c
- L
'a' + L
'A' : c
;
743 const wchar_t* ctype
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const {
744 for (; low
!= high
; ++low
)
745 # ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
746 *low
= isascii(*low
) ? _DefaultRuneLocale
.__mapupper
[*low
] : *low
;
747 # elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
748 *low
= isascii(*low
) ? ctype
<char>::__classic_upper_table()[*low
] : *low
;
750 *low
= (isascii(*low
) && __locale::__islower(*low
, _LIBCPP_GET_C_LOCALE
)) ? (*low
- L
'a' + L
'A') : *low
;
755 wchar_t ctype
<wchar_t>::do_tolower(char_type c
) const {
756 # ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
757 return isascii(c
) ? _DefaultRuneLocale
.__maplower
[c
] : c
;
758 # elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
759 return isascii(c
) ? ctype
<char>::__classic_lower_table()[c
] : c
;
761 return (isascii(c
) && __locale::__isupper(c
, _LIBCPP_GET_C_LOCALE
)) ? c
- L
'A' + 'a' : c
;
765 const wchar_t* ctype
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const {
766 for (; low
!= high
; ++low
)
767 # ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
768 *low
= isascii(*low
) ? _DefaultRuneLocale
.__maplower
[*low
] : *low
;
769 # elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
770 *low
= isascii(*low
) ? ctype
<char>::__classic_lower_table()[*low
] : *low
;
772 *low
= (isascii(*low
) && __locale::__isupper(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
- L
'A' + L
'a' : *low
;
777 wchar_t ctype
<wchar_t>::do_widen(char c
) const { return c
; }
779 const char* ctype
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const {
780 for (; low
!= high
; ++low
, ++dest
)
785 char ctype
<wchar_t>::do_narrow(char_type c
, char dfault
) const {
787 return static_cast<char>(c
);
791 const wchar_t* ctype
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const {
792 for (; low
!= high
; ++low
, ++dest
)
794 *dest
= static_cast<char>(*low
);
799 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
801 // template <> class ctype<char>;
803 constinit
locale::id ctype
<char>::id
;
805 const size_t ctype
<char>::table_size
;
807 ctype
<char>::ctype(const mask
* tab
, bool del
, size_t refs
) : locale::facet(refs
), __tab_(tab
), __del_(del
) {
809 __tab_
= classic_table();
812 ctype
<char>::~ctype() {
813 if (__tab_
&& __del_
)
817 char ctype
<char>::do_toupper(char_type c
) const {
818 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
819 return isascii(c
) ? static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(c
)]) : c
;
820 #elif defined(__NetBSD__)
821 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]);
822 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
823 return isascii(c
) ? static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]) : c
;
825 return (isascii(c
) && __locale::__islower(c
, _LIBCPP_GET_C_LOCALE
)) ? c
- 'a' + 'A' : c
;
829 const char* ctype
<char>::do_toupper(char_type
* low
, const char_type
* high
) const {
830 for (; low
!= high
; ++low
)
831 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
832 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(*low
)]) : *low
;
833 #elif defined(__NetBSD__)
834 *low
= static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low
)]);
835 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
836 *low
= isascii(*low
) ? static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low
)]) : *low
;
838 *low
= (isascii(*low
) && __locale::__islower(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
- 'a' + 'A' : *low
;
843 char ctype
<char>::do_tolower(char_type c
) const {
844 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
845 return isascii(c
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(c
)]) : c
;
846 #elif defined(__NetBSD__)
847 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c
)]);
848 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
849 return isascii(c
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(c
)]) : c
;
851 return (isascii(c
) && __locale::__isupper(c
, _LIBCPP_GET_C_LOCALE
)) ? c
- 'A' + 'a' : c
;
855 const char* ctype
<char>::do_tolower(char_type
* low
, const char_type
* high
) const {
856 for (; low
!= high
; ++low
)
857 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
858 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(*low
)]) : *low
;
859 #elif defined(__NetBSD__)
860 *low
= static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low
)]);
861 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
862 *low
= isascii(*low
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low
)]) : *low
;
864 *low
= (isascii(*low
) && __locale::__isupper(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
- 'A' + 'a' : *low
;
869 char ctype
<char>::do_widen(char c
) const { return c
; }
871 const char* ctype
<char>::do_widen(const char* low
, const char* high
, char_type
* dest
) const {
872 for (; low
!= high
; ++low
, ++dest
)
877 char ctype
<char>::do_narrow(char_type c
, char dfault
) const {
879 return static_cast<char>(c
);
883 const char* ctype
<char>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const {
884 for (; low
!= high
; ++low
, ++dest
)
892 #if defined(__EMSCRIPTEN__)
893 extern "C" const unsigned short** __ctype_b_loc();
894 extern "C" const int** __ctype_tolower_loc();
895 extern "C" const int** __ctype_toupper_loc();
898 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
899 const ctype
<char>::mask
* ctype
<char>::classic_table() noexcept
{
901 static constexpr const ctype
<char>::mask builtin_table
[table_size
] = {
906 cntrl
, cntrl
| space
| blank
,
907 cntrl
| space
, cntrl
| space
,
908 cntrl
| space
, cntrl
| space
,
918 space
| blank
| print
, punct
| print
,
919 punct
| print
, punct
| print
,
920 punct
| print
, punct
| print
,
921 punct
| print
, punct
| print
,
922 punct
| print
, punct
| print
,
923 punct
| print
, punct
| print
,
924 punct
| print
, punct
| print
,
925 punct
| print
, punct
| print
,
926 digit
| print
| xdigit
, digit
| print
| xdigit
,
927 digit
| print
| xdigit
, digit
| print
| xdigit
,
928 digit
| print
| xdigit
, digit
| print
| xdigit
,
929 digit
| print
| xdigit
, digit
| print
| xdigit
,
930 digit
| print
| xdigit
, digit
| print
| xdigit
,
931 punct
| print
, punct
| print
,
932 punct
| print
, punct
| print
,
933 punct
| print
, punct
| print
,
934 punct
| print
, upper
| xdigit
| print
| alpha
,
935 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
936 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
937 upper
| xdigit
| print
| alpha
, upper
| print
| alpha
,
938 upper
| print
| alpha
, upper
| print
| alpha
,
939 upper
| print
| alpha
, upper
| print
| alpha
,
940 upper
| print
| alpha
, upper
| print
| alpha
,
941 upper
| print
| alpha
, upper
| print
| alpha
,
942 upper
| print
| alpha
, upper
| print
| alpha
,
943 upper
| print
| alpha
, upper
| print
| alpha
,
944 upper
| print
| alpha
, upper
| print
| alpha
,
945 upper
| print
| alpha
, upper
| print
| alpha
,
946 upper
| print
| alpha
, upper
| print
| alpha
,
947 upper
| print
| alpha
, punct
| print
,
948 punct
| print
, punct
| print
,
949 punct
| print
, punct
| print
,
950 punct
| print
, lower
| xdigit
| print
| alpha
,
951 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
952 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
953 lower
| xdigit
| print
| alpha
, lower
| print
| alpha
,
954 lower
| print
| alpha
, lower
| print
| alpha
,
955 lower
| print
| alpha
, lower
| print
| alpha
,
956 lower
| print
| alpha
, lower
| print
| alpha
,
957 lower
| print
| alpha
, lower
| print
| alpha
,
958 lower
| print
| alpha
, lower
| print
| alpha
,
959 lower
| print
| alpha
, lower
| print
| alpha
,
960 lower
| print
| alpha
, lower
| print
| alpha
,
961 lower
| print
| alpha
, lower
| print
| alpha
,
962 lower
| print
| alpha
, lower
| print
| alpha
,
963 lower
| print
| alpha
, punct
| print
,
964 punct
| print
, punct
| print
,
965 punct
| print
, cntrl
,
966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
967 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
969 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
970 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
973 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
976 return builtin_table
;
979 const ctype
<char>::mask
* ctype
<char>::classic_table() noexcept
{
980 # if defined(__APPLE__) || defined(__FreeBSD__)
981 return _DefaultRuneLocale
.__runetype
;
982 # elif defined(__NetBSD__)
983 return _C_ctype_tab_
+ 1;
984 # elif defined(__GLIBC__)
985 return _LIBCPP_GET_C_LOCALE
->__ctype_b
;
986 # elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
987 return __pctype_func();
988 # elif defined(__EMSCRIPTEN__)
989 return *__ctype_b_loc();
990 # elif defined(_NEWLIB_VERSION)
991 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
994 return (const unsigned int*)__lc_ctype_ptr
->obj
->mask
;
995 # elif defined(__MVS__)
996 # if defined(__NATIVE_ASCII_F)
997 return const_cast<const ctype
<char>::mask
*>(__OBJ_DATA(__lc_ctype_a
)->mask
);
999 return const_cast<const ctype
<char>::mask
*>(__ctypec
);
1002 // Platform not supported: abort so the person doing the port knows what to
1004 # warning ctype<char>::classic_table() is not implemented
1005 printf("ctype<char>::classic_table() is not implemented\n");
1012 #if defined(__GLIBC__)
1013 const int* ctype
<char>::__classic_lower_table() noexcept
{ return _LIBCPP_GET_C_LOCALE
->__ctype_tolower
; }
1015 const int* ctype
<char>::__classic_upper_table() noexcept
{ return _LIBCPP_GET_C_LOCALE
->__ctype_toupper
; }
1016 #elif defined(__NetBSD__)
1017 const short* ctype
<char>::__classic_lower_table() noexcept
{ return _C_tolower_tab_
+ 1; }
1019 const short* ctype
<char>::__classic_upper_table() noexcept
{ return _C_toupper_tab_
+ 1; }
1021 #elif defined(__EMSCRIPTEN__)
1022 const int* ctype
<char>::__classic_lower_table() noexcept
{ return *__ctype_tolower_loc(); }
1024 const int* ctype
<char>::__classic_upper_table() noexcept
{ return *__ctype_toupper_loc(); }
1025 #elif defined(__MVS__)
1026 const unsigned short* ctype
<char>::__classic_lower_table() _NOEXCEPT
{
1027 # if defined(__NATIVE_ASCII_F)
1028 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->lower
);
1030 return const_cast<const unsigned short*>(__ctype
+ __TOLOWER_INDEX
);
1033 const unsigned short* ctype
<char>::__classic_upper_table() _NOEXCEPT
{
1034 # if defined(__NATIVE_ASCII_F)
1035 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->upper
);
1037 return const_cast<const unsigned short*>(__ctype
+ __TOUPPER_INDEX
);
1040 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1042 // template <> class ctype_byname<char>
1044 ctype_byname
<char>::ctype_byname(const char* name
, size_t refs
)
1045 : ctype
<char>(0, false, refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
, 0)) {
1047 __throw_runtime_error(
1048 ("ctype_byname<char>::ctype_byname"
1049 " failed to construct for " +
1054 ctype_byname
<char>::ctype_byname(const string
& name
, size_t refs
)
1055 : ctype
<char>(0, false, refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
.c_str(), 0)) {
1057 __throw_runtime_error(
1058 ("ctype_byname<char>::ctype_byname"
1059 " failed to construct for " +
1064 ctype_byname
<char>::~ctype_byname() { __locale::__freelocale(__l_
); }
1066 char ctype_byname
<char>::do_toupper(char_type c
) const {
1067 return static_cast<char>(__locale::__toupper(static_cast<unsigned char>(c
), __l_
));
1070 const char* ctype_byname
<char>::do_toupper(char_type
* low
, const char_type
* high
) const {
1071 for (; low
!= high
; ++low
)
1072 *low
= static_cast<char>(__locale::__toupper(static_cast<unsigned char>(*low
), __l_
));
1076 char ctype_byname
<char>::do_tolower(char_type c
) const {
1077 return static_cast<char>(__locale::__tolower(static_cast<unsigned char>(c
), __l_
));
1080 const char* ctype_byname
<char>::do_tolower(char_type
* low
, const char_type
* high
) const {
1081 for (; low
!= high
; ++low
)
1082 *low
= static_cast<char>(__locale::__tolower(static_cast<unsigned char>(*low
), __l_
));
1086 // template <> class ctype_byname<wchar_t>
1088 #if _LIBCPP_HAS_WIDE_CHARACTERS
1089 ctype_byname
<wchar_t>::ctype_byname(const char* name
, size_t refs
)
1090 : ctype
<wchar_t>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
, 0)) {
1092 __throw_runtime_error(
1093 ("ctype_byname<wchar_t>::ctype_byname"
1094 " failed to construct for " +
1099 ctype_byname
<wchar_t>::ctype_byname(const string
& name
, size_t refs
)
1100 : ctype
<wchar_t>(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, name
.c_str(), 0)) {
1102 __throw_runtime_error(
1103 ("ctype_byname<wchar_t>::ctype_byname"
1104 " failed to construct for " +
1109 ctype_byname
<wchar_t>::~ctype_byname() { __locale::__freelocale(__l_
); }
1111 bool ctype_byname
<wchar_t>::do_is(mask m
, char_type c
) const {
1112 # ifdef _LIBCPP_WCTYPE_IS_MASK
1113 return static_cast<bool>(iswctype_l(c
, m
, __l_
));
1115 bool result
= false;
1116 wint_t ch
= static_cast<wint_t>(c
);
1117 if ((m
& space
) == space
)
1118 result
|= (__locale::__iswspace(ch
, __l_
) != 0);
1119 if ((m
& print
) == print
)
1120 result
|= (__locale::__iswprint(ch
, __l_
) != 0);
1121 if ((m
& cntrl
) == cntrl
)
1122 result
|= (__locale::__iswcntrl(ch
, __l_
) != 0);
1123 if ((m
& upper
) == upper
)
1124 result
|= (__locale::__iswupper(ch
, __l_
) != 0);
1125 if ((m
& lower
) == lower
)
1126 result
|= (__locale::__iswlower(ch
, __l_
) != 0);
1127 if ((m
& alpha
) == alpha
)
1128 result
|= (__locale::__iswalpha(ch
, __l_
) != 0);
1129 if ((m
& digit
) == digit
)
1130 result
|= (__locale::__iswdigit(ch
, __l_
) != 0);
1131 if ((m
& punct
) == punct
)
1132 result
|= (__locale::__iswpunct(ch
, __l_
) != 0);
1133 if ((m
& xdigit
) == xdigit
)
1134 result
|= (__locale::__iswxdigit(ch
, __l_
) != 0);
1135 if ((m
& blank
) == blank
)
1136 result
|= (__locale::__iswblank(ch
, __l_
) != 0);
1141 const wchar_t* ctype_byname
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const {
1142 for (; low
!= high
; ++low
, ++vec
) {
1144 *vec
= static_cast<mask
>(ctype
<char>::classic_table()[*low
]);
1147 wint_t ch
= static_cast<wint_t>(*low
);
1148 if (__locale::__iswspace(ch
, __l_
))
1150 # ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1151 if (__locale::__iswprint(ch
, __l_
))
1154 if (__locale::__iswcntrl(ch
, __l_
))
1156 if (__locale::__iswupper(ch
, __l_
))
1158 if (__locale::__iswlower(ch
, __l_
))
1160 # ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1161 if (__locale::__iswalpha(ch
, __l_
))
1164 if (__locale::__iswdigit(ch
, __l_
))
1166 if (__locale::__iswpunct(ch
, __l_
))
1168 # ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1169 if (__locale::__iswxdigit(ch
, __l_
))
1172 if (__locale::__iswblank(ch
, __l_
))
1179 const wchar_t* ctype_byname
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const {
1180 for (; low
!= high
; ++low
) {
1181 # ifdef _LIBCPP_WCTYPE_IS_MASK
1182 if (iswctype_l(*low
, m
, __l_
))
1185 wint_t ch
= static_cast<wint_t>(*low
);
1186 if ((m
& space
) == space
&& __locale::__iswspace(ch
, __l_
))
1188 if ((m
& print
) == print
&& __locale::__iswprint(ch
, __l_
))
1190 if ((m
& cntrl
) == cntrl
&& __locale::__iswcntrl(ch
, __l_
))
1192 if ((m
& upper
) == upper
&& __locale::__iswupper(ch
, __l_
))
1194 if ((m
& lower
) == lower
&& __locale::__iswlower(ch
, __l_
))
1196 if ((m
& alpha
) == alpha
&& __locale::__iswalpha(ch
, __l_
))
1198 if ((m
& digit
) == digit
&& __locale::__iswdigit(ch
, __l_
))
1200 if ((m
& punct
) == punct
&& __locale::__iswpunct(ch
, __l_
))
1202 if ((m
& xdigit
) == xdigit
&& __locale::__iswxdigit(ch
, __l_
))
1204 if ((m
& blank
) == blank
&& __locale::__iswblank(ch
, __l_
))
1211 const wchar_t* ctype_byname
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const {
1212 for (; low
!= high
; ++low
) {
1213 # ifdef _LIBCPP_WCTYPE_IS_MASK
1214 if (!iswctype_l(*low
, m
, __l_
))
1217 wint_t ch
= static_cast<wint_t>(*low
);
1218 if ((m
& space
) == space
&& __locale::__iswspace(ch
, __l_
))
1220 if ((m
& print
) == print
&& __locale::__iswprint(ch
, __l_
))
1222 if ((m
& cntrl
) == cntrl
&& __locale::__iswcntrl(ch
, __l_
))
1224 if ((m
& upper
) == upper
&& __locale::__iswupper(ch
, __l_
))
1226 if ((m
& lower
) == lower
&& __locale::__iswlower(ch
, __l_
))
1228 if ((m
& alpha
) == alpha
&& __locale::__iswalpha(ch
, __l_
))
1230 if ((m
& digit
) == digit
&& __locale::__iswdigit(ch
, __l_
))
1232 if ((m
& punct
) == punct
&& __locale::__iswpunct(ch
, __l_
))
1234 if ((m
& xdigit
) == xdigit
&& __locale::__iswxdigit(ch
, __l_
))
1236 if ((m
& blank
) == blank
&& __locale::__iswblank(ch
, __l_
))
1244 wchar_t ctype_byname
<wchar_t>::do_toupper(char_type c
) const { return __locale::__towupper(c
, __l_
); }
1246 const wchar_t* ctype_byname
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const {
1247 for (; low
!= high
; ++low
)
1248 *low
= __locale::__towupper(*low
, __l_
);
1252 wchar_t ctype_byname
<wchar_t>::do_tolower(char_type c
) const { return __locale::__towlower(c
, __l_
); }
1254 const wchar_t* ctype_byname
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const {
1255 for (; low
!= high
; ++low
)
1256 *low
= __locale::__towlower(*low
, __l_
);
1260 wchar_t ctype_byname
<wchar_t>::do_widen(char c
) const { return __locale::__btowc(c
, __l_
); }
1262 const char* ctype_byname
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const {
1263 for (; low
!= high
; ++low
, ++dest
)
1264 *dest
= __locale::__btowc(*low
, __l_
);
1268 char ctype_byname
<wchar_t>::do_narrow(char_type c
, char dfault
) const {
1269 int r
= __locale::__wctob(c
, __l_
);
1270 return (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1274 ctype_byname
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const {
1275 for (; low
!= high
; ++low
, ++dest
) {
1276 int r
= __locale::__wctob(*low
, __l_
);
1277 *dest
= (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1281 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1283 // template <> class codecvt<char, char, mbstate_t>
1285 constinit
locale::id codecvt
<char, char, mbstate_t>::id
;
1287 codecvt
<char, char, mbstate_t>::~codecvt() {}
1289 codecvt
<char, char, mbstate_t>::result codecvt
<char, char, mbstate_t>::do_out(
1291 const intern_type
* frm
,
1293 const intern_type
*& frm_nxt
,
1296 extern_type
*& to_nxt
) const {
1302 codecvt
<char, char, mbstate_t>::result codecvt
<char, char, mbstate_t>::do_in(
1304 const extern_type
* frm
,
1306 const extern_type
*& frm_nxt
,
1309 intern_type
*& to_nxt
) const {
1315 codecvt
<char, char, mbstate_t>::result
1316 codecvt
<char, char, mbstate_t>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
1321 int codecvt
<char, char, mbstate_t>::do_encoding() const noexcept
{ return 1; }
1323 bool codecvt
<char, char, mbstate_t>::do_always_noconv() const noexcept
{ return true; }
1325 int codecvt
<char, char, mbstate_t>::do_length(
1326 state_type
&, const extern_type
* frm
, const extern_type
* end
, size_t mx
) const {
1327 return static_cast<int>(min
<size_t>(mx
, static_cast<size_t>(end
- frm
)));
1330 int codecvt
<char, char, mbstate_t>::do_max_length() const noexcept
{ return 1; }
1332 // template <> class codecvt<wchar_t, char, mbstate_t>
1334 #if _LIBCPP_HAS_WIDE_CHARACTERS
1335 constinit
locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
1337 codecvt
<wchar_t, char, mbstate_t>::codecvt(size_t refs
) : locale::facet(refs
), __l_(_LIBCPP_GET_C_LOCALE
) {}
1339 codecvt
<wchar_t, char, mbstate_t>::codecvt(const char* nm
, size_t refs
)
1340 : locale::facet(refs
), __l_(__locale::__newlocale(LC_ALL_MASK
, nm
, 0)) {
1342 __throw_runtime_error(
1343 ("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1344 " failed to construct for " +
1349 codecvt
<wchar_t, char, mbstate_t>::~codecvt() {
1350 if (__l_
!= _LIBCPP_GET_C_LOCALE
)
1351 __locale::__freelocale(__l_
);
1354 codecvt
<wchar_t, char, mbstate_t>::result codecvt
<wchar_t, char, mbstate_t>::do_out(
1356 const intern_type
* frm
,
1357 const intern_type
* frm_end
,
1358 const intern_type
*& frm_nxt
,
1360 extern_type
* to_end
,
1361 extern_type
*& to_nxt
) const {
1362 // look for first internal null in frm
1363 const intern_type
* fend
= frm
;
1364 for (; fend
!= frm_end
; ++fend
)
1367 // loop over all null-terminated sequences in frm
1369 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
) {
1370 // save state in case it is needed to recover to_nxt on error
1371 mbstate_t save_state
= st
;
1372 size_t n
= __locale::__wcsnrtombs(
1373 to
, &frm_nxt
, static_cast<size_t>(fend
- frm
), static_cast<size_t>(to_end
- to
), &st
, __l_
);
1374 if (n
== size_t(-1)) {
1375 // need to recover to_nxt
1376 for (to_nxt
= to
; frm
!= frm_nxt
; ++frm
) {
1377 n
= __locale::__wcrtomb(to_nxt
, *frm
, &save_state
, __l_
);
1378 if (n
== size_t(-1))
1388 if (to_nxt
== to_end
)
1390 if (fend
!= frm_end
) // set up next null terminated sequence
1392 // Try to write the terminating null
1393 extern_type tmp
[MB_LEN_MAX
];
1394 n
= __locale::__wcrtomb(tmp
, intern_type(), &st
, __l_
);
1395 if (n
== size_t(-1)) // on error
1397 if (n
> static_cast<size_t>(to_end
- to_nxt
)) // is there room?
1399 for (extern_type
* p
= tmp
; n
; --n
) // write it
1402 // look for next null in frm
1403 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1408 return frm_nxt
== frm_end
? ok
: partial
;
1411 codecvt
<wchar_t, char, mbstate_t>::result codecvt
<wchar_t, char, mbstate_t>::do_in(
1413 const extern_type
* frm
,
1414 const extern_type
* frm_end
,
1415 const extern_type
*& frm_nxt
,
1417 intern_type
* to_end
,
1418 intern_type
*& to_nxt
) const {
1419 // look for first internal null in frm
1420 const extern_type
* fend
= frm
;
1421 for (; fend
!= frm_end
; ++fend
)
1424 // loop over all null-terminated sequences in frm
1426 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
) {
1427 // save state in case it is needed to recover to_nxt on error
1428 mbstate_t save_state
= st
;
1429 size_t n
= __locale::__mbsnrtowcs(
1430 to
, &frm_nxt
, static_cast<size_t>(fend
- frm
), static_cast<size_t>(to_end
- to
), &st
, __l_
);
1431 if (n
== size_t(-1)) {
1432 // need to recover to_nxt
1433 for (to_nxt
= to
; frm
!= frm_nxt
; ++to_nxt
) {
1434 n
= __locale::__mbrtowc(to_nxt
, frm
, static_cast<size_t>(fend
- frm
), &save_state
, __l_
);
1451 return frm_nxt
== frm_end
? ok
: partial
;
1453 if (n
== size_t(-1))
1456 if (to_nxt
== to_end
)
1458 if (fend
!= frm_end
) // set up next null terminated sequence
1460 // Try to write the terminating null
1461 n
= __locale::__mbrtowc(to_nxt
, frm_nxt
, 1, &st
, __l_
);
1462 if (n
!= 0) // on error
1466 // look for next null in frm
1467 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1472 return frm_nxt
== frm_end
? ok
: partial
;
1475 codecvt
<wchar_t, char, mbstate_t>::result codecvt
<wchar_t, char, mbstate_t>::do_unshift(
1476 state_type
& st
, extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const {
1478 extern_type tmp
[MB_LEN_MAX
];
1479 size_t n
= __locale::__wcrtomb(tmp
, intern_type(), &st
, __l_
);
1480 if (n
== size_t(-1) || n
== 0) // on error
1483 if (n
> static_cast<size_t>(to_end
- to_nxt
)) // is there room?
1485 for (extern_type
* p
= tmp
; n
; --n
) // write it
1490 int codecvt
<wchar_t, char, mbstate_t>::do_encoding() const noexcept
{
1491 if (__locale::__mbtowc(nullptr, nullptr, MB_LEN_MAX
, __l_
) != 0)
1494 // stateless encoding
1495 if (__l_
== 0 || __locale::__mb_len_max(__l_
) == 1) // there are no known constant length encodings
1496 return 1; // which take more than 1 char to form a wchar_t
1500 bool codecvt
<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
{ return false; }
1502 int codecvt
<wchar_t, char, mbstate_t>::do_length(
1503 state_type
& st
, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
1505 for (size_t nwchar_t
= 0; nwchar_t
< mx
&& frm
!= frm_end
; ++nwchar_t
) {
1506 size_t n
= __locale::__mbrlen(frm
, static_cast<size_t>(frm_end
- frm
), &st
, __l_
);
1524 int codecvt
<wchar_t, char, mbstate_t>::do_max_length() const noexcept
{
1525 return __l_
== 0 ? 1 : static_cast<int>(__locale::__mb_len_max(__l_
));
1527 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1530 // UTF-32 UTF-16 UTF-8 # of code points
1531 // first second first second third fourth
1532 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1533 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1534 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1535 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1536 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1537 // 00D800 - 00DFFF invalid
1538 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1539 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1540 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1541 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1543 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1544 static codecvt_base::result
utf16_to_utf8(
1545 const uint16_t* frm
,
1546 const uint16_t* frm_end
,
1547 const uint16_t*& frm_nxt
,
1551 unsigned long Maxcode
= 0x10FFFF,
1552 codecvt_mode mode
= codecvt_mode(0)) {
1555 if (mode
& generate_header
) {
1556 if (to_end
- to_nxt
< 3)
1557 return codecvt_base::partial
;
1558 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1559 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1560 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1562 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
1563 uint16_t wc1
= *frm_nxt
;
1565 return codecvt_base::error
;
1567 if (to_end
- to_nxt
< 1)
1568 return codecvt_base::partial
;
1569 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1570 } else if (wc1
< 0x0800) {
1571 if (to_end
- to_nxt
< 2)
1572 return codecvt_base::partial
;
1573 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1574 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1575 } else if (wc1
< 0xD800) {
1576 if (to_end
- to_nxt
< 3)
1577 return codecvt_base::partial
;
1578 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1579 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1580 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1581 } else if (wc1
< 0xDC00) {
1582 if (frm_end
- frm_nxt
< 2)
1583 return codecvt_base::partial
;
1584 uint16_t wc2
= frm_nxt
[1];
1585 if ((wc2
& 0xFC00) != 0xDC00)
1586 return codecvt_base::error
;
1587 if (to_end
- to_nxt
< 4)
1588 return codecvt_base::partial
;
1589 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) + ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1590 return codecvt_base::error
;
1592 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1593 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1594 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1595 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1596 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1597 } else if (wc1
< 0xE000) {
1598 return codecvt_base::error
;
1600 if (to_end
- to_nxt
< 3)
1601 return codecvt_base::partial
;
1602 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1603 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1604 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1607 return codecvt_base::ok
;
1610 static codecvt_base::result
utf16_to_utf8(
1611 const uint32_t* frm
,
1612 const uint32_t* frm_end
,
1613 const uint32_t*& frm_nxt
,
1617 unsigned long Maxcode
= 0x10FFFF,
1618 codecvt_mode mode
= codecvt_mode(0)) {
1621 if (mode
& generate_header
) {
1622 if (to_end
- to_nxt
< 3)
1623 return codecvt_base::partial
;
1624 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1625 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1626 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1628 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
1629 uint16_t wc1
= static_cast<uint16_t>(*frm_nxt
);
1631 return codecvt_base::error
;
1633 if (to_end
- to_nxt
< 1)
1634 return codecvt_base::partial
;
1635 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1636 } else if (wc1
< 0x0800) {
1637 if (to_end
- to_nxt
< 2)
1638 return codecvt_base::partial
;
1639 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1640 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1641 } else if (wc1
< 0xD800) {
1642 if (to_end
- to_nxt
< 3)
1643 return codecvt_base::partial
;
1644 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1645 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1646 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1647 } else if (wc1
< 0xDC00) {
1648 if (frm_end
- frm_nxt
< 2)
1649 return codecvt_base::partial
;
1650 uint16_t wc2
= static_cast<uint16_t>(frm_nxt
[1]);
1651 if ((wc2
& 0xFC00) != 0xDC00)
1652 return codecvt_base::error
;
1653 if (to_end
- to_nxt
< 4)
1654 return codecvt_base::partial
;
1655 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) + ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1656 return codecvt_base::error
;
1658 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1659 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1660 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1661 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1662 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1663 } else if (wc1
< 0xE000) {
1664 return codecvt_base::error
;
1666 if (to_end
- to_nxt
< 3)
1667 return codecvt_base::partial
;
1668 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1669 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1670 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1673 return codecvt_base::ok
;
1676 static codecvt_base::result
utf8_to_utf16(
1678 const uint8_t* frm_end
,
1679 const uint8_t*& frm_nxt
,
1683 unsigned long Maxcode
= 0x10FFFF,
1684 codecvt_mode mode
= codecvt_mode(0)) {
1687 if (mode
& consume_header
) {
1688 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
1691 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
) {
1692 uint8_t c1
= *frm_nxt
;
1694 return codecvt_base::error
;
1696 *to_nxt
= static_cast<uint16_t>(c1
);
1698 } else if (c1
< 0xC2) {
1699 return codecvt_base::error
;
1700 } else if (c1
< 0xE0) {
1701 if (frm_end
- frm_nxt
< 2)
1702 return codecvt_base::partial
;
1703 uint8_t c2
= frm_nxt
[1];
1704 if ((c2
& 0xC0) != 0x80)
1705 return codecvt_base::error
;
1706 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
1708 return codecvt_base::error
;
1711 } else if (c1
< 0xF0) {
1712 if (frm_end
- frm_nxt
< 2)
1713 return codecvt_base::partial
;
1714 uint8_t c2
= frm_nxt
[1];
1717 if ((c2
& 0xE0) != 0xA0)
1718 return codecvt_base::error
;
1721 if ((c2
& 0xE0) != 0x80)
1722 return codecvt_base::error
;
1725 if ((c2
& 0xC0) != 0x80)
1726 return codecvt_base::error
;
1729 if (frm_end
- frm_nxt
< 3)
1730 return codecvt_base::partial
;
1731 uint8_t c3
= frm_nxt
[2];
1732 if ((c3
& 0xC0) != 0x80)
1733 return codecvt_base::error
;
1734 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12) | ((c2
& 0x3F) << 6) | (c3
& 0x3F));
1736 return codecvt_base::error
;
1739 } else if (c1
< 0xF5) {
1740 if (frm_end
- frm_nxt
< 2)
1741 return codecvt_base::partial
;
1742 uint8_t c2
= frm_nxt
[1];
1745 if (!(0x90 <= c2
&& c2
<= 0xBF))
1746 return codecvt_base::error
;
1749 if ((c2
& 0xF0) != 0x80)
1750 return codecvt_base::error
;
1753 if ((c2
& 0xC0) != 0x80)
1754 return codecvt_base::error
;
1757 if (frm_end
- frm_nxt
< 3)
1758 return codecvt_base::partial
;
1759 uint8_t c3
= frm_nxt
[2];
1760 if ((c3
& 0xC0) != 0x80)
1761 return codecvt_base::error
;
1762 if (frm_end
- frm_nxt
< 4)
1763 return codecvt_base::partial
;
1764 uint8_t c4
= frm_nxt
[3];
1765 if ((c4
& 0xC0) != 0x80)
1766 return codecvt_base::error
;
1767 if (to_end
- to_nxt
< 2)
1768 return codecvt_base::partial
;
1769 if ((((c1
& 7UL) << 18) + ((c2
& 0x3FUL
) << 12) + ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
1770 return codecvt_base::error
;
1771 *to_nxt
= static_cast<uint16_t>(
1772 0xD800 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6) | ((c2
& 0x0F) << 2) | ((c3
& 0x30) >> 4));
1773 *++to_nxt
= static_cast<uint16_t>(0xDC00 | ((c3
& 0x0F) << 6) | (c4
& 0x3F));
1776 return codecvt_base::error
;
1779 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
1782 static codecvt_base::result
utf8_to_utf16(
1784 const uint8_t* frm_end
,
1785 const uint8_t*& frm_nxt
,
1789 unsigned long Maxcode
= 0x10FFFF,
1790 codecvt_mode mode
= codecvt_mode(0)) {
1793 if (mode
& consume_header
) {
1794 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
1797 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
) {
1798 uint8_t c1
= *frm_nxt
;
1800 return codecvt_base::error
;
1802 *to_nxt
= static_cast<uint32_t>(c1
);
1804 } else if (c1
< 0xC2) {
1805 return codecvt_base::error
;
1806 } else if (c1
< 0xE0) {
1807 if (frm_end
- frm_nxt
< 2)
1808 return codecvt_base::partial
;
1809 uint8_t c2
= frm_nxt
[1];
1810 if ((c2
& 0xC0) != 0x80)
1811 return codecvt_base::error
;
1812 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
1814 return codecvt_base::error
;
1815 *to_nxt
= static_cast<uint32_t>(t
);
1817 } else if (c1
< 0xF0) {
1818 if (frm_end
- frm_nxt
< 2)
1819 return codecvt_base::partial
;
1820 uint8_t c2
= frm_nxt
[1];
1823 if ((c2
& 0xE0) != 0xA0)
1824 return codecvt_base::error
;
1827 if ((c2
& 0xE0) != 0x80)
1828 return codecvt_base::error
;
1831 if ((c2
& 0xC0) != 0x80)
1832 return codecvt_base::error
;
1835 if (frm_end
- frm_nxt
< 3)
1836 return codecvt_base::partial
;
1837 uint8_t c3
= frm_nxt
[2];
1838 if ((c3
& 0xC0) != 0x80)
1839 return codecvt_base::error
;
1840 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12) | ((c2
& 0x3F) << 6) | (c3
& 0x3F));
1842 return codecvt_base::error
;
1843 *to_nxt
= static_cast<uint32_t>(t
);
1845 } else if (c1
< 0xF5) {
1846 if (frm_end
- frm_nxt
< 2)
1847 return codecvt_base::partial
;
1848 uint8_t c2
= frm_nxt
[1];
1851 if (!(0x90 <= c2
&& c2
<= 0xBF))
1852 return codecvt_base::error
;
1855 if ((c2
& 0xF0) != 0x80)
1856 return codecvt_base::error
;
1859 if ((c2
& 0xC0) != 0x80)
1860 return codecvt_base::error
;
1863 if (frm_end
- frm_nxt
< 3)
1864 return codecvt_base::partial
;
1865 uint8_t c3
= frm_nxt
[2];
1866 if ((c3
& 0xC0) != 0x80)
1867 return codecvt_base::error
;
1868 if (frm_end
- frm_nxt
< 4)
1869 return codecvt_base::partial
;
1870 uint8_t c4
= frm_nxt
[3];
1871 if ((c4
& 0xC0) != 0x80)
1872 return codecvt_base::error
;
1873 if (to_end
- to_nxt
< 2)
1874 return codecvt_base::partial
;
1875 if ((((c1
& 7UL) << 18) + ((c2
& 0x3FUL
) << 12) + ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
1876 return codecvt_base::error
;
1877 *to_nxt
= static_cast<uint32_t>(
1878 0xD800 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6) | ((c2
& 0x0F) << 2) | ((c3
& 0x30) >> 4));
1879 *++to_nxt
= static_cast<uint32_t>(0xDC00 | ((c3
& 0x0F) << 6) | (c4
& 0x3F));
1882 return codecvt_base::error
;
1885 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
1888 static int utf8_to_utf16_length(
1890 const uint8_t* frm_end
,
1892 unsigned long Maxcode
= 0x10FFFF,
1893 codecvt_mode mode
= codecvt_mode(0)) {
1894 const uint8_t* frm_nxt
= frm
;
1895 if (mode
& consume_header
) {
1896 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
1899 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
&& nchar16_t
< mx
; ++nchar16_t
) {
1900 uint8_t c1
= *frm_nxt
;
1905 } else if (c1
< 0xC2) {
1907 } else if (c1
< 0xE0) {
1908 if ((frm_end
- frm_nxt
< 2) || (frm_nxt
[1] & 0xC0) != 0x80)
1910 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (frm_nxt
[1] & 0x3F));
1914 } else if (c1
< 0xF0) {
1915 if (frm_end
- frm_nxt
< 3)
1917 uint8_t c2
= frm_nxt
[1];
1918 uint8_t c3
= frm_nxt
[2];
1921 if ((c2
& 0xE0) != 0xA0)
1922 return static_cast<int>(frm_nxt
- frm
);
1925 if ((c2
& 0xE0) != 0x80)
1926 return static_cast<int>(frm_nxt
- frm
);
1929 if ((c2
& 0xC0) != 0x80)
1930 return static_cast<int>(frm_nxt
- frm
);
1933 if ((c3
& 0xC0) != 0x80)
1935 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
1938 } else if (c1
< 0xF5) {
1939 if (frm_end
- frm_nxt
< 4 || mx
- nchar16_t
< 2)
1941 uint8_t c2
= frm_nxt
[1];
1942 uint8_t c3
= frm_nxt
[2];
1943 uint8_t c4
= frm_nxt
[3];
1946 if (!(0x90 <= c2
&& c2
<= 0xBF))
1947 return static_cast<int>(frm_nxt
- frm
);
1950 if ((c2
& 0xF0) != 0x80)
1951 return static_cast<int>(frm_nxt
- frm
);
1954 if ((c2
& 0xC0) != 0x80)
1955 return static_cast<int>(frm_nxt
- frm
);
1958 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
1960 if ((((c1
& 7UL) << 18) + ((c2
& 0x3FUL
) << 12) + ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
1968 return static_cast<int>(frm_nxt
- frm
);
1971 static codecvt_base::result
ucs4_to_utf8(
1972 const uint32_t* frm
,
1973 const uint32_t* frm_end
,
1974 const uint32_t*& frm_nxt
,
1978 unsigned long Maxcode
= 0x10FFFF,
1979 codecvt_mode mode
= codecvt_mode(0)) {
1982 if (mode
& generate_header
) {
1983 if (to_end
- to_nxt
< 3)
1984 return codecvt_base::partial
;
1985 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1986 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1987 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1989 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
1990 uint32_t wc
= *frm_nxt
;
1991 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
1992 return codecvt_base::error
;
1993 if (wc
< 0x000080) {
1994 if (to_end
- to_nxt
< 1)
1995 return codecvt_base::partial
;
1996 *to_nxt
++ = static_cast<uint8_t>(wc
);
1997 } else if (wc
< 0x000800) {
1998 if (to_end
- to_nxt
< 2)
1999 return codecvt_base::partial
;
2000 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2001 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2002 } else if (wc
< 0x010000) {
2003 if (to_end
- to_nxt
< 3)
2004 return codecvt_base::partial
;
2005 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2006 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2007 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2008 } else // if (wc < 0x110000)
2010 if (to_end
- to_nxt
< 4)
2011 return codecvt_base::partial
;
2012 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (wc
>> 18));
2013 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x03F000) >> 12));
2014 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x000FC0) >> 6));
2015 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x00003F));
2018 return codecvt_base::ok
;
2021 static codecvt_base::result
utf8_to_ucs4(
2023 const uint8_t* frm_end
,
2024 const uint8_t*& frm_nxt
,
2028 unsigned long Maxcode
= 0x10FFFF,
2029 codecvt_mode mode
= codecvt_mode(0)) {
2032 if (mode
& consume_header
) {
2033 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
2036 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
) {
2037 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2040 return codecvt_base::error
;
2041 *to_nxt
= static_cast<uint32_t>(c1
);
2043 } else if (c1
< 0xC2) {
2044 return codecvt_base::error
;
2045 } else if (c1
< 0xE0) {
2046 if (frm_end
- frm_nxt
< 2)
2047 return codecvt_base::partial
;
2048 uint8_t c2
= frm_nxt
[1];
2049 if ((c2
& 0xC0) != 0x80)
2050 return codecvt_base::error
;
2051 uint32_t t
= static_cast<uint32_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2053 return codecvt_base::error
;
2056 } else if (c1
< 0xF0) {
2057 if (frm_end
- frm_nxt
< 2)
2058 return codecvt_base::partial
;
2059 uint8_t c2
= frm_nxt
[1];
2062 if ((c2
& 0xE0) != 0xA0)
2063 return codecvt_base::error
;
2066 if ((c2
& 0xE0) != 0x80)
2067 return codecvt_base::error
;
2070 if ((c2
& 0xC0) != 0x80)
2071 return codecvt_base::error
;
2074 if (frm_end
- frm_nxt
< 3)
2075 return codecvt_base::partial
;
2076 uint8_t c3
= frm_nxt
[2];
2077 if ((c3
& 0xC0) != 0x80)
2078 return codecvt_base::error
;
2079 uint32_t t
= static_cast<uint32_t>(((c1
& 0x0F) << 12) | ((c2
& 0x3F) << 6) | (c3
& 0x3F));
2081 return codecvt_base::error
;
2084 } else if (c1
< 0xF5) {
2085 if (frm_end
- frm_nxt
< 2)
2086 return codecvt_base::partial
;
2087 uint8_t c2
= frm_nxt
[1];
2090 if (!(0x90 <= c2
&& c2
<= 0xBF))
2091 return codecvt_base::error
;
2094 if ((c2
& 0xF0) != 0x80)
2095 return codecvt_base::error
;
2098 if ((c2
& 0xC0) != 0x80)
2099 return codecvt_base::error
;
2102 if (frm_end
- frm_nxt
< 3)
2103 return codecvt_base::partial
;
2104 uint8_t c3
= frm_nxt
[2];
2105 if ((c3
& 0xC0) != 0x80)
2106 return codecvt_base::error
;
2107 if (frm_end
- frm_nxt
< 4)
2108 return codecvt_base::partial
;
2109 uint8_t c4
= frm_nxt
[3];
2110 if ((c4
& 0xC0) != 0x80)
2111 return codecvt_base::error
;
2112 uint32_t t
= static_cast<uint32_t>(((c1
& 0x07) << 18) | ((c2
& 0x3F) << 12) | ((c3
& 0x3F) << 6) | (c4
& 0x3F));
2114 return codecvt_base::error
;
2118 return codecvt_base::error
;
2121 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2124 static int utf8_to_ucs4_length(
2126 const uint8_t* frm_end
,
2128 unsigned long Maxcode
= 0x10FFFF,
2129 codecvt_mode mode
= codecvt_mode(0)) {
2130 const uint8_t* frm_nxt
= frm
;
2131 if (mode
& consume_header
) {
2132 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
2135 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
) {
2136 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2141 } else if (c1
< 0xC2) {
2143 } else if (c1
< 0xE0) {
2144 if ((frm_end
- frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2146 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2149 } else if (c1
< 0xF0) {
2150 if (frm_end
- frm_nxt
< 3)
2152 uint8_t c2
= frm_nxt
[1];
2153 uint8_t c3
= frm_nxt
[2];
2156 if ((c2
& 0xE0) != 0xA0)
2157 return static_cast<int>(frm_nxt
- frm
);
2160 if ((c2
& 0xE0) != 0x80)
2161 return static_cast<int>(frm_nxt
- frm
);
2164 if ((c2
& 0xC0) != 0x80)
2165 return static_cast<int>(frm_nxt
- frm
);
2168 if ((c3
& 0xC0) != 0x80)
2170 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2173 } else if (c1
< 0xF5) {
2174 if (frm_end
- frm_nxt
< 4)
2176 uint8_t c2
= frm_nxt
[1];
2177 uint8_t c3
= frm_nxt
[2];
2178 uint8_t c4
= frm_nxt
[3];
2181 if (!(0x90 <= c2
&& c2
<= 0xBF))
2182 return static_cast<int>(frm_nxt
- frm
);
2185 if ((c2
& 0xF0) != 0x80)
2186 return static_cast<int>(frm_nxt
- frm
);
2189 if ((c2
& 0xC0) != 0x80)
2190 return static_cast<int>(frm_nxt
- frm
);
2193 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2195 if ((((c1
& 0x07u
) << 18) | ((c2
& 0x3Fu
) << 12) | ((c3
& 0x3Fu
) << 6) | (c4
& 0x3Fu
)) > Maxcode
)
2202 return static_cast<int>(frm_nxt
- frm
);
2205 static codecvt_base::result
ucs2_to_utf8(
2206 const uint16_t* frm
,
2207 const uint16_t* frm_end
,
2208 const uint16_t*& frm_nxt
,
2212 unsigned long Maxcode
= 0x10FFFF,
2213 codecvt_mode mode
= codecvt_mode(0)) {
2216 if (mode
& generate_header
) {
2217 if (to_end
- to_nxt
< 3)
2218 return codecvt_base::partial
;
2219 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2220 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2221 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2223 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
2224 uint16_t wc
= *frm_nxt
;
2225 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2226 return codecvt_base::error
;
2228 if (to_end
- to_nxt
< 1)
2229 return codecvt_base::partial
;
2230 *to_nxt
++ = static_cast<uint8_t>(wc
);
2231 } else if (wc
< 0x0800) {
2232 if (to_end
- to_nxt
< 2)
2233 return codecvt_base::partial
;
2234 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2235 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2236 } else // if (wc <= 0xFFFF)
2238 if (to_end
- to_nxt
< 3)
2239 return codecvt_base::partial
;
2240 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2241 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2242 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2245 return codecvt_base::ok
;
2248 static codecvt_base::result
utf8_to_ucs2(
2250 const uint8_t* frm_end
,
2251 const uint8_t*& frm_nxt
,
2255 unsigned long Maxcode
= 0x10FFFF,
2256 codecvt_mode mode
= codecvt_mode(0)) {
2259 if (mode
& consume_header
) {
2260 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
2263 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
) {
2264 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2267 return codecvt_base::error
;
2268 *to_nxt
= static_cast<uint16_t>(c1
);
2270 } else if (c1
< 0xC2) {
2271 return codecvt_base::error
;
2272 } else if (c1
< 0xE0) {
2273 if (frm_end
- frm_nxt
< 2)
2274 return codecvt_base::partial
;
2275 uint8_t c2
= frm_nxt
[1];
2276 if ((c2
& 0xC0) != 0x80)
2277 return codecvt_base::error
;
2278 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2280 return codecvt_base::error
;
2283 } else if (c1
< 0xF0) {
2284 if (frm_end
- frm_nxt
< 2)
2285 return codecvt_base::partial
;
2286 uint8_t c2
= frm_nxt
[1];
2289 if ((c2
& 0xE0) != 0xA0)
2290 return codecvt_base::error
;
2293 if ((c2
& 0xE0) != 0x80)
2294 return codecvt_base::error
;
2297 if ((c2
& 0xC0) != 0x80)
2298 return codecvt_base::error
;
2301 if (frm_end
- frm_nxt
< 3)
2302 return codecvt_base::partial
;
2303 uint8_t c3
= frm_nxt
[2];
2304 if ((c3
& 0xC0) != 0x80)
2305 return codecvt_base::error
;
2306 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12) | ((c2
& 0x3F) << 6) | (c3
& 0x3F));
2308 return codecvt_base::error
;
2312 return codecvt_base::error
;
2315 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2318 static int utf8_to_ucs2_length(
2320 const uint8_t* frm_end
,
2322 unsigned long Maxcode
= 0x10FFFF,
2323 codecvt_mode mode
= codecvt_mode(0)) {
2324 const uint8_t* frm_nxt
= frm
;
2325 if (mode
& consume_header
) {
2326 if (frm_end
- frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB && frm_nxt
[2] == 0xBF)
2329 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
) {
2330 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2335 } else if (c1
< 0xC2) {
2337 } else if (c1
< 0xE0) {
2338 if ((frm_end
- frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2340 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2343 } else if (c1
< 0xF0) {
2344 if (frm_end
- frm_nxt
< 3)
2346 uint8_t c2
= frm_nxt
[1];
2347 uint8_t c3
= frm_nxt
[2];
2350 if ((c2
& 0xE0) != 0xA0)
2351 return static_cast<int>(frm_nxt
- frm
);
2354 if ((c2
& 0xE0) != 0x80)
2355 return static_cast<int>(frm_nxt
- frm
);
2358 if ((c2
& 0xC0) != 0x80)
2359 return static_cast<int>(frm_nxt
- frm
);
2362 if ((c3
& 0xC0) != 0x80)
2364 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2371 return static_cast<int>(frm_nxt
- frm
);
2374 static codecvt_base::result
ucs4_to_utf16be(
2375 const uint32_t* frm
,
2376 const uint32_t* frm_end
,
2377 const uint32_t*& frm_nxt
,
2381 unsigned long Maxcode
= 0x10FFFF,
2382 codecvt_mode mode
= codecvt_mode(0)) {
2385 if (mode
& generate_header
) {
2386 if (to_end
- to_nxt
< 2)
2387 return codecvt_base::partial
;
2388 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2389 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2391 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
2392 uint32_t wc
= *frm_nxt
;
2393 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2394 return codecvt_base::error
;
2395 if (wc
< 0x010000) {
2396 if (to_end
- to_nxt
< 2)
2397 return codecvt_base::partial
;
2398 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2399 *to_nxt
++ = static_cast<uint8_t>(wc
);
2401 if (to_end
- to_nxt
< 4)
2402 return codecvt_base::partial
;
2403 uint16_t t
= static_cast<uint16_t>(0xD800 | ((((wc
& 0x1F0000) >> 16) - 1) << 6) | ((wc
& 0x00FC00) >> 10));
2404 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2405 *to_nxt
++ = static_cast<uint8_t>(t
);
2406 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2407 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2408 *to_nxt
++ = static_cast<uint8_t>(t
);
2411 return codecvt_base::ok
;
2414 static codecvt_base::result
utf16be_to_ucs4(
2416 const uint8_t* frm_end
,
2417 const uint8_t*& frm_nxt
,
2421 unsigned long Maxcode
= 0x10FFFF,
2422 codecvt_mode mode
= codecvt_mode(0)) {
2425 if (mode
& consume_header
) {
2426 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2429 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
) {
2430 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2431 if ((c1
& 0xFC00) == 0xDC00)
2432 return codecvt_base::error
;
2433 if ((c1
& 0xFC00) != 0xD800) {
2435 return codecvt_base::error
;
2436 *to_nxt
= static_cast<uint32_t>(c1
);
2439 if (frm_end
- frm_nxt
< 4)
2440 return codecvt_base::partial
;
2441 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2442 if ((c2
& 0xFC00) != 0xDC00)
2443 return codecvt_base::error
;
2444 uint32_t t
= static_cast<uint32_t>(((((c1
& 0x03C0) >> 6) + 1) << 16) | ((c1
& 0x003F) << 10) | (c2
& 0x03FF));
2446 return codecvt_base::error
;
2451 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2454 static int utf16be_to_ucs4_length(
2456 const uint8_t* frm_end
,
2458 unsigned long Maxcode
= 0x10FFFF,
2459 codecvt_mode mode
= codecvt_mode(0)) {
2460 const uint8_t* frm_nxt
= frm
;
2461 if (mode
& consume_header
) {
2462 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2465 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
) {
2466 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2467 if ((c1
& 0xFC00) == 0xDC00)
2469 if ((c1
& 0xFC00) != 0xD800) {
2474 if (frm_end
- frm_nxt
< 4)
2476 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2477 if ((c2
& 0xFC00) != 0xDC00)
2479 uint32_t t
= static_cast<uint32_t>(((((c1
& 0x03C0) >> 6) + 1) << 16) | ((c1
& 0x003F) << 10) | (c2
& 0x03FF));
2485 return static_cast<int>(frm_nxt
- frm
);
2488 static codecvt_base::result
ucs4_to_utf16le(
2489 const uint32_t* frm
,
2490 const uint32_t* frm_end
,
2491 const uint32_t*& frm_nxt
,
2495 unsigned long Maxcode
= 0x10FFFF,
2496 codecvt_mode mode
= codecvt_mode(0)) {
2499 if (mode
& generate_header
) {
2500 if (to_end
- to_nxt
< 2)
2501 return codecvt_base::partial
;
2502 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2503 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2505 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
2506 uint32_t wc
= *frm_nxt
;
2507 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2508 return codecvt_base::error
;
2509 if (wc
< 0x010000) {
2510 if (to_end
- to_nxt
< 2)
2511 return codecvt_base::partial
;
2512 *to_nxt
++ = static_cast<uint8_t>(wc
);
2513 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2515 if (to_end
- to_nxt
< 4)
2516 return codecvt_base::partial
;
2517 uint16_t t
= static_cast<uint16_t>(0xD800 | ((((wc
& 0x1F0000) >> 16) - 1) << 6) | ((wc
& 0x00FC00) >> 10));
2518 *to_nxt
++ = static_cast<uint8_t>(t
);
2519 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2520 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2521 *to_nxt
++ = static_cast<uint8_t>(t
);
2522 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2525 return codecvt_base::ok
;
2528 static codecvt_base::result
utf16le_to_ucs4(
2530 const uint8_t* frm_end
,
2531 const uint8_t*& frm_nxt
,
2535 unsigned long Maxcode
= 0x10FFFF,
2536 codecvt_mode mode
= codecvt_mode(0)) {
2539 if (mode
& consume_header
) {
2540 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2543 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
) {
2544 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2545 if ((c1
& 0xFC00) == 0xDC00)
2546 return codecvt_base::error
;
2547 if ((c1
& 0xFC00) != 0xD800) {
2549 return codecvt_base::error
;
2550 *to_nxt
= static_cast<uint32_t>(c1
);
2553 if (frm_end
- frm_nxt
< 4)
2554 return codecvt_base::partial
;
2555 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2556 if ((c2
& 0xFC00) != 0xDC00)
2557 return codecvt_base::error
;
2558 uint32_t t
= static_cast<uint32_t>(((((c1
& 0x03C0) >> 6) + 1) << 16) | ((c1
& 0x003F) << 10) | (c2
& 0x03FF));
2560 return codecvt_base::error
;
2565 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2568 static int utf16le_to_ucs4_length(
2570 const uint8_t* frm_end
,
2572 unsigned long Maxcode
= 0x10FFFF,
2573 codecvt_mode mode
= codecvt_mode(0)) {
2574 const uint8_t* frm_nxt
= frm
;
2575 if (mode
& consume_header
) {
2576 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2579 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
) {
2580 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2581 if ((c1
& 0xFC00) == 0xDC00)
2583 if ((c1
& 0xFC00) != 0xD800) {
2588 if (frm_end
- frm_nxt
< 4)
2590 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2591 if ((c2
& 0xFC00) != 0xDC00)
2593 uint32_t t
= static_cast<uint32_t>(((((c1
& 0x03C0) >> 6) + 1) << 16) | ((c1
& 0x003F) << 10) | (c2
& 0x03FF));
2599 return static_cast<int>(frm_nxt
- frm
);
2602 static codecvt_base::result
ucs2_to_utf16be(
2603 const uint16_t* frm
,
2604 const uint16_t* frm_end
,
2605 const uint16_t*& frm_nxt
,
2609 unsigned long Maxcode
= 0x10FFFF,
2610 codecvt_mode mode
= codecvt_mode(0)) {
2613 if (mode
& generate_header
) {
2614 if (to_end
- to_nxt
< 2)
2615 return codecvt_base::partial
;
2616 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2617 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2619 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
2620 uint16_t wc
= *frm_nxt
;
2621 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2622 return codecvt_base::error
;
2623 if (to_end
- to_nxt
< 2)
2624 return codecvt_base::partial
;
2625 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2626 *to_nxt
++ = static_cast<uint8_t>(wc
);
2628 return codecvt_base::ok
;
2631 static codecvt_base::result
utf16be_to_ucs2(
2633 const uint8_t* frm_end
,
2634 const uint8_t*& frm_nxt
,
2638 unsigned long Maxcode
= 0x10FFFF,
2639 codecvt_mode mode
= codecvt_mode(0)) {
2642 if (mode
& consume_header
) {
2643 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2646 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
) {
2647 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2648 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
2649 return codecvt_base::error
;
2653 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2656 static int utf16be_to_ucs2_length(
2658 const uint8_t* frm_end
,
2660 unsigned long Maxcode
= 0x10FFFF,
2661 codecvt_mode mode
= codecvt_mode(0)) {
2662 const uint8_t* frm_nxt
= frm
;
2663 if (mode
& consume_header
) {
2664 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2667 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
) {
2668 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2669 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
2673 return static_cast<int>(frm_nxt
- frm
);
2676 static codecvt_base::result
ucs2_to_utf16le(
2677 const uint16_t* frm
,
2678 const uint16_t* frm_end
,
2679 const uint16_t*& frm_nxt
,
2683 unsigned long Maxcode
= 0x10FFFF,
2684 codecvt_mode mode
= codecvt_mode(0)) {
2687 if (mode
& generate_header
) {
2688 if (to_end
- to_nxt
< 2)
2689 return codecvt_base::partial
;
2690 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2691 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2693 for (; frm_nxt
< frm_end
; ++frm_nxt
) {
2694 uint16_t wc
= *frm_nxt
;
2695 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2696 return codecvt_base::error
;
2697 if (to_end
- to_nxt
< 2)
2698 return codecvt_base::partial
;
2699 *to_nxt
++ = static_cast<uint8_t>(wc
);
2700 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2702 return codecvt_base::ok
;
2705 static codecvt_base::result
utf16le_to_ucs2(
2707 const uint8_t* frm_end
,
2708 const uint8_t*& frm_nxt
,
2712 unsigned long Maxcode
= 0x10FFFF,
2713 codecvt_mode mode
= codecvt_mode(0)) {
2716 if (mode
& consume_header
) {
2717 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2720 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
) {
2721 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2722 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
2723 return codecvt_base::error
;
2727 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2730 static int utf16le_to_ucs2_length(
2732 const uint8_t* frm_end
,
2734 unsigned long Maxcode
= 0x10FFFF,
2735 codecvt_mode mode
= codecvt_mode(0)) {
2736 const uint8_t* frm_nxt
= frm
;
2738 if (mode
& consume_header
) {
2739 if (frm_end
- frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2742 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
) {
2743 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2744 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
2748 return static_cast<int>(frm_nxt
- frm
);
2751 _LIBCPP_SUPPRESS_DEPRECATED_POP
2753 // template <> class codecvt<char16_t, char, mbstate_t>
2755 constinit
locale::id codecvt
<char16_t
, char, mbstate_t>::id
;
2757 codecvt
<char16_t
, char, mbstate_t>::~codecvt() {}
2759 codecvt
<char16_t
, char, mbstate_t>::result codecvt
<char16_t
, char, mbstate_t>::do_out(
2761 const intern_type
* frm
,
2762 const intern_type
* frm_end
,
2763 const intern_type
*& frm_nxt
,
2765 extern_type
* to_end
,
2766 extern_type
*& to_nxt
) const {
2767 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
2768 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
2769 const uint16_t* _frm_nxt
= _frm
;
2770 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
2771 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
2772 uint8_t* _to_nxt
= _to
;
2773 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2774 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2775 to_nxt
= to
+ (_to_nxt
- _to
);
2779 codecvt
<char16_t
, char, mbstate_t>::result codecvt
<char16_t
, char, mbstate_t>::do_in(
2781 const extern_type
* frm
,
2782 const extern_type
* frm_end
,
2783 const extern_type
*& frm_nxt
,
2785 intern_type
* to_end
,
2786 intern_type
*& to_nxt
) const {
2787 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2788 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2789 const uint8_t* _frm_nxt
= _frm
;
2790 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
2791 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
2792 uint16_t* _to_nxt
= _to
;
2793 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2794 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2795 to_nxt
= to
+ (_to_nxt
- _to
);
2799 codecvt
<char16_t
, char, mbstate_t>::result
2800 codecvt
<char16_t
, char, mbstate_t>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
2805 int codecvt
<char16_t
, char, mbstate_t>::do_encoding() const noexcept
{ return 0; }
2807 bool codecvt
<char16_t
, char, mbstate_t>::do_always_noconv() const noexcept
{ return false; }
2809 int codecvt
<char16_t
, char, mbstate_t>::do_length(
2810 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
2811 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2812 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2813 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
2816 int codecvt
<char16_t
, char, mbstate_t>::do_max_length() const noexcept
{ return 4; }
2818 #if _LIBCPP_HAS_CHAR8_T
2820 // template <> class codecvt<char16_t, char8_t, mbstate_t>
2822 constinit
locale::id codecvt
<char16_t
, char8_t
, mbstate_t>::id
;
2824 codecvt
<char16_t
, char8_t
, mbstate_t>::~codecvt() {}
2826 codecvt
<char16_t
, char8_t
, mbstate_t>::result codecvt
<char16_t
, char8_t
, mbstate_t>::do_out(
2828 const intern_type
* frm
,
2829 const intern_type
* frm_end
,
2830 const intern_type
*& frm_nxt
,
2832 extern_type
* to_end
,
2833 extern_type
*& to_nxt
) const {
2834 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
2835 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
2836 const uint16_t* _frm_nxt
= _frm
;
2837 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
2838 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
2839 uint8_t* _to_nxt
= _to
;
2840 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2841 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2842 to_nxt
= to
+ (_to_nxt
- _to
);
2846 codecvt
<char16_t
, char8_t
, mbstate_t>::result codecvt
<char16_t
, char8_t
, mbstate_t>::do_in(
2848 const extern_type
* frm
,
2849 const extern_type
* frm_end
,
2850 const extern_type
*& frm_nxt
,
2852 intern_type
* to_end
,
2853 intern_type
*& to_nxt
) const {
2854 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2855 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2856 const uint8_t* _frm_nxt
= _frm
;
2857 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
2858 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
2859 uint16_t* _to_nxt
= _to
;
2860 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2861 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2862 to_nxt
= to
+ (_to_nxt
- _to
);
2866 codecvt
<char16_t
, char8_t
, mbstate_t>::result codecvt
<char16_t
, char8_t
, mbstate_t>::do_unshift(
2867 state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
2872 int codecvt
<char16_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
{ return 0; }
2874 bool codecvt
<char16_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
{ return false; }
2876 int codecvt
<char16_t
, char8_t
, mbstate_t>::do_length(
2877 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
2878 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2879 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2880 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
2883 int codecvt
<char16_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
{ return 4; }
2887 // template <> class codecvt<char32_t, char, mbstate_t>
2889 constinit
locale::id codecvt
<char32_t
, char, mbstate_t>::id
;
2891 codecvt
<char32_t
, char, mbstate_t>::~codecvt() {}
2893 codecvt
<char32_t
, char, mbstate_t>::result codecvt
<char32_t
, char, mbstate_t>::do_out(
2895 const intern_type
* frm
,
2896 const intern_type
* frm_end
,
2897 const intern_type
*& frm_nxt
,
2899 extern_type
* to_end
,
2900 extern_type
*& to_nxt
) const {
2901 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
2902 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
2903 const uint32_t* _frm_nxt
= _frm
;
2904 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
2905 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
2906 uint8_t* _to_nxt
= _to
;
2907 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2908 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2909 to_nxt
= to
+ (_to_nxt
- _to
);
2913 codecvt
<char32_t
, char, mbstate_t>::result codecvt
<char32_t
, char, mbstate_t>::do_in(
2915 const extern_type
* frm
,
2916 const extern_type
* frm_end
,
2917 const extern_type
*& frm_nxt
,
2919 intern_type
* to_end
,
2920 intern_type
*& to_nxt
) const {
2921 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2922 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2923 const uint8_t* _frm_nxt
= _frm
;
2924 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
2925 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
2926 uint32_t* _to_nxt
= _to
;
2927 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2928 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2929 to_nxt
= to
+ (_to_nxt
- _to
);
2933 codecvt
<char32_t
, char, mbstate_t>::result
2934 codecvt
<char32_t
, char, mbstate_t>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
2939 int codecvt
<char32_t
, char, mbstate_t>::do_encoding() const noexcept
{ return 0; }
2941 bool codecvt
<char32_t
, char, mbstate_t>::do_always_noconv() const noexcept
{ return false; }
2943 int codecvt
<char32_t
, char, mbstate_t>::do_length(
2944 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
2945 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2946 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2947 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
2950 int codecvt
<char32_t
, char, mbstate_t>::do_max_length() const noexcept
{ return 4; }
2952 #if _LIBCPP_HAS_CHAR8_T
2954 // template <> class codecvt<char32_t, char8_t, mbstate_t>
2956 constinit
locale::id codecvt
<char32_t
, char8_t
, mbstate_t>::id
;
2958 codecvt
<char32_t
, char8_t
, mbstate_t>::~codecvt() {}
2960 codecvt
<char32_t
, char8_t
, mbstate_t>::result codecvt
<char32_t
, char8_t
, mbstate_t>::do_out(
2962 const intern_type
* frm
,
2963 const intern_type
* frm_end
,
2964 const intern_type
*& frm_nxt
,
2966 extern_type
* to_end
,
2967 extern_type
*& to_nxt
) const {
2968 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
2969 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
2970 const uint32_t* _frm_nxt
= _frm
;
2971 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
2972 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
2973 uint8_t* _to_nxt
= _to
;
2974 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2975 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2976 to_nxt
= to
+ (_to_nxt
- _to
);
2980 codecvt
<char32_t
, char8_t
, mbstate_t>::result codecvt
<char32_t
, char8_t
, mbstate_t>::do_in(
2982 const extern_type
* frm
,
2983 const extern_type
* frm_end
,
2984 const extern_type
*& frm_nxt
,
2986 intern_type
* to_end
,
2987 intern_type
*& to_nxt
) const {
2988 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
2989 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
2990 const uint8_t* _frm_nxt
= _frm
;
2991 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
2992 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
2993 uint32_t* _to_nxt
= _to
;
2994 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
2995 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
2996 to_nxt
= to
+ (_to_nxt
- _to
);
3000 codecvt
<char32_t
, char8_t
, mbstate_t>::result codecvt
<char32_t
, char8_t
, mbstate_t>::do_unshift(
3001 state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3006 int codecvt
<char32_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
{ return 0; }
3008 bool codecvt
<char32_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
{ return false; }
3010 int codecvt
<char32_t
, char8_t
, mbstate_t>::do_length(
3011 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3012 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3013 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3014 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3017 int codecvt
<char32_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
{ return 4; }
3021 // __codecvt_utf8<wchar_t>
3023 #if _LIBCPP_HAS_WIDE_CHARACTERS
3024 __codecvt_utf8
<wchar_t>::result __codecvt_utf8
<wchar_t>::do_out(
3026 const intern_type
* frm
,
3027 const intern_type
* frm_end
,
3028 const intern_type
*& frm_nxt
,
3030 extern_type
* to_end
,
3031 extern_type
*& to_nxt
) const {
3032 # if defined(_LIBCPP_SHORT_WCHAR)
3033 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3034 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3035 const uint16_t* _frm_nxt
= _frm
;
3037 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3038 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3039 const uint32_t* _frm_nxt
= _frm
;
3041 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3042 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3043 uint8_t* _to_nxt
= _to
;
3044 # if defined(_LIBCPP_SHORT_WCHAR)
3045 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3047 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3049 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3050 to_nxt
= to
+ (_to_nxt
- _to
);
3054 __codecvt_utf8
<wchar_t>::result __codecvt_utf8
<wchar_t>::do_in(
3056 const extern_type
* frm
,
3057 const extern_type
* frm_end
,
3058 const extern_type
*& frm_nxt
,
3060 intern_type
* to_end
,
3061 intern_type
*& to_nxt
) const {
3062 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3063 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3064 const uint8_t* _frm_nxt
= _frm
;
3065 # if defined(_LIBCPP_SHORT_WCHAR)
3066 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3067 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3068 uint16_t* _to_nxt
= _to
;
3069 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3071 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3072 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3073 uint32_t* _to_nxt
= _to
;
3074 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3076 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3077 to_nxt
= to
+ (_to_nxt
- _to
);
3081 __codecvt_utf8
<wchar_t>::result
3082 __codecvt_utf8
<wchar_t>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3087 int __codecvt_utf8
<wchar_t>::do_encoding() const noexcept
{ return 0; }
3089 bool __codecvt_utf8
<wchar_t>::do_always_noconv() const noexcept
{ return false; }
3091 int __codecvt_utf8
<wchar_t>::do_length(
3092 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3093 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3094 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3095 # if defined(_LIBCPP_SHORT_WCHAR)
3096 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3098 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3102 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3103 int __codecvt_utf8
<wchar_t>::do_max_length() const noexcept
{
3104 # if defined(_LIBCPP_SHORT_WCHAR)
3105 if (__mode_
& consume_header
)
3109 if (__mode_
& consume_header
)
3114 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3116 // __codecvt_utf8<char16_t>
3118 __codecvt_utf8
<char16_t
>::result __codecvt_utf8
<char16_t
>::do_out(
3120 const intern_type
* frm
,
3121 const intern_type
* frm_end
,
3122 const intern_type
*& frm_nxt
,
3124 extern_type
* to_end
,
3125 extern_type
*& to_nxt
) const {
3126 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3127 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3128 const uint16_t* _frm_nxt
= _frm
;
3129 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3130 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3131 uint8_t* _to_nxt
= _to
;
3132 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3133 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3134 to_nxt
= to
+ (_to_nxt
- _to
);
3138 __codecvt_utf8
<char16_t
>::result __codecvt_utf8
<char16_t
>::do_in(
3140 const extern_type
* frm
,
3141 const extern_type
* frm_end
,
3142 const extern_type
*& frm_nxt
,
3144 intern_type
* to_end
,
3145 intern_type
*& to_nxt
) const {
3146 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3147 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3148 const uint8_t* _frm_nxt
= _frm
;
3149 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3150 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3151 uint16_t* _to_nxt
= _to
;
3152 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3153 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3154 to_nxt
= to
+ (_to_nxt
- _to
);
3158 __codecvt_utf8
<char16_t
>::result
3159 __codecvt_utf8
<char16_t
>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3164 int __codecvt_utf8
<char16_t
>::do_encoding() const noexcept
{ return 0; }
3166 bool __codecvt_utf8
<char16_t
>::do_always_noconv() const noexcept
{ return false; }
3168 int __codecvt_utf8
<char16_t
>::do_length(
3169 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3170 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3171 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3172 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3175 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3176 int __codecvt_utf8
<char16_t
>::do_max_length() const noexcept
{
3177 if (__mode_
& consume_header
)
3181 _LIBCPP_SUPPRESS_DEPRECATED_POP
3183 // __codecvt_utf8<char32_t>
3185 __codecvt_utf8
<char32_t
>::result __codecvt_utf8
<char32_t
>::do_out(
3187 const intern_type
* frm
,
3188 const intern_type
* frm_end
,
3189 const intern_type
*& frm_nxt
,
3191 extern_type
* to_end
,
3192 extern_type
*& to_nxt
) const {
3193 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3194 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3195 const uint32_t* _frm_nxt
= _frm
;
3196 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3197 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3198 uint8_t* _to_nxt
= _to
;
3199 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3200 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3201 to_nxt
= to
+ (_to_nxt
- _to
);
3205 __codecvt_utf8
<char32_t
>::result __codecvt_utf8
<char32_t
>::do_in(
3207 const extern_type
* frm
,
3208 const extern_type
* frm_end
,
3209 const extern_type
*& frm_nxt
,
3211 intern_type
* to_end
,
3212 intern_type
*& to_nxt
) const {
3213 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3214 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3215 const uint8_t* _frm_nxt
= _frm
;
3216 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3217 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3218 uint32_t* _to_nxt
= _to
;
3219 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3220 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3221 to_nxt
= to
+ (_to_nxt
- _to
);
3225 __codecvt_utf8
<char32_t
>::result
3226 __codecvt_utf8
<char32_t
>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3231 int __codecvt_utf8
<char32_t
>::do_encoding() const noexcept
{ return 0; }
3233 bool __codecvt_utf8
<char32_t
>::do_always_noconv() const noexcept
{ return false; }
3235 int __codecvt_utf8
<char32_t
>::do_length(
3236 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3237 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3238 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3239 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3242 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3243 int __codecvt_utf8
<char32_t
>::do_max_length() const noexcept
{
3244 if (__mode_
& consume_header
)
3248 _LIBCPP_SUPPRESS_DEPRECATED_POP
3250 // __codecvt_utf16<wchar_t, false>
3252 #if _LIBCPP_HAS_WIDE_CHARACTERS
3253 __codecvt_utf16
<wchar_t, false>::result __codecvt_utf16
<wchar_t, false>::do_out(
3255 const intern_type
* frm
,
3256 const intern_type
* frm_end
,
3257 const intern_type
*& frm_nxt
,
3259 extern_type
* to_end
,
3260 extern_type
*& to_nxt
) const {
3261 # if defined(_LIBCPP_SHORT_WCHAR)
3262 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3263 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3264 const uint16_t* _frm_nxt
= _frm
;
3266 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3267 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3268 const uint32_t* _frm_nxt
= _frm
;
3270 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3271 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3272 uint8_t* _to_nxt
= _to
;
3273 # if defined(_LIBCPP_SHORT_WCHAR)
3274 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3276 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3278 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3279 to_nxt
= to
+ (_to_nxt
- _to
);
3283 __codecvt_utf16
<wchar_t, false>::result __codecvt_utf16
<wchar_t, false>::do_in(
3285 const extern_type
* frm
,
3286 const extern_type
* frm_end
,
3287 const extern_type
*& frm_nxt
,
3289 intern_type
* to_end
,
3290 intern_type
*& to_nxt
) const {
3291 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3292 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3293 const uint8_t* _frm_nxt
= _frm
;
3294 # if defined(_LIBCPP_SHORT_WCHAR)
3295 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3296 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3297 uint16_t* _to_nxt
= _to
;
3298 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3300 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3301 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3302 uint32_t* _to_nxt
= _to
;
3303 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3305 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3306 to_nxt
= to
+ (_to_nxt
- _to
);
3310 __codecvt_utf16
<wchar_t, false>::result
3311 __codecvt_utf16
<wchar_t, false>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3316 int __codecvt_utf16
<wchar_t, false>::do_encoding() const noexcept
{ return 0; }
3318 bool __codecvt_utf16
<wchar_t, false>::do_always_noconv() const noexcept
{ return false; }
3320 int __codecvt_utf16
<wchar_t, false>::do_length(
3321 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3322 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3323 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3324 # if defined(_LIBCPP_SHORT_WCHAR)
3325 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3327 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3331 int __codecvt_utf16
<wchar_t, false>::do_max_length() const noexcept
{
3332 # if defined(_LIBCPP_SHORT_WCHAR)
3333 if (__mode_
& consume_header
)
3337 if (__mode_
& consume_header
)
3343 // __codecvt_utf16<wchar_t, true>
3345 __codecvt_utf16
<wchar_t, true>::result __codecvt_utf16
<wchar_t, true>::do_out(
3347 const intern_type
* frm
,
3348 const intern_type
* frm_end
,
3349 const intern_type
*& frm_nxt
,
3351 extern_type
* to_end
,
3352 extern_type
*& to_nxt
) const {
3353 # if defined(_LIBCPP_SHORT_WCHAR)
3354 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3355 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3356 const uint16_t* _frm_nxt
= _frm
;
3358 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3359 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3360 const uint32_t* _frm_nxt
= _frm
;
3362 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3363 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3364 uint8_t* _to_nxt
= _to
;
3365 # if defined(_LIBCPP_SHORT_WCHAR)
3366 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3368 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3370 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3371 to_nxt
= to
+ (_to_nxt
- _to
);
3375 __codecvt_utf16
<wchar_t, true>::result __codecvt_utf16
<wchar_t, true>::do_in(
3377 const extern_type
* frm
,
3378 const extern_type
* frm_end
,
3379 const extern_type
*& frm_nxt
,
3381 intern_type
* to_end
,
3382 intern_type
*& to_nxt
) const {
3383 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3384 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3385 const uint8_t* _frm_nxt
= _frm
;
3386 # if defined(_LIBCPP_SHORT_WCHAR)
3387 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3388 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3389 uint16_t* _to_nxt
= _to
;
3390 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3392 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3393 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3394 uint32_t* _to_nxt
= _to
;
3395 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3397 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3398 to_nxt
= to
+ (_to_nxt
- _to
);
3402 __codecvt_utf16
<wchar_t, true>::result
3403 __codecvt_utf16
<wchar_t, true>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3408 int __codecvt_utf16
<wchar_t, true>::do_encoding() const noexcept
{ return 0; }
3410 bool __codecvt_utf16
<wchar_t, true>::do_always_noconv() const noexcept
{ return false; }
3412 int __codecvt_utf16
<wchar_t, true>::do_length(
3413 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3414 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3415 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3416 # if defined(_LIBCPP_SHORT_WCHAR)
3417 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3419 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3423 int __codecvt_utf16
<wchar_t, true>::do_max_length() const noexcept
{
3424 # if defined(_LIBCPP_SHORT_WCHAR)
3425 if (__mode_
& consume_header
)
3429 if (__mode_
& consume_header
)
3434 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3436 // __codecvt_utf16<char16_t, false>
3438 __codecvt_utf16
<char16_t
, false>::result __codecvt_utf16
<char16_t
, false>::do_out(
3440 const intern_type
* frm
,
3441 const intern_type
* frm_end
,
3442 const intern_type
*& frm_nxt
,
3444 extern_type
* to_end
,
3445 extern_type
*& to_nxt
) const {
3446 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3447 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3448 const uint16_t* _frm_nxt
= _frm
;
3449 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3450 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3451 uint8_t* _to_nxt
= _to
;
3452 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3453 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3454 to_nxt
= to
+ (_to_nxt
- _to
);
3458 __codecvt_utf16
<char16_t
, false>::result __codecvt_utf16
<char16_t
, false>::do_in(
3460 const extern_type
* frm
,
3461 const extern_type
* frm_end
,
3462 const extern_type
*& frm_nxt
,
3464 intern_type
* to_end
,
3465 intern_type
*& to_nxt
) const {
3466 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3467 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3468 const uint8_t* _frm_nxt
= _frm
;
3469 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3470 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3471 uint16_t* _to_nxt
= _to
;
3472 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3473 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3474 to_nxt
= to
+ (_to_nxt
- _to
);
3478 __codecvt_utf16
<char16_t
, false>::result
3479 __codecvt_utf16
<char16_t
, false>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3484 int __codecvt_utf16
<char16_t
, false>::do_encoding() const noexcept
{ return 0; }
3486 bool __codecvt_utf16
<char16_t
, false>::do_always_noconv() const noexcept
{ return false; }
3488 int __codecvt_utf16
<char16_t
, false>::do_length(
3489 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3490 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3491 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3492 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3495 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3496 int __codecvt_utf16
<char16_t
, false>::do_max_length() const noexcept
{
3497 if (__mode_
& consume_header
)
3501 _LIBCPP_SUPPRESS_DEPRECATED_POP
3503 // __codecvt_utf16<char16_t, true>
3505 __codecvt_utf16
<char16_t
, true>::result __codecvt_utf16
<char16_t
, true>::do_out(
3507 const intern_type
* frm
,
3508 const intern_type
* frm_end
,
3509 const intern_type
*& frm_nxt
,
3511 extern_type
* to_end
,
3512 extern_type
*& to_nxt
) const {
3513 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3514 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3515 const uint16_t* _frm_nxt
= _frm
;
3516 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3517 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3518 uint8_t* _to_nxt
= _to
;
3519 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3520 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3521 to_nxt
= to
+ (_to_nxt
- _to
);
3525 __codecvt_utf16
<char16_t
, true>::result __codecvt_utf16
<char16_t
, true>::do_in(
3527 const extern_type
* frm
,
3528 const extern_type
* frm_end
,
3529 const extern_type
*& frm_nxt
,
3531 intern_type
* to_end
,
3532 intern_type
*& to_nxt
) const {
3533 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3534 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3535 const uint8_t* _frm_nxt
= _frm
;
3536 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3537 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3538 uint16_t* _to_nxt
= _to
;
3539 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3540 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3541 to_nxt
= to
+ (_to_nxt
- _to
);
3545 __codecvt_utf16
<char16_t
, true>::result
3546 __codecvt_utf16
<char16_t
, true>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3551 int __codecvt_utf16
<char16_t
, true>::do_encoding() const noexcept
{ return 0; }
3553 bool __codecvt_utf16
<char16_t
, true>::do_always_noconv() const noexcept
{ return false; }
3555 int __codecvt_utf16
<char16_t
, true>::do_length(
3556 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3557 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3558 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3559 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3562 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3563 int __codecvt_utf16
<char16_t
, true>::do_max_length() const noexcept
{
3564 if (__mode_
& consume_header
)
3568 _LIBCPP_SUPPRESS_DEPRECATED_POP
3570 // __codecvt_utf16<char32_t, false>
3572 __codecvt_utf16
<char32_t
, false>::result __codecvt_utf16
<char32_t
, false>::do_out(
3574 const intern_type
* frm
,
3575 const intern_type
* frm_end
,
3576 const intern_type
*& frm_nxt
,
3578 extern_type
* to_end
,
3579 extern_type
*& to_nxt
) const {
3580 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3581 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3582 const uint32_t* _frm_nxt
= _frm
;
3583 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3584 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3585 uint8_t* _to_nxt
= _to
;
3586 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3587 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3588 to_nxt
= to
+ (_to_nxt
- _to
);
3592 __codecvt_utf16
<char32_t
, false>::result __codecvt_utf16
<char32_t
, false>::do_in(
3594 const extern_type
* frm
,
3595 const extern_type
* frm_end
,
3596 const extern_type
*& frm_nxt
,
3598 intern_type
* to_end
,
3599 intern_type
*& to_nxt
) const {
3600 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3601 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3602 const uint8_t* _frm_nxt
= _frm
;
3603 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3604 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3605 uint32_t* _to_nxt
= _to
;
3606 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3607 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3608 to_nxt
= to
+ (_to_nxt
- _to
);
3612 __codecvt_utf16
<char32_t
, false>::result
3613 __codecvt_utf16
<char32_t
, false>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3618 int __codecvt_utf16
<char32_t
, false>::do_encoding() const noexcept
{ return 0; }
3620 bool __codecvt_utf16
<char32_t
, false>::do_always_noconv() const noexcept
{ return false; }
3622 int __codecvt_utf16
<char32_t
, false>::do_length(
3623 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3624 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3625 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3626 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3629 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3630 int __codecvt_utf16
<char32_t
, false>::do_max_length() const noexcept
{
3631 if (__mode_
& consume_header
)
3635 _LIBCPP_SUPPRESS_DEPRECATED_POP
3637 // __codecvt_utf16<char32_t, true>
3639 __codecvt_utf16
<char32_t
, true>::result __codecvt_utf16
<char32_t
, true>::do_out(
3641 const intern_type
* frm
,
3642 const intern_type
* frm_end
,
3643 const intern_type
*& frm_nxt
,
3645 extern_type
* to_end
,
3646 extern_type
*& to_nxt
) const {
3647 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3648 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3649 const uint32_t* _frm_nxt
= _frm
;
3650 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3651 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3652 uint8_t* _to_nxt
= _to
;
3653 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3654 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3655 to_nxt
= to
+ (_to_nxt
- _to
);
3659 __codecvt_utf16
<char32_t
, true>::result __codecvt_utf16
<char32_t
, true>::do_in(
3661 const extern_type
* frm
,
3662 const extern_type
* frm_end
,
3663 const extern_type
*& frm_nxt
,
3665 intern_type
* to_end
,
3666 intern_type
*& to_nxt
) const {
3667 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3668 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3669 const uint8_t* _frm_nxt
= _frm
;
3670 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3671 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3672 uint32_t* _to_nxt
= _to
;
3673 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3674 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3675 to_nxt
= to
+ (_to_nxt
- _to
);
3679 __codecvt_utf16
<char32_t
, true>::result
3680 __codecvt_utf16
<char32_t
, true>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3685 int __codecvt_utf16
<char32_t
, true>::do_encoding() const noexcept
{ return 0; }
3687 bool __codecvt_utf16
<char32_t
, true>::do_always_noconv() const noexcept
{ return false; }
3689 int __codecvt_utf16
<char32_t
, true>::do_length(
3690 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3691 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3692 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3693 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3696 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3697 int __codecvt_utf16
<char32_t
, true>::do_max_length() const noexcept
{
3698 if (__mode_
& consume_header
)
3702 _LIBCPP_SUPPRESS_DEPRECATED_POP
3704 // __codecvt_utf8_utf16<wchar_t>
3706 #if _LIBCPP_HAS_WIDE_CHARACTERS
3707 __codecvt_utf8_utf16
<wchar_t>::result __codecvt_utf8_utf16
<wchar_t>::do_out(
3709 const intern_type
* frm
,
3710 const intern_type
* frm_end
,
3711 const intern_type
*& frm_nxt
,
3713 extern_type
* to_end
,
3714 extern_type
*& to_nxt
) const {
3715 # if defined(_LIBCPP_SHORT_WCHAR)
3716 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3717 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3718 const uint16_t* _frm_nxt
= _frm
;
3720 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3721 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3722 const uint32_t* _frm_nxt
= _frm
;
3724 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3725 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3726 uint8_t* _to_nxt
= _to
;
3727 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3728 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3729 to_nxt
= to
+ (_to_nxt
- _to
);
3733 __codecvt_utf8_utf16
<wchar_t>::result __codecvt_utf8_utf16
<wchar_t>::do_in(
3735 const extern_type
* frm
,
3736 const extern_type
* frm_end
,
3737 const extern_type
*& frm_nxt
,
3739 intern_type
* to_end
,
3740 intern_type
*& to_nxt
) const {
3741 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3742 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3743 const uint8_t* _frm_nxt
= _frm
;
3744 # if defined(_LIBCPP_SHORT_WCHAR)
3745 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3746 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3747 uint16_t* _to_nxt
= _to
;
3749 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3750 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3751 uint32_t* _to_nxt
= _to
;
3753 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3754 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3755 to_nxt
= to
+ (_to_nxt
- _to
);
3759 __codecvt_utf8_utf16
<wchar_t>::result
3760 __codecvt_utf8_utf16
<wchar_t>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3765 int __codecvt_utf8_utf16
<wchar_t>::do_encoding() const noexcept
{ return 0; }
3767 bool __codecvt_utf8_utf16
<wchar_t>::do_always_noconv() const noexcept
{ return false; }
3769 int __codecvt_utf8_utf16
<wchar_t>::do_length(
3770 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3771 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3772 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3773 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3776 int __codecvt_utf8_utf16
<wchar_t>::do_max_length() const noexcept
{
3777 if (__mode_
& consume_header
)
3781 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3783 // __codecvt_utf8_utf16<char16_t>
3785 __codecvt_utf8_utf16
<char16_t
>::result __codecvt_utf8_utf16
<char16_t
>::do_out(
3787 const intern_type
* frm
,
3788 const intern_type
* frm_end
,
3789 const intern_type
*& frm_nxt
,
3791 extern_type
* to_end
,
3792 extern_type
*& to_nxt
) const {
3793 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3794 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3795 const uint16_t* _frm_nxt
= _frm
;
3796 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3797 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3798 uint8_t* _to_nxt
= _to
;
3799 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3800 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3801 to_nxt
= to
+ (_to_nxt
- _to
);
3805 __codecvt_utf8_utf16
<char16_t
>::result __codecvt_utf8_utf16
<char16_t
>::do_in(
3807 const extern_type
* frm
,
3808 const extern_type
* frm_end
,
3809 const extern_type
*& frm_nxt
,
3811 intern_type
* to_end
,
3812 intern_type
*& to_nxt
) const {
3813 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3814 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3815 const uint8_t* _frm_nxt
= _frm
;
3816 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3817 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3818 uint16_t* _to_nxt
= _to
;
3819 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3820 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3821 to_nxt
= to
+ (_to_nxt
- _to
);
3825 __codecvt_utf8_utf16
<char16_t
>::result
3826 __codecvt_utf8_utf16
<char16_t
>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3831 int __codecvt_utf8_utf16
<char16_t
>::do_encoding() const noexcept
{ return 0; }
3833 bool __codecvt_utf8_utf16
<char16_t
>::do_always_noconv() const noexcept
{ return false; }
3835 int __codecvt_utf8_utf16
<char16_t
>::do_length(
3836 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3837 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3838 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3839 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3842 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3843 int __codecvt_utf8_utf16
<char16_t
>::do_max_length() const noexcept
{
3844 if (__mode_
& consume_header
)
3848 _LIBCPP_SUPPRESS_DEPRECATED_POP
3850 // __codecvt_utf8_utf16<char32_t>
3852 __codecvt_utf8_utf16
<char32_t
>::result __codecvt_utf8_utf16
<char32_t
>::do_out(
3854 const intern_type
* frm
,
3855 const intern_type
* frm_end
,
3856 const intern_type
*& frm_nxt
,
3858 extern_type
* to_end
,
3859 extern_type
*& to_nxt
) const {
3860 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3861 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3862 const uint32_t* _frm_nxt
= _frm
;
3863 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3864 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3865 uint8_t* _to_nxt
= _to
;
3866 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3867 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3868 to_nxt
= to
+ (_to_nxt
- _to
);
3872 __codecvt_utf8_utf16
<char32_t
>::result __codecvt_utf8_utf16
<char32_t
>::do_in(
3874 const extern_type
* frm
,
3875 const extern_type
* frm_end
,
3876 const extern_type
*& frm_nxt
,
3878 intern_type
* to_end
,
3879 intern_type
*& to_nxt
) const {
3880 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3881 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3882 const uint8_t* _frm_nxt
= _frm
;
3883 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3884 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3885 uint32_t* _to_nxt
= _to
;
3886 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
, __maxcode_
, __mode_
);
3887 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3888 to_nxt
= to
+ (_to_nxt
- _to
);
3892 __codecvt_utf8_utf16
<char32_t
>::result
3893 __codecvt_utf8_utf16
<char32_t
>::do_unshift(state_type
&, extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const {
3898 int __codecvt_utf8_utf16
<char32_t
>::do_encoding() const noexcept
{ return 0; }
3900 bool __codecvt_utf8_utf16
<char32_t
>::do_always_noconv() const noexcept
{ return false; }
3902 int __codecvt_utf8_utf16
<char32_t
>::do_length(
3903 state_type
&, const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const {
3904 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3905 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3906 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3909 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3910 int __codecvt_utf8_utf16
<char32_t
>::do_max_length() const noexcept
{
3911 if (__mode_
& consume_header
)
3915 _LIBCPP_SUPPRESS_DEPRECATED_POP
3917 // __narrow_to_utf8<16>
3919 __narrow_to_utf8
<16>::~__narrow_to_utf8() {}
3921 // __narrow_to_utf8<32>
3923 __narrow_to_utf8
<32>::~__narrow_to_utf8() {}
3925 // __widen_from_utf8<16>
3927 __widen_from_utf8
<16>::~__widen_from_utf8() {}
3929 // __widen_from_utf8<32>
3931 __widen_from_utf8
<32>::~__widen_from_utf8() {}
3933 #if _LIBCPP_HAS_WIDE_CHARACTERS
3934 static bool checked_string_to_wchar_convert(wchar_t& dest
, const char* ptr
, __locale::__locale_t loc
) {
3939 size_t ret
= __locale::__mbrtowc(&out
, ptr
, strlen(ptr
), &mb
, loc
);
3940 if (ret
== static_cast<size_t>(-1) || ret
== static_cast<size_t>(-2)) {
3946 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3948 #if !_LIBCPP_HAS_WIDE_CHARACTERS
3949 static bool is_narrow_non_breaking_space(const char* ptr
) {
3950 // https://www.fileformat.info/info/unicode/char/202f/index.htm
3951 return ptr
[0] == '\xe2' && ptr
[1] == '\x80' && ptr
[2] == '\xaf';
3954 static bool is_non_breaking_space(const char* ptr
) {
3955 // https://www.fileformat.info/info/unicode/char/0a/index.htm
3956 return ptr
[0] == '\xc2' && ptr
[1] == '\xa0';
3958 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3960 static bool checked_string_to_char_convert(char& dest
, const char* ptr
, __locale::__locale_t __loc
) {
3968 #if _LIBCPP_HAS_WIDE_CHARACTERS
3969 // First convert the MBS into a wide char then attempt to narrow it using
3972 if (!checked_string_to_wchar_convert(wout
, ptr
, __loc
))
3975 if ((res
= __locale::__wctob(wout
, __loc
)) != char_traits
<char>::eof()) {
3979 // FIXME: Work around specific multibyte sequences that we can reasonably
3980 // translate into a different single byte.
3982 case L
'\u202F': // narrow non-breaking space
3983 case L
'\u00A0': // non-breaking space
3989 #else // _LIBCPP_HAS_WIDE_CHARACTERS
3990 // FIXME: Work around specific multibyte sequences that we can reasonably
3991 // translate into a different single byte.
3992 if (is_narrow_non_breaking_space(ptr
) || is_non_breaking_space(ptr
)) {
3998 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
3999 __libcpp_unreachable();
4002 // numpunct<char> && numpunct<wchar_t>
4004 constinit
locale::id numpunct
<char>::id
;
4005 #if _LIBCPP_HAS_WIDE_CHARACTERS
4006 constinit
locale::id numpunct
<wchar_t>::id
;
4009 numpunct
<char>::numpunct(size_t refs
) : locale::facet(refs
), __decimal_point_('.'), __thousands_sep_(',') {}
4011 #if _LIBCPP_HAS_WIDE_CHARACTERS
4012 numpunct
<wchar_t>::numpunct(size_t refs
) : locale::facet(refs
), __decimal_point_(L
'.'), __thousands_sep_(L
',') {}
4015 numpunct
<char>::~numpunct() {}
4017 #if _LIBCPP_HAS_WIDE_CHARACTERS
4018 numpunct
<wchar_t>::~numpunct() {}
4021 char numpunct
< char >::do_decimal_point() const { return __decimal_point_
; }
4022 #if _LIBCPP_HAS_WIDE_CHARACTERS
4023 wchar_t numpunct
<wchar_t>::do_decimal_point() const { return __decimal_point_
; }
4026 char numpunct
< char >::do_thousands_sep() const { return __thousands_sep_
; }
4027 #if _LIBCPP_HAS_WIDE_CHARACTERS
4028 wchar_t numpunct
<wchar_t>::do_thousands_sep() const { return __thousands_sep_
; }
4031 string numpunct
< char >::do_grouping() const { return __grouping_
; }
4032 #if _LIBCPP_HAS_WIDE_CHARACTERS
4033 string numpunct
<wchar_t>::do_grouping() const { return __grouping_
; }
4036 string numpunct
< char >::do_truename() const { return "true"; }
4037 #if _LIBCPP_HAS_WIDE_CHARACTERS
4038 wstring numpunct
<wchar_t>::do_truename() const { return L
"true"; }
4041 string numpunct
< char >::do_falsename() const { return "false"; }
4042 #if _LIBCPP_HAS_WIDE_CHARACTERS
4043 wstring numpunct
<wchar_t>::do_falsename() const { return L
"false"; }
4046 // numpunct_byname<char>
4048 numpunct_byname
<char>::numpunct_byname(const char* nm
, size_t refs
) : numpunct
<char>(refs
) { __init(nm
); }
4050 numpunct_byname
<char>::numpunct_byname(const string
& nm
, size_t refs
) : numpunct
<char>(refs
) { __init(nm
.c_str()); }
4052 numpunct_byname
<char>::~numpunct_byname() {}
4054 void numpunct_byname
<char>::__init(const char* nm
) {
4055 typedef numpunct
<char> base
;
4056 if (strcmp(nm
, "C") != 0) {
4057 __libcpp_unique_locale
loc(nm
);
4059 __throw_runtime_error(
4060 ("numpunct_byname<char>::numpunct_byname"
4061 " failed to construct for " +
4065 lconv
* lc
= __locale::__localeconv(loc
.get());
4066 if (!checked_string_to_char_convert(__decimal_point_
, lc
->decimal_point
, loc
.get()))
4067 __decimal_point_
= base::do_decimal_point();
4068 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->thousands_sep
, loc
.get()))
4069 __thousands_sep_
= base::do_thousands_sep();
4070 __grouping_
= lc
->grouping
;
4071 // localization for truename and falsename is not available
4075 // numpunct_byname<wchar_t>
4077 #if _LIBCPP_HAS_WIDE_CHARACTERS
4078 numpunct_byname
<wchar_t>::numpunct_byname(const char* nm
, size_t refs
) : numpunct
<wchar_t>(refs
) { __init(nm
); }
4080 numpunct_byname
<wchar_t>::numpunct_byname(const string
& nm
, size_t refs
) : numpunct
<wchar_t>(refs
) {
4084 numpunct_byname
<wchar_t>::~numpunct_byname() {}
4086 void numpunct_byname
<wchar_t>::__init(const char* nm
) {
4087 if (strcmp(nm
, "C") != 0) {
4088 __libcpp_unique_locale
loc(nm
);
4090 __throw_runtime_error(
4091 ("numpunct_byname<wchar_t>::numpunct_byname"
4092 " failed to construct for " +
4096 lconv
* lc
= __locale::__localeconv(loc
.get());
4097 checked_string_to_wchar_convert(__decimal_point_
, lc
->decimal_point
, loc
.get());
4098 checked_string_to_wchar_convert(__thousands_sep_
, lc
->thousands_sep
, loc
.get());
4099 __grouping_
= lc
->grouping
;
4100 // localization for truename and falsename is not available
4103 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
4107 int __num_get_base::__get_base(ios_base
& iob
) {
4108 ios_base::fmtflags __basefield
= iob
.flags() & ios_base::basefield
;
4109 if (__basefield
== ios_base::oct
)
4111 else if (__basefield
== ios_base::hex
)
4113 else if (__basefield
== 0)
4118 const char __num_get_base::__src
[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4120 void __check_grouping(const string
& __grouping
, unsigned* __g
, unsigned* __g_end
, ios_base::iostate
& __err
) {
4121 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4122 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4123 if (__grouping
.size() != 0 && __g_end
- __g
> 1) {
4124 reverse(__g
, __g_end
);
4125 const char* __ig
= __grouping
.data();
4126 const char* __eg
= __ig
+ __grouping
.size();
4127 for (unsigned* __r
= __g
; __r
< __g_end
- 1; ++__r
) {
4128 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max()) {
4129 if (static_cast<unsigned>(*__ig
) != *__r
) {
4130 __err
= ios_base::failbit
;
4134 if (__eg
- __ig
> 1)
4137 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max()) {
4138 if (static_cast<unsigned>(*__ig
) < __g_end
[-1] || __g_end
[-1] == 0)
4139 __err
= ios_base::failbit
;
4144 void __num_put_base::__format_int(char* __fmtp
, const char* __len
, bool __signd
, ios_base::fmtflags __flags
) {
4145 if ((__flags
& ios_base::showpos
) && (__flags
& ios_base::basefield
) != ios_base::oct
&&
4146 (__flags
& ios_base::basefield
) != ios_base::hex
&& __signd
)
4148 if (__flags
& ios_base::showbase
)
4151 *__fmtp
++ = *__len
++;
4152 if ((__flags
& ios_base::basefield
) == ios_base::oct
)
4154 else if ((__flags
& ios_base::basefield
) == ios_base::hex
) {
4155 if (__flags
& ios_base::uppercase
)
4165 bool __num_put_base::__format_float(char* __fmtp
, const char* __len
, ios_base::fmtflags __flags
) {
4166 bool specify_precision
= true;
4167 if (__flags
& ios_base::showpos
)
4169 if (__flags
& ios_base::showpoint
)
4171 ios_base::fmtflags floatfield
= __flags
& ios_base::floatfield
;
4172 bool uppercase
= (__flags
& ios_base::uppercase
) != 0;
4173 if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4174 specify_precision
= false;
4180 *__fmtp
++ = *__len
++;
4181 if (floatfield
== ios_base::fixed
) {
4186 } else if (floatfield
== ios_base::scientific
) {
4191 } else if (floatfield
== (ios_base::fixed
| ios_base::scientific
)) {
4202 return specify_precision
;
4205 char* __num_put_base::__identify_padding(char* __nb
, char* __ne
, const ios_base
& __iob
) {
4206 switch (__iob
.flags() & ios_base::adjustfield
) {
4207 case ios_base::internal
:
4208 if (__nb
[0] == '-' || __nb
[0] == '+')
4210 if (__ne
- __nb
>= 2 && __nb
[0] == '0' && (__nb
[1] == 'x' || __nb
[1] == 'X'))
4213 case ios_base::left
:
4215 case ios_base::right
:
4224 static string
* init_weeks() {
4225 static string weeks
[14];
4226 weeks
[0] = "Sunday";
4227 weeks
[1] = "Monday";
4228 weeks
[2] = "Tuesday";
4229 weeks
[3] = "Wednesday";
4230 weeks
[4] = "Thursday";
4231 weeks
[5] = "Friday";
4232 weeks
[6] = "Saturday";
4243 #if _LIBCPP_HAS_WIDE_CHARACTERS
4244 static wstring
* init_wweeks() {
4245 static wstring weeks
[14];
4246 weeks
[0] = L
"Sunday";
4247 weeks
[1] = L
"Monday";
4248 weeks
[2] = L
"Tuesday";
4249 weeks
[3] = L
"Wednesday";
4250 weeks
[4] = L
"Thursday";
4251 weeks
[5] = L
"Friday";
4252 weeks
[6] = L
"Saturday";
4265 const string
* __time_get_c_storage
<char>::__weeks() const {
4266 static const string
* weeks
= init_weeks();
4270 #if _LIBCPP_HAS_WIDE_CHARACTERS
4272 const wstring
* __time_get_c_storage
<wchar_t>::__weeks() const {
4273 static const wstring
* weeks
= init_wweeks();
4278 static string
* init_months() {
4279 static string months
[24];
4280 months
[0] = "January";
4281 months
[1] = "February";
4282 months
[2] = "March";
4283 months
[3] = "April";
4287 months
[7] = "August";
4288 months
[8] = "September";
4289 months
[9] = "October";
4290 months
[10] = "November";
4291 months
[11] = "December";
4307 #if _LIBCPP_HAS_WIDE_CHARACTERS
4308 static wstring
* init_wmonths() {
4309 static wstring months
[24];
4310 months
[0] = L
"January";
4311 months
[1] = L
"February";
4312 months
[2] = L
"March";
4313 months
[3] = L
"April";
4315 months
[5] = L
"June";
4316 months
[6] = L
"July";
4317 months
[7] = L
"August";
4318 months
[8] = L
"September";
4319 months
[9] = L
"October";
4320 months
[10] = L
"November";
4321 months
[11] = L
"December";
4322 months
[12] = L
"Jan";
4323 months
[13] = L
"Feb";
4324 months
[14] = L
"Mar";
4325 months
[15] = L
"Apr";
4326 months
[16] = L
"May";
4327 months
[17] = L
"Jun";
4328 months
[18] = L
"Jul";
4329 months
[19] = L
"Aug";
4330 months
[20] = L
"Sep";
4331 months
[21] = L
"Oct";
4332 months
[22] = L
"Nov";
4333 months
[23] = L
"Dec";
4339 const string
* __time_get_c_storage
<char>::__months() const {
4340 static const string
* months
= init_months();
4344 #if _LIBCPP_HAS_WIDE_CHARACTERS
4346 const wstring
* __time_get_c_storage
<wchar_t>::__months() const {
4347 static const wstring
* months
= init_wmonths();
4352 static string
* init_am_pm() {
4353 static string am_pm
[2];
4359 #if _LIBCPP_HAS_WIDE_CHARACTERS
4360 static wstring
* init_wam_pm() {
4361 static wstring am_pm
[2];
4369 const string
* __time_get_c_storage
<char>::__am_pm() const {
4370 static const string
* am_pm
= init_am_pm();
4374 #if _LIBCPP_HAS_WIDE_CHARACTERS
4376 const wstring
* __time_get_c_storage
<wchar_t>::__am_pm() const {
4377 static const wstring
* am_pm
= init_wam_pm();
4383 const string
& __time_get_c_storage
<char>::__x() const {
4384 static string
s("%m/%d/%y");
4388 #if _LIBCPP_HAS_WIDE_CHARACTERS
4390 const wstring
& __time_get_c_storage
<wchar_t>::__x() const {
4391 static wstring
s(L
"%m/%d/%y");
4397 const string
& __time_get_c_storage
<char>::__X() const {
4398 static string
s("%H:%M:%S");
4402 #if _LIBCPP_HAS_WIDE_CHARACTERS
4404 const wstring
& __time_get_c_storage
<wchar_t>::__X() const {
4405 static wstring
s(L
"%H:%M:%S");
4411 const string
& __time_get_c_storage
<char>::__c() const {
4412 static string
s("%a %b %d %H:%M:%S %Y");
4416 #if _LIBCPP_HAS_WIDE_CHARACTERS
4418 const wstring
& __time_get_c_storage
<wchar_t>::__c() const {
4419 static wstring
s(L
"%a %b %d %H:%M:%S %Y");
4425 const string
& __time_get_c_storage
<char>::__r() const {
4426 static string
s("%I:%M:%S %p");
4430 #if _LIBCPP_HAS_WIDE_CHARACTERS
4432 const wstring
& __time_get_c_storage
<wchar_t>::__r() const {
4433 static wstring
s(L
"%I:%M:%S %p");
4440 __time_get::__time_get(const char* nm
) : __loc_(__locale::__newlocale(LC_ALL_MASK
, nm
, 0)) {
4442 __throw_runtime_error(("time_get_byname failed to construct for " + string(nm
)).c_str());
4445 __time_get::__time_get(const string
& nm
) : __loc_(__locale::__newlocale(LC_ALL_MASK
, nm
.c_str(), 0)) {
4447 __throw_runtime_error(("time_get_byname failed to construct for " + nm
).c_str());
4450 __time_get::~__time_get() { __locale::__freelocale(__loc_
); }
4452 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
4455 string __time_get_storage
<char>::__analyze(char fmt
, const ctype
<char>& ct
) {
4470 size_t n
= __locale::__strftime(buf
, countof(buf
), f
, &t
, __loc_
);
4475 if (ct
.is(ctype_base::space
, *bb
)) {
4476 result
.push_back(' ');
4477 for (++bb
; bb
!= be
&& ct
.is(ctype_base::space
, *bb
); ++bb
)
4482 ios_base::iostate err
= ios_base::goodbit
;
4483 ptrdiff_t i
= __scan_keyword(w
, be
, this->__weeks_
, this->__weeks_
+ 14, ct
, err
, false) - this->__weeks_
;
4485 result
.push_back('%');
4487 result
.push_back('A');
4489 result
.push_back('a');
4494 i
= __scan_keyword(w
, be
, this->__months_
, this->__months_
+ 24, ct
, err
, false) - this->__months_
;
4496 result
.push_back('%');
4498 result
.push_back('B');
4500 result
.push_back('b');
4501 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
4502 result
.back() = 'm';
4506 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0) {
4508 i
= __scan_keyword(w
, be
, this->__am_pm_
, this->__am_pm_
+ 2, ct
, err
, false) - this->__am_pm_
;
4510 result
.push_back('%');
4511 result
.push_back('p');
4517 if (ct
.is(ctype_base::digit
, *bb
)) {
4518 switch (__get_up_to_n_digits(bb
, be
, err
, ct
, 4)) {
4520 result
.push_back('%');
4521 result
.push_back('w');
4524 result
.push_back('%');
4525 result
.push_back('u');
4528 result
.push_back('%');
4529 result
.push_back('I');
4532 result
.push_back('%');
4533 result
.push_back('m');
4536 result
.push_back('%');
4537 result
.push_back('H');
4540 result
.push_back('%');
4541 result
.push_back('d');
4544 result
.push_back('%');
4545 result
.push_back('M');
4548 result
.push_back('%');
4549 result
.push_back('S');
4552 result
.push_back('%');
4553 result
.push_back('y');
4556 result
.push_back('%');
4557 result
.push_back('j');
4560 result
.push_back('%');
4561 result
.push_back('Y');
4564 for (; w
!= bb
; ++w
)
4565 result
.push_back(*w
);
4571 result
.push_back('%');
4572 result
.push_back('%');
4576 result
.push_back(*bb
);
4582 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
4584 #if _LIBCPP_HAS_WIDE_CHARACTERS
4586 wstring __time_get_storage
<wchar_t>::__analyze(char fmt
, const ctype
<wchar_t>& ct
) {
4601 __locale::__strftime(buf
, countof(buf
), f
, &t
, __loc_
);
4603 wchar_t* wbb
= wbuf
;
4605 const char* bb
= buf
;
4606 size_t j
= __locale::__mbsrtowcs(wbb
, &bb
, countof(wbuf
), &mb
, __loc_
);
4607 if (j
== size_t(-1))
4608 __throw_runtime_error("locale not supported");
4609 wchar_t* wbe
= wbb
+ j
;
4611 while (wbb
!= wbe
) {
4612 if (ct
.is(ctype_base::space
, *wbb
)) {
4613 result
.push_back(L
' ');
4614 for (++wbb
; wbb
!= wbe
&& ct
.is(ctype_base::space
, *wbb
); ++wbb
)
4619 ios_base::iostate err
= ios_base::goodbit
;
4620 ptrdiff_t i
= __scan_keyword(w
, wbe
, this->__weeks_
, this->__weeks_
+ 14, ct
, err
, false) - this->__weeks_
;
4622 result
.push_back(L
'%');
4624 result
.push_back(L
'A');
4626 result
.push_back(L
'a');
4631 i
= __scan_keyword(w
, wbe
, this->__months_
, this->__months_
+ 24, ct
, err
, false) - this->__months_
;
4633 result
.push_back(L
'%');
4635 result
.push_back(L
'B');
4637 result
.push_back(L
'b');
4638 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
4639 result
.back() = L
'm';
4643 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0) {
4645 i
= __scan_keyword(w
, wbe
, this->__am_pm_
, this->__am_pm_
+ 2, ct
, err
, false) - this->__am_pm_
;
4647 result
.push_back(L
'%');
4648 result
.push_back(L
'p');
4654 if (ct
.is(ctype_base::digit
, *wbb
)) {
4655 switch (__get_up_to_n_digits(wbb
, wbe
, err
, ct
, 4)) {
4657 result
.push_back(L
'%');
4658 result
.push_back(L
'w');
4661 result
.push_back(L
'%');
4662 result
.push_back(L
'u');
4665 result
.push_back(L
'%');
4666 result
.push_back(L
'I');
4669 result
.push_back(L
'%');
4670 result
.push_back(L
'm');
4673 result
.push_back(L
'%');
4674 result
.push_back(L
'H');
4677 result
.push_back(L
'%');
4678 result
.push_back(L
'd');
4681 result
.push_back(L
'%');
4682 result
.push_back(L
'M');
4685 result
.push_back(L
'%');
4686 result
.push_back(L
'S');
4689 result
.push_back(L
'%');
4690 result
.push_back(L
'y');
4693 result
.push_back(L
'%');
4694 result
.push_back(L
'j');
4697 result
.push_back(L
'%');
4698 result
.push_back(L
'Y');
4701 for (; w
!= wbb
; ++w
)
4702 result
.push_back(*w
);
4707 if (ct
.narrow(*wbb
, 0) == '%') {
4708 result
.push_back(L
'%');
4709 result
.push_back(L
'%');
4713 result
.push_back(*wbb
);
4718 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
4721 void __time_get_storage
<char>::init(const ctype
<char>& ct
) {
4725 for (int i
= 0; i
< 7; ++i
) {
4727 __locale::__strftime(buf
, countof(buf
), "%A", &t
, __loc_
);
4729 __locale::__strftime(buf
, countof(buf
), "%a", &t
, __loc_
);
4730 __weeks_
[i
+ 7] = buf
;
4733 for (int i
= 0; i
< 12; ++i
) {
4735 __locale::__strftime(buf
, countof(buf
), "%B", &t
, __loc_
);
4737 __locale::__strftime(buf
, countof(buf
), "%b", &t
, __loc_
);
4738 __months_
[i
+ 12] = buf
;
4742 __locale::__strftime(buf
, countof(buf
), "%p", &t
, __loc_
);
4745 __locale::__strftime(buf
, countof(buf
), "%p", &t
, __loc_
);
4747 __c_
= __analyze('c', ct
);
4748 __r_
= __analyze('r', ct
);
4749 __x_
= __analyze('x', ct
);
4750 __X_
= __analyze('X', ct
);
4753 #if _LIBCPP_HAS_WIDE_CHARACTERS
4755 void __time_get_storage
<wchar_t>::init(const ctype
<wchar_t>& ct
) {
4762 for (int i
= 0; i
< 7; ++i
) {
4764 __locale::__strftime(buf
, countof(buf
), "%A", &t
, __loc_
);
4766 const char* bb
= buf
;
4767 size_t j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4768 if (j
== size_t(-1) || j
== 0)
4769 __throw_runtime_error("locale not supported");
4771 __weeks_
[i
].assign(wbuf
, wbe
);
4772 __locale::__strftime(buf
, countof(buf
), "%a", &t
, __loc_
);
4775 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4776 if (j
== size_t(-1) || j
== 0)
4777 __throw_runtime_error("locale not supported");
4779 __weeks_
[i
+ 7].assign(wbuf
, wbe
);
4782 for (int i
= 0; i
< 12; ++i
) {
4784 __locale::__strftime(buf
, countof(buf
), "%B", &t
, __loc_
);
4786 const char* bb
= buf
;
4787 size_t j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4788 if (j
== size_t(-1) || j
== 0)
4789 __throw_runtime_error("locale not supported");
4791 __months_
[i
].assign(wbuf
, wbe
);
4792 __locale::__strftime(buf
, countof(buf
), "%b", &t
, __loc_
);
4795 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4796 if (j
== size_t(-1) || j
== 0)
4797 __throw_runtime_error("locale not supported");
4799 __months_
[i
+ 12].assign(wbuf
, wbe
);
4803 __locale::__strftime(buf
, countof(buf
), "%p", &t
, __loc_
);
4805 const char* bb
= buf
;
4806 size_t j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4807 if (j
== size_t(-1))
4808 __throw_runtime_error("locale not supported");
4810 __am_pm_
[0].assign(wbuf
, wbe
);
4812 __locale::__strftime(buf
, countof(buf
), "%p", &t
, __loc_
);
4815 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
4816 if (j
== size_t(-1))
4817 __throw_runtime_error("locale not supported");
4819 __am_pm_
[1].assign(wbuf
, wbe
);
4820 __c_
= __analyze('c', ct
);
4821 __r_
= __analyze('r', ct
);
4822 __x_
= __analyze('x', ct
);
4823 __X_
= __analyze('X', ct
);
4825 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
4827 template <class CharT
>
4828 struct _LIBCPP_HIDDEN __time_get_temp
: public ctype_byname
<CharT
> {
4829 explicit __time_get_temp(const char* nm
) : ctype_byname
<CharT
>(nm
, 1) {}
4830 explicit __time_get_temp(const string
& nm
) : ctype_byname
<CharT
>(nm
, 1) {}
4834 __time_get_storage
<char>::__time_get_storage(const char* __nm
) : __time_get(__nm
) {
4835 const __time_get_temp
<char> ct(__nm
);
4840 __time_get_storage
<char>::__time_get_storage(const string
& __nm
) : __time_get(__nm
) {
4841 const __time_get_temp
<char> ct(__nm
);
4845 #if _LIBCPP_HAS_WIDE_CHARACTERS
4847 __time_get_storage
<wchar_t>::__time_get_storage(const char* __nm
) : __time_get(__nm
) {
4848 const __time_get_temp
<wchar_t> ct(__nm
);
4853 __time_get_storage
<wchar_t>::__time_get_storage(const string
& __nm
) : __time_get(__nm
) {
4854 const __time_get_temp
<wchar_t> ct(__nm
);
4857 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
4860 time_base::dateorder __time_get_storage
<char>::__do_date_order() const {
4862 for (i
= 0; i
< __x_
.size(); ++i
)
4869 for (++i
; i
< __x_
.size(); ++i
)
4872 if (i
== __x_
.size())
4877 for (++i
; i
< __x_
.size(); ++i
)
4880 if (i
== __x_
.size())
4884 return time_base::ymd
;
4887 for (++i
; i
< __x_
.size(); ++i
)
4890 if (i
== __x_
.size())
4894 return time_base::ydm
;
4899 for (++i
; i
< __x_
.size(); ++i
)
4902 if (i
== __x_
.size())
4905 if (__x_
[i
] == 'd') {
4906 for (++i
; i
< __x_
.size(); ++i
)
4909 if (i
== __x_
.size())
4912 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
4913 return time_base::mdy
;
4918 for (++i
; i
< __x_
.size(); ++i
)
4921 if (i
== __x_
.size())
4924 if (__x_
[i
] == 'm') {
4925 for (++i
; i
< __x_
.size(); ++i
)
4928 if (i
== __x_
.size())
4931 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
4932 return time_base::dmy
;
4937 return time_base::no_order
;
4940 #if _LIBCPP_HAS_WIDE_CHARACTERS
4942 time_base::dateorder __time_get_storage
<wchar_t>::__do_date_order() const {
4944 for (i
= 0; i
< __x_
.size(); ++i
)
4945 if (__x_
[i
] == L
'%')
4951 for (++i
; i
< __x_
.size(); ++i
)
4952 if (__x_
[i
] == L
'%')
4954 if (i
== __x_
.size())
4959 for (++i
; i
< __x_
.size(); ++i
)
4960 if (__x_
[i
] == L
'%')
4962 if (i
== __x_
.size())
4965 if (__x_
[i
] == L
'd')
4966 return time_base::ymd
;
4969 for (++i
; i
< __x_
.size(); ++i
)
4970 if (__x_
[i
] == L
'%')
4972 if (i
== __x_
.size())
4975 if (__x_
[i
] == L
'm')
4976 return time_base::ydm
;
4981 for (++i
; i
< __x_
.size(); ++i
)
4982 if (__x_
[i
] == L
'%')
4984 if (i
== __x_
.size())
4987 if (__x_
[i
] == L
'd') {
4988 for (++i
; i
< __x_
.size(); ++i
)
4989 if (__x_
[i
] == L
'%')
4991 if (i
== __x_
.size())
4994 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
4995 return time_base::mdy
;
5000 for (++i
; i
< __x_
.size(); ++i
)
5001 if (__x_
[i
] == L
'%')
5003 if (i
== __x_
.size())
5006 if (__x_
[i
] == L
'm') {
5007 for (++i
; i
< __x_
.size(); ++i
)
5008 if (__x_
[i
] == L
'%')
5010 if (i
== __x_
.size())
5013 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5014 return time_base::dmy
;
5019 return time_base::no_order
;
5021 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
5025 __time_put::__time_put(const char* nm
) : __loc_(__locale::__newlocale(LC_ALL_MASK
, nm
, 0)) {
5027 __throw_runtime_error(("time_put_byname failed to construct for " + string(nm
)).c_str());
5030 __time_put::__time_put(const string
& nm
) : __loc_(__locale::__newlocale(LC_ALL_MASK
, nm
.c_str(), 0)) {
5032 __throw_runtime_error(("time_put_byname failed to construct for " + nm
).c_str());
5035 __time_put::~__time_put() {
5036 if (__loc_
!= _LIBCPP_GET_C_LOCALE
)
5037 __locale::__freelocale(__loc_
);
5040 void __time_put::__do_put(char* __nb
, char*& __ne
, const tm
* __tm
, char __fmt
, char __mod
) const {
5041 char fmt
[] = {'%', __fmt
, __mod
, 0};
5043 swap(fmt
[1], fmt
[2]);
5044 size_t n
= __locale::__strftime(__nb
, countof(__nb
, __ne
), fmt
, __tm
, __loc_
);
5048 #if _LIBCPP_HAS_WIDE_CHARACTERS
5049 void __time_put::__do_put(wchar_t* __wb
, wchar_t*& __we
, const tm
* __tm
, char __fmt
, char __mod
) const {
5051 char* __ne
= __nar
+ 100;
5052 __do_put(__nar
, __ne
, __tm
, __fmt
, __mod
);
5054 const char* __nb
= __nar
;
5055 size_t j
= __locale::__mbsrtowcs(__wb
, &__nb
, countof(__wb
, __we
), &mb
, __loc_
);
5056 if (j
== size_t(-1))
5057 __throw_runtime_error("locale not supported");
5060 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
5062 // moneypunct_byname
5064 template <class charT
>
5065 static void __init_pat(
5066 money_base::pattern
& pat
,
5067 basic_string
<charT
>& __curr_symbol_
,
5073 const char sign
= static_cast<char>(money_base::sign
);
5074 const char space
= static_cast<char>(money_base::space
);
5075 const char none
= static_cast<char>(money_base::none
);
5076 const char symbol
= static_cast<char>(money_base::symbol
);
5077 const char value
= static_cast<char>(money_base::value
);
5078 const bool symbol_contains_sep
= intl
&& __curr_symbol_
.size() == 4;
5080 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5081 // function'. "Space between sign and symbol or value" means that
5082 // if the sign is adjacent to the symbol, there's a space between
5083 // them, and otherwise there's a space between the sign and value.
5085 // C11's localeconv specifies that the fourth character of an
5086 // international curr_symbol is used to separate the sign and
5087 // value when sep_by_space says to do so. C++ can't represent
5088 // that, so we just use a space. When sep_by_space says to
5089 // separate the symbol and value-or-sign with a space, we rearrange the
5090 // curr_symbol to put its spacing character on the correct side of
5093 // We also need to avoid adding an extra space between the sign
5094 // and value when the currency symbol is suppressed (by not
5095 // setting showbase). We match glibc's strfmon by interpreting
5096 // sep_by_space==1 as "omit the space when the currency symbol is
5099 // Users who want to get this right should use ICU instead.
5101 switch (cs_precedes
) {
5102 case 0: // value before curr_symbol
5103 if (symbol_contains_sep
) {
5104 // Move the separator to before the symbol, to place it
5105 // between the value and symbol.
5106 rotate(__curr_symbol_
.begin(), __curr_symbol_
.begin() + 3, __curr_symbol_
.end());
5108 switch (sign_posn
) {
5109 case 0: // Parentheses surround the quantity and currency symbol.
5110 pat
.field
[0] = sign
;
5111 pat
.field
[1] = value
;
5112 pat
.field
[2] = none
; // Any space appears in the symbol.
5113 pat
.field
[3] = symbol
;
5114 switch (sep_by_space
) {
5115 case 0: // No space separates the currency symbol and value.
5116 // This case may have changed between C99 and C11;
5117 // assume the currency symbol matches the intention.
5118 case 2: // Space between sign and currency or value.
5119 // The "sign" is two parentheses, so no space here either.
5121 case 1: // Space between currency-and-sign or currency and value.
5122 if (!symbol_contains_sep
) {
5123 // We insert the space into the symbol instead of
5124 // setting pat.field[2]=space so that when
5125 // showbase is not set, the space goes away too.
5126 __curr_symbol_
.insert(0, 1, space_char
);
5133 case 1: // The sign string precedes the quantity and currency symbol.
5134 pat
.field
[0] = sign
;
5135 pat
.field
[3] = symbol
;
5136 switch (sep_by_space
) {
5137 case 0: // No space separates the currency symbol and value.
5138 pat
.field
[1] = value
;
5139 pat
.field
[2] = none
;
5141 case 1: // Space between currency-and-sign or currency and value.
5142 pat
.field
[1] = value
;
5143 pat
.field
[2] = none
;
5144 if (!symbol_contains_sep
) {
5145 // We insert the space into the symbol instead of
5146 // setting pat.field[2]=space so that when
5147 // showbase is not set, the space goes away too.
5148 __curr_symbol_
.insert(0, 1, space_char
);
5151 case 2: // Space between sign and currency or value.
5152 pat
.field
[1] = space
;
5153 pat
.field
[2] = value
;
5154 if (symbol_contains_sep
) {
5155 // Remove the separator from the symbol, since it
5156 // has already appeared after the sign.
5157 __curr_symbol_
.erase(__curr_symbol_
.begin());
5164 case 2: // The sign string succeeds the quantity and currency symbol.
5165 pat
.field
[0] = value
;
5166 pat
.field
[3] = sign
;
5167 switch (sep_by_space
) {
5168 case 0: // No space separates the currency symbol and value.
5169 pat
.field
[1] = none
;
5170 pat
.field
[2] = symbol
;
5172 case 1: // Space between currency-and-sign or currency and value.
5173 if (!symbol_contains_sep
) {
5174 // We insert the space into the symbol instead of
5175 // setting pat.field[1]=space so that when
5176 // showbase is not set, the space goes away too.
5177 __curr_symbol_
.insert(0, 1, space_char
);
5179 pat
.field
[1] = none
;
5180 pat
.field
[2] = symbol
;
5182 case 2: // Space between sign and currency or value.
5183 pat
.field
[1] = symbol
;
5184 pat
.field
[2] = space
;
5185 if (symbol_contains_sep
) {
5186 // Remove the separator from the symbol, since it
5187 // should not be removed if showbase is absent.
5188 __curr_symbol_
.erase(__curr_symbol_
.begin());
5195 case 3: // The sign string immediately precedes the currency symbol.
5196 pat
.field
[0] = value
;
5197 pat
.field
[3] = symbol
;
5198 switch (sep_by_space
) {
5199 case 0: // No space separates the currency symbol and value.
5200 pat
.field
[1] = none
;
5201 pat
.field
[2] = sign
;
5203 case 1: // Space between currency-and-sign or currency and value.
5204 pat
.field
[1] = space
;
5205 pat
.field
[2] = sign
;
5206 if (symbol_contains_sep
) {
5207 // Remove the separator from the symbol, since it
5208 // has already appeared before the sign.
5209 __curr_symbol_
.erase(__curr_symbol_
.begin());
5212 case 2: // Space between sign and currency or value.
5213 pat
.field
[1] = sign
;
5214 pat
.field
[2] = none
;
5215 if (!symbol_contains_sep
) {
5216 // We insert the space into the symbol instead of
5217 // setting pat.field[2]=space so that when
5218 // showbase is not set, the space goes away too.
5219 __curr_symbol_
.insert(0, 1, space_char
);
5226 case 4: // The sign string immediately succeeds the currency symbol.
5227 pat
.field
[0] = value
;
5228 pat
.field
[3] = sign
;
5229 switch (sep_by_space
) {
5230 case 0: // No space separates the currency symbol and value.
5231 pat
.field
[1] = none
;
5232 pat
.field
[2] = symbol
;
5234 case 1: // Space between currency-and-sign or currency and value.
5235 pat
.field
[1] = none
;
5236 pat
.field
[2] = symbol
;
5237 if (!symbol_contains_sep
) {
5238 // We insert the space into the symbol instead of
5239 // setting pat.field[1]=space so that when
5240 // showbase is not set, the space goes away too.
5241 __curr_symbol_
.insert(0, 1, space_char
);
5244 case 2: // Space between sign and currency or value.
5245 pat
.field
[1] = symbol
;
5246 pat
.field
[2] = space
;
5247 if (symbol_contains_sep
) {
5248 // Remove the separator from the symbol, since it
5249 // should not disappear when showbase is absent.
5250 __curr_symbol_
.erase(__curr_symbol_
.begin());
5261 case 1: // curr_symbol before value
5262 switch (sign_posn
) {
5263 case 0: // Parentheses surround the quantity and currency symbol.
5264 pat
.field
[0] = sign
;
5265 pat
.field
[1] = symbol
;
5266 pat
.field
[2] = none
; // Any space appears in the symbol.
5267 pat
.field
[3] = value
;
5268 switch (sep_by_space
) {
5269 case 0: // No space separates the currency symbol and value.
5270 // This case may have changed between C99 and C11;
5271 // assume the currency symbol matches the intention.
5272 case 2: // Space between sign and currency or value.
5273 // The "sign" is two parentheses, so no space here either.
5275 case 1: // Space between currency-and-sign or currency and value.
5276 if (!symbol_contains_sep
) {
5277 // We insert the space into the symbol instead of
5278 // setting pat.field[2]=space so that when
5279 // showbase is not set, the space goes away too.
5280 __curr_symbol_
.insert(0, 1, space_char
);
5287 case 1: // The sign string precedes the quantity and currency symbol.
5288 pat
.field
[0] = sign
;
5289 pat
.field
[3] = value
;
5290 switch (sep_by_space
) {
5291 case 0: // No space separates the currency symbol and value.
5292 pat
.field
[1] = symbol
;
5293 pat
.field
[2] = none
;
5295 case 1: // Space between currency-and-sign or currency and value.
5296 pat
.field
[1] = symbol
;
5297 pat
.field
[2] = none
;
5298 if (!symbol_contains_sep
) {
5299 // We insert the space into the symbol instead of
5300 // setting pat.field[2]=space so that when
5301 // showbase is not set, the space goes away too.
5302 __curr_symbol_
.push_back(space_char
);
5305 case 2: // Space between sign and currency or value.
5306 pat
.field
[1] = space
;
5307 pat
.field
[2] = symbol
;
5308 if (symbol_contains_sep
) {
5309 // Remove the separator from the symbol, since it
5310 // has already appeared after the sign.
5311 __curr_symbol_
.pop_back();
5318 case 2: // The sign string succeeds the quantity and currency symbol.
5319 pat
.field
[0] = symbol
;
5320 pat
.field
[3] = sign
;
5321 switch (sep_by_space
) {
5322 case 0: // No space separates the currency symbol and value.
5323 pat
.field
[1] = none
;
5324 pat
.field
[2] = value
;
5326 case 1: // Space between currency-and-sign or currency and value.
5327 pat
.field
[1] = none
;
5328 pat
.field
[2] = value
;
5329 if (!symbol_contains_sep
) {
5330 // We insert the space into the symbol instead of
5331 // setting pat.field[1]=space so that when
5332 // showbase is not set, the space goes away too.
5333 __curr_symbol_
.push_back(space_char
);
5336 case 2: // Space between sign and currency or value.
5337 pat
.field
[1] = value
;
5338 pat
.field
[2] = space
;
5339 if (symbol_contains_sep
) {
5340 // Remove the separator from the symbol, since it
5341 // will appear before the sign.
5342 __curr_symbol_
.pop_back();
5349 case 3: // The sign string immediately precedes the currency symbol.
5350 pat
.field
[0] = sign
;
5351 pat
.field
[3] = value
;
5352 switch (sep_by_space
) {
5353 case 0: // No space separates the currency symbol and value.
5354 pat
.field
[1] = symbol
;
5355 pat
.field
[2] = none
;
5357 case 1: // Space between currency-and-sign or currency and value.
5358 pat
.field
[1] = symbol
;
5359 pat
.field
[2] = none
;
5360 if (!symbol_contains_sep
) {
5361 // We insert the space into the symbol instead of
5362 // setting pat.field[2]=space so that when
5363 // showbase is not set, the space goes away too.
5364 __curr_symbol_
.push_back(space_char
);
5367 case 2: // Space between sign and currency or value.
5368 pat
.field
[1] = space
;
5369 pat
.field
[2] = symbol
;
5370 if (symbol_contains_sep
) {
5371 // Remove the separator from the symbol, since it
5372 // has already appeared after the sign.
5373 __curr_symbol_
.pop_back();
5380 case 4: // The sign string immediately succeeds the currency symbol.
5381 pat
.field
[0] = symbol
;
5382 pat
.field
[3] = value
;
5383 switch (sep_by_space
) {
5384 case 0: // No space separates the currency symbol and value.
5385 pat
.field
[1] = sign
;
5386 pat
.field
[2] = none
;
5388 case 1: // Space between currency-and-sign or currency and value.
5389 pat
.field
[1] = sign
;
5390 pat
.field
[2] = space
;
5391 if (symbol_contains_sep
) {
5392 // Remove the separator from the symbol, since it
5393 // should not disappear when showbase is absent.
5394 __curr_symbol_
.pop_back();
5397 case 2: // Space between sign and currency or value.
5398 pat
.field
[1] = none
;
5399 pat
.field
[2] = sign
;
5400 if (!symbol_contains_sep
) {
5401 // We insert the space into the symbol instead of
5402 // setting pat.field[1]=space so that when
5403 // showbase is not set, the space goes away too.
5404 __curr_symbol_
.push_back(space_char
);
5418 pat
.field
[0] = symbol
;
5419 pat
.field
[1] = sign
;
5420 pat
.field
[2] = none
;
5421 pat
.field
[3] = value
;
5425 void moneypunct_byname
<char, false>::init(const char* nm
) {
5426 typedef moneypunct
<char, false> base
;
5427 __libcpp_unique_locale
loc(nm
);
5429 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
5431 lconv
* lc
= __locale::__localeconv(loc
.get());
5432 if (!checked_string_to_char_convert(__decimal_point_
, lc
->mon_decimal_point
, loc
.get()))
5433 __decimal_point_
= base::do_decimal_point();
5434 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->mon_thousands_sep
, loc
.get()))
5435 __thousands_sep_
= base::do_thousands_sep();
5437 __grouping_
= lc
->mon_grouping
;
5438 __curr_symbol_
= lc
->currency_symbol
;
5439 if (lc
->frac_digits
!= CHAR_MAX
)
5440 __frac_digits_
= lc
->frac_digits
;
5442 __frac_digits_
= base::do_frac_digits();
5443 if (lc
->p_sign_posn
== 0)
5444 __positive_sign_
= "()";
5446 __positive_sign_
= lc
->positive_sign
;
5447 if (lc
->n_sign_posn
== 0)
5448 __negative_sign_
= "()";
5450 __negative_sign_
= lc
->negative_sign
;
5451 // Assume the positive and negative formats will want spaces in
5452 // the same places in curr_symbol since there's no way to
5453 // represent anything else.
5454 string_type __dummy_curr_symbol
= __curr_symbol_
;
5455 __init_pat(__pos_format_
, __dummy_curr_symbol
, false, lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
5456 __init_pat(__neg_format_
, __curr_symbol_
, false, lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
5460 void moneypunct_byname
<char, true>::init(const char* nm
) {
5461 typedef moneypunct
<char, true> base
;
5462 __libcpp_unique_locale
loc(nm
);
5464 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
5466 lconv
* lc
= __locale::__localeconv(loc
.get());
5467 if (!checked_string_to_char_convert(__decimal_point_
, lc
->mon_decimal_point
, loc
.get()))
5468 __decimal_point_
= base::do_decimal_point();
5469 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->mon_thousands_sep
, loc
.get()))
5470 __thousands_sep_
= base::do_thousands_sep();
5471 __grouping_
= lc
->mon_grouping
;
5472 __curr_symbol_
= lc
->int_curr_symbol
;
5473 if (lc
->int_frac_digits
!= CHAR_MAX
)
5474 __frac_digits_
= lc
->int_frac_digits
;
5476 __frac_digits_
= base::do_frac_digits();
5477 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5478 if (lc
->p_sign_posn
== 0)
5479 #else // _LIBCPP_MSVCRT
5480 if (lc
->int_p_sign_posn
== 0)
5481 #endif // !_LIBCPP_MSVCRT
5482 __positive_sign_
= "()";
5484 __positive_sign_
= lc
->positive_sign
;
5485 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5486 if (lc
->n_sign_posn
== 0)
5487 #else // _LIBCPP_MSVCRT
5488 if (lc
->int_n_sign_posn
== 0)
5489 #endif // !_LIBCPP_MSVCRT
5490 __negative_sign_
= "()";
5492 __negative_sign_
= lc
->negative_sign
;
5493 // Assume the positive and negative formats will want spaces in
5494 // the same places in curr_symbol since there's no way to
5495 // represent anything else.
5496 string_type __dummy_curr_symbol
= __curr_symbol_
;
5497 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5498 __init_pat(__pos_format_
, __dummy_curr_symbol
, true, lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
5499 __init_pat(__neg_format_
, __curr_symbol_
, true, lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
5500 #else // _LIBCPP_MSVCRT
5503 __dummy_curr_symbol
,
5505 lc
->int_p_cs_precedes
,
5506 lc
->int_p_sep_by_space
,
5507 lc
->int_p_sign_posn
,
5510 __neg_format_
, __curr_symbol_
, true, lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
, lc
->int_n_sign_posn
, ' ');
5511 #endif // !_LIBCPP_MSVCRT
5514 #if _LIBCPP_HAS_WIDE_CHARACTERS
5516 void moneypunct_byname
<wchar_t, false>::init(const char* nm
) {
5517 typedef moneypunct
<wchar_t, false> base
;
5518 __libcpp_unique_locale
loc(nm
);
5520 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
5521 lconv
* lc
= __locale::__localeconv(loc
.get());
5522 if (!checked_string_to_wchar_convert(__decimal_point_
, lc
->mon_decimal_point
, loc
.get()))
5523 __decimal_point_
= base::do_decimal_point();
5524 if (!checked_string_to_wchar_convert(__thousands_sep_
, lc
->mon_thousands_sep
, loc
.get()))
5525 __thousands_sep_
= base::do_thousands_sep();
5526 __grouping_
= lc
->mon_grouping
;
5529 const char* bb
= lc
->currency_symbol
;
5530 size_t j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5531 if (j
== size_t(-1))
5532 __throw_runtime_error("locale not supported");
5533 wchar_t* wbe
= wbuf
+ j
;
5534 __curr_symbol_
.assign(wbuf
, wbe
);
5535 if (lc
->frac_digits
!= CHAR_MAX
)
5536 __frac_digits_
= lc
->frac_digits
;
5538 __frac_digits_
= base::do_frac_digits();
5539 if (lc
->p_sign_posn
== 0)
5540 __positive_sign_
= L
"()";
5543 bb
= lc
->positive_sign
;
5544 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5545 if (j
== size_t(-1))
5546 __throw_runtime_error("locale not supported");
5548 __positive_sign_
.assign(wbuf
, wbe
);
5550 if (lc
->n_sign_posn
== 0)
5551 __negative_sign_
= L
"()";
5554 bb
= lc
->negative_sign
;
5555 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5556 if (j
== size_t(-1))
5557 __throw_runtime_error("locale not supported");
5559 __negative_sign_
.assign(wbuf
, wbe
);
5561 // Assume the positive and negative formats will want spaces in
5562 // the same places in curr_symbol since there's no way to
5563 // represent anything else.
5564 string_type __dummy_curr_symbol
= __curr_symbol_
;
5565 __init_pat(__pos_format_
, __dummy_curr_symbol
, false, lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
5566 __init_pat(__neg_format_
, __curr_symbol_
, false, lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
5570 void moneypunct_byname
<wchar_t, true>::init(const char* nm
) {
5571 typedef moneypunct
<wchar_t, true> base
;
5572 __libcpp_unique_locale
loc(nm
);
5574 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
5576 lconv
* lc
= __locale::__localeconv(loc
.get());
5577 if (!checked_string_to_wchar_convert(__decimal_point_
, lc
->mon_decimal_point
, loc
.get()))
5578 __decimal_point_
= base::do_decimal_point();
5579 if (!checked_string_to_wchar_convert(__thousands_sep_
, lc
->mon_thousands_sep
, loc
.get()))
5580 __thousands_sep_
= base::do_thousands_sep();
5581 __grouping_
= lc
->mon_grouping
;
5584 const char* bb
= lc
->int_curr_symbol
;
5585 size_t j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5586 if (j
== size_t(-1))
5587 __throw_runtime_error("locale not supported");
5588 wchar_t* wbe
= wbuf
+ j
;
5589 __curr_symbol_
.assign(wbuf
, wbe
);
5590 if (lc
->int_frac_digits
!= CHAR_MAX
)
5591 __frac_digits_
= lc
->int_frac_digits
;
5593 __frac_digits_
= base::do_frac_digits();
5594 # if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5595 if (lc
->p_sign_posn
== 0)
5596 # else // _LIBCPP_MSVCRT
5597 if (lc
->int_p_sign_posn
== 0)
5598 # endif // !_LIBCPP_MSVCRT
5599 __positive_sign_
= L
"()";
5602 bb
= lc
->positive_sign
;
5603 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5604 if (j
== size_t(-1))
5605 __throw_runtime_error("locale not supported");
5607 __positive_sign_
.assign(wbuf
, wbe
);
5609 # if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5610 if (lc
->n_sign_posn
== 0)
5611 # else // _LIBCPP_MSVCRT
5612 if (lc
->int_n_sign_posn
== 0)
5613 # endif // !_LIBCPP_MSVCRT
5614 __negative_sign_
= L
"()";
5617 bb
= lc
->negative_sign
;
5618 j
= __locale::__mbsrtowcs(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
5619 if (j
== size_t(-1))
5620 __throw_runtime_error("locale not supported");
5622 __negative_sign_
.assign(wbuf
, wbe
);
5624 // Assume the positive and negative formats will want spaces in
5625 // the same places in curr_symbol since there's no way to
5626 // represent anything else.
5627 string_type __dummy_curr_symbol
= __curr_symbol_
;
5628 # if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5629 __init_pat(__pos_format_
, __dummy_curr_symbol
, true, lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
5630 __init_pat(__neg_format_
, __curr_symbol_
, true, lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
5631 # else // _LIBCPP_MSVCRT
5634 __dummy_curr_symbol
,
5636 lc
->int_p_cs_precedes
,
5637 lc
->int_p_sep_by_space
,
5638 lc
->int_p_sign_posn
,
5641 __neg_format_
, __curr_symbol_
, true, lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
, lc
->int_n_sign_posn
, L
' ');
5642 # endif // !_LIBCPP_MSVCRT
5644 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
5646 void __do_nothing(void*) {}
5648 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<char>;
5649 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<wchar_t>;)
5651 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<char>;
5652 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<wchar_t>;)
5654 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<char>;
5655 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<wchar_t>;)
5657 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<char>;
5658 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<wchar_t>;)
5660 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<char>;
5661 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<wchar_t>;)
5663 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<char>;
5664 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<wchar_t>;)
5666 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<char>;
5667 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<wchar_t>;)
5669 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<char>;
5670 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<wchar_t>;)
5672 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<char>;
5673 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<wchar_t>;)
5675 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, false>;
5676 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, true>;
5677 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, false>;)
5678 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, true>;)
5680 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, false>;
5681 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, true>;
5682 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, false>;)
5683 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, true>;)
5685 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<char>;
5686 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<wchar_t>;)
5688 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<char>;
5689 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<wchar_t>;)
5691 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<char>;
5692 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<wchar_t>;)
5694 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<char>;
5695 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<wchar_t>;)
5697 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<char>;
5698 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<wchar_t>;)
5700 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<char>;
5701 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<wchar_t>;)
5703 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char, char, mbstate_t>;
5704 _LIBCPP_IF_WIDE_CHARACTERS(
5705 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<wchar_t, char, mbstate_t>;)
5706 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
5707 codecvt_byname
<char16_t
, char, mbstate_t>;
5708 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
5709 codecvt_byname
<char32_t
, char, mbstate_t>;
5710 #if _LIBCPP_HAS_CHAR8_T
5711 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char8_t
, mbstate_t>;
5712 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char8_t
, mbstate_t>;
5715 _LIBCPP_END_NAMESPACE_STD