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 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
30 # include <sys/localedef.h> // for __lc_ctype_ptr
33 #if defined(_LIBCPP_MSVCRT)
34 # define _CTYPE_DISABLE_MACROS
37 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
38 # include "__support/win32/locale_win32.h"
39 #elif !defined(__BIONIC__) && !defined(__NuttX__)
40 # include <langinfo.h>
43 #include "include/atomic_support.h"
44 #include "include/sso_allocator.h"
46 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
47 // lots of noise in the build log, but no bugs that I know of.
48 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
51 #include <__undef_macros>
53 _LIBCPP_BEGIN_NAMESPACE_STD
55 struct __libcpp_unique_locale
{
56 __libcpp_unique_locale(const char* nm
) : __loc_(newlocale(LC_ALL_MASK
, nm
, 0)) {}
58 ~__libcpp_unique_locale() {
63 explicit operator bool() const { return __loc_
; }
65 locale_t
& get() { return __loc_
; }
69 __libcpp_unique_locale(__libcpp_unique_locale
const&);
70 __libcpp_unique_locale
& operator=(__libcpp_unique_locale
const&);
75 // In theory this could create a race condition. In practice
76 // the race condition is non-fatal since it will just create
77 // a little resource leak. Better approach would be appreciated.
78 static locale_t result
= newlocale(LC_ALL_MASK
, "C", 0);
81 #endif // __cloc_defined
86 void operator()(locale::facet
* p
) { p
->__release_shared(); }
89 template <class T
, class ...Args
>
92 alignas(T
) static std::byte buf
[sizeof(T
)];
93 auto *obj
= ::new (&buf
) T(args
...);
97 template <typename T
, size_t N
>
101 countof(const T (&)[N
])
106 template <typename T
>
110 countof(const T
* const begin
, const T
* const end
)
112 return static_cast<size_t>(end
- begin
);
118 build_name(const string
& other
, const string
& one
, locale::category c
) {
119 if (other
== "*" || one
== "*")
121 if (c
== locale::none
|| other
== one
)
124 // FIXME: Handle the more complicated cases, such as when the locale has
125 // different names for different categories.
129 const locale::category
locale::none
;
130 const locale::category
locale::collate
;
131 const locale::category
locale::ctype
;
132 const locale::category
locale::monetary
;
133 const locale::category
locale::numeric
;
134 const locale::category
locale::time
;
135 const locale::category
locale::messages
;
136 const locale::category
locale::all
;
138 class _LIBCPP_HIDDEN
locale::__imp
142 vector
<facet
*, __sso_allocator
<facet
*, N
> > facets_
;
145 explicit __imp(size_t refs
= 0);
146 explicit __imp(const string
& name
, size_t refs
= 0);
148 __imp(const __imp
&, const string
&, locale::category c
);
149 __imp(const __imp
& other
, const __imp
& one
, locale::category c
);
150 __imp(const __imp
&, facet
* f
, long id
);
153 const string
& name() const {return name_
;}
154 bool has_facet(long id
) const
155 {return static_cast<size_t>(id
) < facets_
.size() && facets_
[static_cast<size_t>(id
)];}
156 const locale::facet
* use_facet(long id
) const;
160 static __no_destroy
<__imp
> classic_locale_imp_
;
163 void install(facet
* f
, long id
);
164 template <class F
> void install(F
* f
) {install(f
, f
->id
.__get());}
165 template <class F
> void install_from(const __imp
& other
);
168 locale::__imp::__imp(size_t refs
)
174 install(&make
<std::collate
<char> >(1u));
175 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
176 install(&make
<std::collate
<wchar_t> >(1u));
178 install(&make
<std::ctype
<char> >(nullptr, false, 1u));
179 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
180 install(&make
<std::ctype
<wchar_t> >(1u));
182 install(&make
<codecvt
<char, char, mbstate_t> >(1u));
183 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
184 install(&make
<codecvt
<wchar_t, char, mbstate_t> >(1u));
186 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
187 install(&make
<codecvt
<char16_t
, char, mbstate_t> >(1u));
188 install(&make
<codecvt
<char32_t
, char, mbstate_t> >(1u));
189 _LIBCPP_SUPPRESS_DEPRECATED_POP
190 #ifndef _LIBCPP_HAS_NO_CHAR8_T
191 install(&make
<codecvt
<char16_t
, char8_t
, mbstate_t> >(1u));
192 install(&make
<codecvt
<char32_t
, char8_t
, mbstate_t> >(1u));
194 install(&make
<numpunct
<char> >(1u));
195 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
196 install(&make
<numpunct
<wchar_t> >(1u));
198 install(&make
<num_get
<char> >(1u));
199 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
200 install(&make
<num_get
<wchar_t> >(1u));
202 install(&make
<num_put
<char> >(1u));
203 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
204 install(&make
<num_put
<wchar_t> >(1u));
206 install(&make
<moneypunct
<char, false> >(1u));
207 install(&make
<moneypunct
<char, true> >(1u));
208 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
209 install(&make
<moneypunct
<wchar_t, false> >(1u));
210 install(&make
<moneypunct
<wchar_t, true> >(1u));
212 install(&make
<money_get
<char> >(1u));
213 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
214 install(&make
<money_get
<wchar_t> >(1u));
216 install(&make
<money_put
<char> >(1u));
217 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
218 install(&make
<money_put
<wchar_t> >(1u));
220 install(&make
<time_get
<char> >(1u));
221 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
222 install(&make
<time_get
<wchar_t> >(1u));
224 install(&make
<time_put
<char> >(1u));
225 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
226 install(&make
<time_put
<wchar_t> >(1u));
228 install(&make
<std::messages
<char> >(1u));
229 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
230 install(&make
<std::messages
<wchar_t> >(1u));
234 locale::__imp::__imp(const string
& name
, size_t refs
)
239 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
242 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
243 facets_
= locale::classic().__locale_
->facets_
;
244 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
246 facets_
[i
]->__add_shared();
247 install(new collate_byname
<char>(name_
));
248 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
249 install(new collate_byname
<wchar_t>(name_
));
251 install(new ctype_byname
<char>(name_
));
252 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
253 install(new ctype_byname
<wchar_t>(name_
));
255 install(new codecvt_byname
<char, char, mbstate_t>(name_
));
256 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
257 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name_
));
259 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
260 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name_
));
261 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name_
));
262 _LIBCPP_SUPPRESS_DEPRECATED_POP
263 #ifndef _LIBCPP_HAS_NO_CHAR8_T
264 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name_
));
265 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name_
));
267 install(new numpunct_byname
<char>(name_
));
268 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
269 install(new numpunct_byname
<wchar_t>(name_
));
271 install(new moneypunct_byname
<char, false>(name_
));
272 install(new moneypunct_byname
<char, true>(name_
));
273 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
274 install(new moneypunct_byname
<wchar_t, false>(name_
));
275 install(new moneypunct_byname
<wchar_t, true>(name_
));
277 install(new time_get_byname
<char>(name_
));
278 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
279 install(new time_get_byname
<wchar_t>(name_
));
281 install(new time_put_byname
<char>(name_
));
282 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
283 install(new time_put_byname
<wchar_t>(name_
));
285 install(new messages_byname
<char>(name_
));
286 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
287 install(new messages_byname
<wchar_t>(name_
));
289 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
293 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
295 facets_
[i
]->__release_shared();
298 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
301 locale::__imp::__imp(const __imp
& other
)
302 : facets_(max
<size_t>(N
, other
.facets_
.size())),
305 facets_
= other
.facets_
;
306 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
308 facets_
[i
]->__add_shared();
311 locale::__imp::__imp(const __imp
& other
, const string
& name
, locale::category c
)
312 : facets_(N
), name_(build_name(other
.name_
, name
, c
))
314 facets_
= other
.facets_
;
315 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
317 facets_
[i
]->__add_shared();
318 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
321 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
322 if (c
& locale::collate
)
324 install(new collate_byname
<char>(name
));
325 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
326 install(new collate_byname
<wchar_t>(name
));
329 if (c
& locale::ctype
)
331 install(new ctype_byname
<char>(name
));
332 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
333 install(new ctype_byname
<wchar_t>(name
));
335 install(new codecvt_byname
<char, char, mbstate_t>(name
));
336 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
337 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name
));
339 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
340 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name
));
341 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name
));
342 _LIBCPP_SUPPRESS_DEPRECATED_POP
343 #ifndef _LIBCPP_HAS_NO_CHAR8_T
344 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name
));
345 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name
));
348 if (c
& locale::monetary
)
350 install(new moneypunct_byname
<char, false>(name
));
351 install(new moneypunct_byname
<char, true>(name
));
352 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
353 install(new moneypunct_byname
<wchar_t, false>(name
));
354 install(new moneypunct_byname
<wchar_t, true>(name
));
357 if (c
& locale::numeric
)
359 install(new numpunct_byname
<char>(name
));
360 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
361 install(new numpunct_byname
<wchar_t>(name
));
364 if (c
& locale::time
)
366 install(new time_get_byname
<char>(name
));
367 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
368 install(new time_get_byname
<wchar_t>(name
));
370 install(new time_put_byname
<char>(name
));
371 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
372 install(new time_put_byname
<wchar_t>(name
));
375 if (c
& locale::messages
)
377 install(new messages_byname
<char>(name
));
378 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
379 install(new messages_byname
<wchar_t>(name
));
382 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
386 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
388 facets_
[i
]->__release_shared();
391 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
397 locale::__imp::install_from(const locale::__imp
& one
)
399 long id
= F::id
.__get();
400 install(const_cast<F
*>(static_cast<const F
*>(one
.use_facet(id
))), id
);
403 locale::__imp::__imp(const __imp
& other
, const __imp
& one
, locale::category c
)
404 : facets_(N
), name_(build_name(other
.name_
, one
.name_
, c
))
406 facets_
= other
.facets_
;
407 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
409 facets_
[i
]->__add_shared();
410 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
413 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
414 if (c
& locale::collate
)
416 install_from
<std::collate
<char> >(one
);
417 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
418 install_from
<std::collate
<wchar_t> >(one
);
421 if (c
& locale::ctype
)
423 install_from
<std::ctype
<char> >(one
);
424 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
425 install_from
<std::ctype
<wchar_t> >(one
);
427 install_from
<std::codecvt
<char, char, mbstate_t> >(one
);
428 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
429 install_from
<std::codecvt
<char16_t
, char, mbstate_t> >(one
);
430 install_from
<std::codecvt
<char32_t
, char, mbstate_t> >(one
);
431 _LIBCPP_SUPPRESS_DEPRECATED_POP
432 #ifndef _LIBCPP_HAS_NO_CHAR8_T
433 install_from
<std::codecvt
<char16_t
, char8_t
, mbstate_t> >(one
);
434 install_from
<std::codecvt
<char32_t
, char8_t
, mbstate_t> >(one
);
436 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
437 install_from
<std::codecvt
<wchar_t, char, mbstate_t> >(one
);
440 if (c
& locale::monetary
)
442 install_from
<moneypunct
<char, false> >(one
);
443 install_from
<moneypunct
<char, true> >(one
);
444 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
445 install_from
<moneypunct
<wchar_t, false> >(one
);
446 install_from
<moneypunct
<wchar_t, true> >(one
);
448 install_from
<money_get
<char> >(one
);
449 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
450 install_from
<money_get
<wchar_t> >(one
);
452 install_from
<money_put
<char> >(one
);
453 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
454 install_from
<money_put
<wchar_t> >(one
);
457 if (c
& locale::numeric
)
459 install_from
<numpunct
<char> >(one
);
460 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461 install_from
<numpunct
<wchar_t> >(one
);
463 install_from
<num_get
<char> >(one
);
464 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
465 install_from
<num_get
<wchar_t> >(one
);
467 install_from
<num_put
<char> >(one
);
468 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
469 install_from
<num_put
<wchar_t> >(one
);
472 if (c
& locale::time
)
474 install_from
<time_get
<char> >(one
);
475 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
476 install_from
<time_get
<wchar_t> >(one
);
478 install_from
<time_put
<char> >(one
);
479 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
480 install_from
<time_put
<wchar_t> >(one
);
483 if (c
& locale::messages
)
485 install_from
<std::messages
<char> >(one
);
486 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
487 install_from
<std::messages
<wchar_t> >(one
);
490 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
494 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
496 facets_
[i
]->__release_shared();
499 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
502 locale::__imp::__imp(const __imp
& other
, facet
* f
, long id
)
503 : facets_(max
<size_t>(N
, other
.facets_
.size()+1)),
507 unique_ptr
<facet
, releaser
> hold(f
);
508 facets_
= other
.facets_
;
509 for (unsigned i
= 0; i
< other
.facets_
.size(); ++i
)
511 facets_
[i
]->__add_shared();
512 install(hold
.get(), id
);
515 locale::__imp::~__imp()
517 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
519 facets_
[i
]->__release_shared();
523 locale::__imp::install(facet
* f
, long id
)
526 unique_ptr
<facet
, releaser
> hold(f
);
527 if (static_cast<size_t>(id
) >= facets_
.size())
528 facets_
.resize(static_cast<size_t>(id
+1));
529 if (facets_
[static_cast<size_t>(id
)])
530 facets_
[static_cast<size_t>(id
)]->__release_shared();
531 facets_
[static_cast<size_t>(id
)] = hold
.release();
535 locale::__imp::use_facet(long id
) const
539 return facets_
[static_cast<size_t>(id
)];
544 // We don't do reference counting on the classic locale.
545 // It's never destroyed anyway, but atomic reference counting may be very
546 // expensive in parallel applications. The classic locale is used by default
547 // in all streams. Note: if a new global locale is installed, then we lose
548 // the benefit of no reference counting.
549 constinit __no_destroy
<locale::__imp
>
550 locale::__imp::classic_locale_imp_(__uninitialized_tag
{}); // initialized below in classic()
552 const locale
& locale::classic() {
553 static const __no_destroy
<locale
> classic_locale(__private_tag
{}, [] {
554 // executed exactly once on first initialization of `classic_locale`
555 locale::__imp::classic_locale_imp_
.__emplace(1u);
556 return &locale::__imp::classic_locale_imp_
.__get();
558 return classic_locale
.__get();
561 locale
& locale::__global() {
562 static __no_destroy
<locale
> g(locale::classic());
566 void locale::__imp::acquire() {
567 if (this != &locale::__imp::classic_locale_imp_
.__get())
571 void locale::__imp::release() {
572 if (this != &locale::__imp::classic_locale_imp_
.__get())
576 locale::locale() noexcept
: __locale_(__global().__locale_
) { __locale_
->acquire(); }
578 locale::locale(const locale
& l
) noexcept
: __locale_(l
.__locale_
) { __locale_
->acquire(); }
580 locale::~locale() { __locale_
->release(); }
583 locale::operator=(const locale
& other
) noexcept
585 other
.__locale_
->acquire();
586 __locale_
->release();
587 __locale_
= other
.__locale_
;
591 locale::locale(const char* name
)
592 : __locale_(name
? new __imp(name
)
593 : (__throw_runtime_error("locale constructed with null"), nullptr))
595 __locale_
->acquire();
598 locale::locale(const string
& name
) : __locale_(new __imp(name
)) { __locale_
->acquire(); }
600 locale::locale(const locale
& other
, const char* name
, category c
)
601 : __locale_(name
? new __imp(*other
.__locale_
, name
, c
)
602 : (__throw_runtime_error("locale constructed with null"), nullptr))
604 __locale_
->acquire();
607 locale::locale(const locale
& other
, const string
& name
, category c
)
608 : __locale_(new __imp(*other
.__locale_
, name
, c
))
610 __locale_
->acquire();
613 locale::locale(const locale
& other
, const locale
& one
, category c
)
614 : __locale_(new __imp(*other
.__locale_
, *one
.__locale_
, c
))
616 __locale_
->acquire();
622 return __locale_
->name();
626 locale::__install_ctor(const locale
& other
, facet
* f
, long id
)
629 __locale_
= new __imp(*other
.__locale_
, f
, id
);
631 __locale_
= other
.__locale_
;
632 __locale_
->acquire();
636 locale::global(const locale
& loc
)
638 locale
& g
= __global();
642 setlocale(LC_ALL
, g
.name().c_str());
647 locale::has_facet(id
& x
) const
649 return __locale_
->has_facet(x
.__get());
653 locale::use_facet(id
& x
) const
655 return __locale_
->use_facet(x
.__get());
659 locale::operator==(const locale
& y
) const
661 return (__locale_
== y
.__locale_
)
662 || (__locale_
->name() != "*" && __locale_
->name() == y
.__locale_
->name());
667 locale::facet::~facet()
672 locale::facet::__on_zero_shared() noexcept
679 constinit
int32_t locale::id::__next_id
= 0;
681 long locale::id::__get() {
682 call_once(__flag_
, [&] { __id_
= __libcpp_atomic_add(&__next_id
, 1); });
686 // template <> class collate_byname<char>
688 collate_byname
<char>::collate_byname(const char* n
, size_t refs
)
689 : collate
<char>(refs
),
690 __l_(newlocale(LC_ALL_MASK
, n
, 0))
693 __throw_runtime_error(("collate_byname<char>::collate_byname"
694 " failed to construct for " + string(n
)).c_str());
697 collate_byname
<char>::collate_byname(const string
& name
, size_t refs
)
698 : collate
<char>(refs
),
699 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
702 __throw_runtime_error(("collate_byname<char>::collate_byname"
703 " failed to construct for " + name
).c_str());
706 collate_byname
<char>::~collate_byname()
712 collate_byname
<char>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
713 const char_type
* __lo2
, const char_type
* __hi2
) const
715 string_type
lhs(__lo1
, __hi1
);
716 string_type
rhs(__lo2
, __hi2
);
717 int r
= strcoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
725 collate_byname
<char>::string_type
726 collate_byname
<char>::do_transform(const char_type
* lo
, const char_type
* hi
) const
728 const string_type
in(lo
, hi
);
729 string_type
out(strxfrm_l(0, in
.c_str(), 0, __l_
), char());
730 strxfrm_l(const_cast<char*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
734 // template <> class collate_byname<wchar_t>
736 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
737 collate_byname
<wchar_t>::collate_byname(const char* n
, size_t refs
)
738 : collate
<wchar_t>(refs
),
739 __l_(newlocale(LC_ALL_MASK
, n
, 0))
742 __throw_runtime_error(("collate_byname<wchar_t>::collate_byname(size_t refs)"
743 " failed to construct for " + string(n
)).c_str());
746 collate_byname
<wchar_t>::collate_byname(const string
& name
, size_t refs
)
747 : collate
<wchar_t>(refs
),
748 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
751 __throw_runtime_error(("collate_byname<wchar_t>::collate_byname(size_t refs)"
752 " failed to construct for " + name
).c_str());
755 collate_byname
<wchar_t>::~collate_byname()
761 collate_byname
<wchar_t>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
762 const char_type
* __lo2
, const char_type
* __hi2
) const
764 string_type
lhs(__lo1
, __hi1
);
765 string_type
rhs(__lo2
, __hi2
);
766 int r
= wcscoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
774 collate_byname
<wchar_t>::string_type
775 collate_byname
<wchar_t>::do_transform(const char_type
* lo
, const char_type
* hi
) const
777 const string_type
in(lo
, hi
);
778 string_type
out(wcsxfrm_l(0, in
.c_str(), 0, __l_
), wchar_t());
779 wcsxfrm_l(const_cast<wchar_t*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
782 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
784 const ctype_base::mask
ctype_base::space
;
785 const ctype_base::mask
ctype_base::print
;
786 const ctype_base::mask
ctype_base::cntrl
;
787 const ctype_base::mask
ctype_base::upper
;
788 const ctype_base::mask
ctype_base::lower
;
789 const ctype_base::mask
ctype_base::alpha
;
790 const ctype_base::mask
ctype_base::digit
;
791 const ctype_base::mask
ctype_base::punct
;
792 const ctype_base::mask
ctype_base::xdigit
;
793 const ctype_base::mask
ctype_base::blank
;
794 const ctype_base::mask
ctype_base::alnum
;
795 const ctype_base::mask
ctype_base::graph
;
797 // template <> class ctype<wchar_t>;
799 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
800 constinit
locale::id ctype
<wchar_t>::id
;
802 ctype
<wchar_t>::~ctype()
807 ctype
<wchar_t>::do_is(mask m
, char_type c
) const
809 return isascii(c
) ? (ctype
<char>::classic_table()[c
] & m
) != 0 : false;
813 ctype
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
815 for (; low
!= high
; ++low
, ++vec
)
816 *vec
= static_cast<mask
>(isascii(*low
) ?
817 ctype
<char>::classic_table()[*low
] : 0);
822 ctype
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
824 for (; low
!= high
; ++low
)
825 if (isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
))
831 ctype
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
833 for (; low
!= high
; ++low
)
834 if (!(isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
)))
840 ctype
<wchar_t>::do_toupper(char_type c
) const
842 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
843 return isascii(c
) ? _DefaultRuneLocale
.__mapupper
[c
] : c
;
844 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
845 defined(__NetBSD__) || defined(__MVS__)
846 return isascii(c
) ? ctype
<char>::__classic_upper_table()[c
] : c
;
848 return (isascii(c
) && iswlower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'a'+L
'A' : c
;
853 ctype
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
855 for (; low
!= high
; ++low
)
856 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
857 *low
= isascii(*low
) ? _DefaultRuneLocale
.__mapupper
[*low
] : *low
;
858 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
859 defined(__NetBSD__) || defined(__MVS__)
860 *low
= isascii(*low
) ? ctype
<char>::__classic_upper_table()[*low
]
863 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? (*low
-L
'a'+L
'A') : *low
;
869 ctype
<wchar_t>::do_tolower(char_type c
) const
871 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
872 return isascii(c
) ? _DefaultRuneLocale
.__maplower
[c
] : c
;
873 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
874 defined(__NetBSD__) || defined(__MVS__)
875 return isascii(c
) ? ctype
<char>::__classic_lower_table()[c
] : c
;
877 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'A'+'a' : c
;
882 ctype
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
884 for (; low
!= high
; ++low
)
885 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
886 *low
= isascii(*low
) ? _DefaultRuneLocale
.__maplower
[*low
] : *low
;
887 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
888 defined(__NetBSD__) || defined(__MVS__)
889 *low
= isascii(*low
) ? ctype
<char>::__classic_lower_table()[*low
]
892 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-L
'A'+L
'a' : *low
;
898 ctype
<wchar_t>::do_widen(char c
) const
904 ctype
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
906 for (; low
!= high
; ++low
, ++dest
)
912 ctype
<wchar_t>::do_narrow(char_type c
, char dfault
) const
915 return static_cast<char>(c
);
920 ctype
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
922 for (; low
!= high
; ++low
, ++dest
)
924 *dest
= static_cast<char>(*low
);
929 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
931 // template <> class ctype<char>;
933 constinit
locale::id ctype
<char>::id
;
935 const size_t ctype
<char>::table_size
;
937 ctype
<char>::ctype(const mask
* tab
, bool del
, size_t refs
)
938 : locale::facet(refs
),
943 __tab_
= classic_table();
946 ctype
<char>::~ctype()
948 if (__tab_
&& __del_
)
953 ctype
<char>::do_toupper(char_type c
) const
955 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
957 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(c
)]) : c
;
958 #elif defined(__NetBSD__)
959 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]);
960 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
962 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]) : c
;
964 return (isascii(c
) && islower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'a'+'A' : c
;
969 ctype
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
971 for (; low
!= high
; ++low
)
972 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
973 *low
= isascii(*low
) ?
974 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(*low
)]) : *low
;
975 #elif defined(__NetBSD__)
976 *low
= static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low
)]);
977 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
978 *low
= isascii(*low
) ?
979 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low
)]) : *low
;
981 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'a'+'A' : *low
;
987 ctype
<char>::do_tolower(char_type c
) const
989 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
991 static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(c
)]) : c
;
992 #elif defined(__NetBSD__)
993 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c
)]);
994 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
996 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c
)]) : c
;
998 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'A'+'a' : c
;
1003 ctype
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1005 for (; low
!= high
; ++low
)
1006 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1007 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(*low
)]) : *low
;
1008 #elif defined(__NetBSD__)
1009 *low
= static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low
)]);
1010 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1011 *low
= isascii(*low
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low
)]) : *low
;
1013 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'A'+'a' : *low
;
1019 ctype
<char>::do_widen(char c
) const
1025 ctype
<char>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1027 for (; low
!= high
; ++low
, ++dest
)
1033 ctype
<char>::do_narrow(char_type c
, char dfault
) const
1036 return static_cast<char>(c
);
1041 ctype
<char>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1043 for (; low
!= high
; ++low
, ++dest
)
1051 #if defined(__EMSCRIPTEN__)
1052 extern "C" const unsigned short ** __ctype_b_loc();
1053 extern "C" const int ** __ctype_tolower_loc();
1054 extern "C" const int ** __ctype_toupper_loc();
1057 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1058 const ctype
<char>::mask
*
1059 ctype
<char>::classic_table() noexcept
1062 static constexpr const ctype
<char>::mask builtin_table
[table_size
] = {
1067 cntrl
, cntrl
| space
| blank
,
1068 cntrl
| space
, cntrl
| space
,
1069 cntrl
| space
, cntrl
| space
,
1079 space
| blank
| print
, punct
| print
,
1080 punct
| print
, punct
| print
,
1081 punct
| print
, punct
| print
,
1082 punct
| print
, punct
| print
,
1083 punct
| print
, punct
| print
,
1084 punct
| print
, punct
| print
,
1085 punct
| print
, punct
| print
,
1086 punct
| print
, punct
| print
,
1087 digit
| print
| xdigit
, digit
| print
| xdigit
,
1088 digit
| print
| xdigit
, digit
| print
| xdigit
,
1089 digit
| print
| xdigit
, digit
| print
| xdigit
,
1090 digit
| print
| xdigit
, digit
| print
| xdigit
,
1091 digit
| print
| xdigit
, digit
| print
| xdigit
,
1092 punct
| print
, punct
| print
,
1093 punct
| print
, punct
| print
,
1094 punct
| print
, punct
| print
,
1095 punct
| print
, upper
| xdigit
| print
| alpha
,
1096 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1097 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1098 upper
| xdigit
| print
| alpha
, upper
| print
| alpha
,
1099 upper
| print
| alpha
, upper
| print
| alpha
,
1100 upper
| print
| alpha
, upper
| print
| alpha
,
1101 upper
| print
| alpha
, upper
| print
| alpha
,
1102 upper
| print
| alpha
, upper
| print
| alpha
,
1103 upper
| print
| alpha
, upper
| print
| alpha
,
1104 upper
| print
| alpha
, upper
| print
| alpha
,
1105 upper
| print
| alpha
, upper
| print
| alpha
,
1106 upper
| print
| alpha
, upper
| print
| alpha
,
1107 upper
| print
| alpha
, upper
| print
| alpha
,
1108 upper
| print
| alpha
, punct
| print
,
1109 punct
| print
, punct
| print
,
1110 punct
| print
, punct
| print
,
1111 punct
| print
, lower
| xdigit
| print
| alpha
,
1112 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1113 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1114 lower
| xdigit
| print
| alpha
, lower
| print
| alpha
,
1115 lower
| print
| alpha
, lower
| print
| alpha
,
1116 lower
| print
| alpha
, lower
| print
| alpha
,
1117 lower
| print
| alpha
, lower
| print
| alpha
,
1118 lower
| print
| alpha
, lower
| print
| alpha
,
1119 lower
| print
| alpha
, lower
| print
| alpha
,
1120 lower
| print
| alpha
, lower
| print
| alpha
,
1121 lower
| print
| alpha
, lower
| print
| alpha
,
1122 lower
| print
| alpha
, lower
| print
| alpha
,
1123 lower
| print
| alpha
, lower
| print
| alpha
,
1124 lower
| print
| alpha
, punct
| print
,
1125 punct
| print
, punct
| print
,
1126 punct
| print
, cntrl
,
1127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1137 return builtin_table
;
1140 const ctype
<char>::mask
*
1141 ctype
<char>::classic_table() noexcept
1143 #if defined(__APPLE__) || defined(__FreeBSD__)
1144 return _DefaultRuneLocale
.__runetype
;
1145 #elif defined(__NetBSD__)
1146 return _C_ctype_tab_
+ 1;
1147 #elif defined(__GLIBC__)
1148 return _LIBCPP_GET_C_LOCALE
->__ctype_b
;
1149 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1150 return __pctype_func();
1151 #elif defined(__EMSCRIPTEN__)
1152 return *__ctype_b_loc();
1153 #elif defined(_NEWLIB_VERSION)
1154 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1157 return (const unsigned int *)__lc_ctype_ptr
->obj
->mask
;
1158 #elif defined(__MVS__)
1159 # if defined(__NATIVE_ASCII_F)
1160 return const_cast<const ctype
<char>::mask
*> (__OBJ_DATA(__lc_ctype_a
)->mask
);
1162 return const_cast<const ctype
<char>::mask
*> (__ctypec
);
1165 // Platform not supported: abort so the person doing the port knows what to
1167 # warning ctype<char>::classic_table() is not implemented
1168 printf("ctype<char>::classic_table() is not implemented\n");
1175 #if defined(__GLIBC__)
1177 ctype
<char>::__classic_lower_table() noexcept
1179 return _LIBCPP_GET_C_LOCALE
->__ctype_tolower
;
1183 ctype
<char>::__classic_upper_table() noexcept
1185 return _LIBCPP_GET_C_LOCALE
->__ctype_toupper
;
1187 #elif defined(__NetBSD__)
1189 ctype
<char>::__classic_lower_table() noexcept
1191 return _C_tolower_tab_
+ 1;
1195 ctype
<char>::__classic_upper_table() noexcept
1197 return _C_toupper_tab_
+ 1;
1200 #elif defined(__EMSCRIPTEN__)
1202 ctype
<char>::__classic_lower_table() noexcept
1204 return *__ctype_tolower_loc();
1208 ctype
<char>::__classic_upper_table() noexcept
1210 return *__ctype_toupper_loc();
1212 #elif defined(__MVS__)
1213 const unsigned short*
1214 ctype
<char>::__classic_lower_table() _NOEXCEPT
1216 # if defined(__NATIVE_ASCII_F)
1217 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->lower
);
1219 return const_cast<const unsigned short*>(__ctype
+ __TOLOWER_INDEX
);
1222 const unsigned short *
1223 ctype
<char>::__classic_upper_table() _NOEXCEPT
1225 # if defined(__NATIVE_ASCII_F)
1226 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->upper
);
1228 return const_cast<const unsigned short*>(__ctype
+ __TOUPPER_INDEX
);
1231 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1233 // template <> class ctype_byname<char>
1235 ctype_byname
<char>::ctype_byname(const char* name
, size_t refs
)
1236 : ctype
<char>(0, false, refs
),
1237 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1240 __throw_runtime_error(("ctype_byname<char>::ctype_byname"
1241 " failed to construct for " + string(name
)).c_str());
1244 ctype_byname
<char>::ctype_byname(const string
& name
, size_t refs
)
1245 : ctype
<char>(0, false, refs
),
1246 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1249 __throw_runtime_error(("ctype_byname<char>::ctype_byname"
1250 " failed to construct for " + name
).c_str());
1253 ctype_byname
<char>::~ctype_byname()
1259 ctype_byname
<char>::do_toupper(char_type c
) const
1261 return static_cast<char>(toupper_l(static_cast<unsigned char>(c
), __l_
));
1265 ctype_byname
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
1267 for (; low
!= high
; ++low
)
1268 *low
= static_cast<char>(toupper_l(static_cast<unsigned char>(*low
), __l_
));
1273 ctype_byname
<char>::do_tolower(char_type c
) const
1275 return static_cast<char>(tolower_l(static_cast<unsigned char>(c
), __l_
));
1279 ctype_byname
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1281 for (; low
!= high
; ++low
)
1282 *low
= static_cast<char>(tolower_l(static_cast<unsigned char>(*low
), __l_
));
1286 // template <> class ctype_byname<wchar_t>
1288 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1289 ctype_byname
<wchar_t>::ctype_byname(const char* name
, size_t refs
)
1290 : ctype
<wchar_t>(refs
),
1291 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1294 __throw_runtime_error(("ctype_byname<wchar_t>::ctype_byname"
1295 " failed to construct for " + string(name
)).c_str());
1298 ctype_byname
<wchar_t>::ctype_byname(const string
& name
, size_t refs
)
1299 : ctype
<wchar_t>(refs
),
1300 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1303 __throw_runtime_error(("ctype_byname<wchar_t>::ctype_byname"
1304 " failed to construct for " + name
).c_str());
1307 ctype_byname
<wchar_t>::~ctype_byname()
1313 ctype_byname
<wchar_t>::do_is(mask m
, char_type c
) const
1315 #ifdef _LIBCPP_WCTYPE_IS_MASK
1316 return static_cast<bool>(iswctype_l(c
, m
, __l_
));
1318 bool result
= false;
1319 wint_t ch
= static_cast<wint_t>(c
);
1320 if ((m
& space
) == space
) result
|= (iswspace_l(ch
, __l_
) != 0);
1321 if ((m
& print
) == print
) result
|= (iswprint_l(ch
, __l_
) != 0);
1322 if ((m
& cntrl
) == cntrl
) result
|= (iswcntrl_l(ch
, __l_
) != 0);
1323 if ((m
& upper
) == upper
) result
|= (iswupper_l(ch
, __l_
) != 0);
1324 if ((m
& lower
) == lower
) result
|= (iswlower_l(ch
, __l_
) != 0);
1325 if ((m
& alpha
) == alpha
) result
|= (iswalpha_l(ch
, __l_
) != 0);
1326 if ((m
& digit
) == digit
) result
|= (iswdigit_l(ch
, __l_
) != 0);
1327 if ((m
& punct
) == punct
) result
|= (iswpunct_l(ch
, __l_
) != 0);
1328 if ((m
& xdigit
) == xdigit
) result
|= (iswxdigit_l(ch
, __l_
) != 0);
1329 if ((m
& blank
) == blank
) result
|= (iswblank_l(ch
, __l_
) != 0);
1335 ctype_byname
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
1337 for (; low
!= high
; ++low
, ++vec
)
1340 *vec
= static_cast<mask
>(ctype
<char>::classic_table()[*low
]);
1344 wint_t ch
= static_cast<wint_t>(*low
);
1345 if (iswspace_l(ch
, __l_
))
1347 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1348 if (iswprint_l(ch
, __l_
))
1351 if (iswcntrl_l(ch
, __l_
))
1353 if (iswupper_l(ch
, __l_
))
1355 if (iswlower_l(ch
, __l_
))
1357 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1358 if (iswalpha_l(ch
, __l_
))
1361 if (iswdigit_l(ch
, __l_
))
1363 if (iswpunct_l(ch
, __l_
))
1365 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1366 if (iswxdigit_l(ch
, __l_
))
1369 if (iswblank_l(ch
, __l_
))
1377 ctype_byname
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
1379 for (; low
!= high
; ++low
)
1381 #ifdef _LIBCPP_WCTYPE_IS_MASK
1382 if (iswctype_l(*low
, m
, __l_
))
1385 wint_t ch
= static_cast<wint_t>(*low
);
1386 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) break;
1387 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) break;
1388 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) break;
1389 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) break;
1390 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) break;
1391 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) break;
1392 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) break;
1393 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) break;
1394 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) break;
1395 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) break;
1402 ctype_byname
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
1404 for (; low
!= high
; ++low
)
1406 #ifdef _LIBCPP_WCTYPE_IS_MASK
1407 if (!iswctype_l(*low
, m
, __l_
))
1410 wint_t ch
= static_cast<wint_t>(*low
);
1411 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) continue;
1412 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) continue;
1413 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) continue;
1414 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) continue;
1415 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) continue;
1416 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) continue;
1417 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) continue;
1418 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) continue;
1419 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) continue;
1420 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) continue;
1428 ctype_byname
<wchar_t>::do_toupper(char_type c
) const
1430 return towupper_l(c
, __l_
);
1434 ctype_byname
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
1436 for (; low
!= high
; ++low
)
1437 *low
= towupper_l(*low
, __l_
);
1442 ctype_byname
<wchar_t>::do_tolower(char_type c
) const
1444 return towlower_l(c
, __l_
);
1448 ctype_byname
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
1450 for (; low
!= high
; ++low
)
1451 *low
= towlower_l(*low
, __l_
);
1456 ctype_byname
<wchar_t>::do_widen(char c
) const
1458 return __libcpp_btowc_l(c
, __l_
);
1462 ctype_byname
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1464 for (; low
!= high
; ++low
, ++dest
)
1465 *dest
= __libcpp_btowc_l(*low
, __l_
);
1470 ctype_byname
<wchar_t>::do_narrow(char_type c
, char dfault
) const
1472 int r
= __libcpp_wctob_l(c
, __l_
);
1473 return (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1477 ctype_byname
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1479 for (; low
!= high
; ++low
, ++dest
)
1481 int r
= __libcpp_wctob_l(*low
, __l_
);
1482 *dest
= (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1486 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1488 // template <> class codecvt<char, char, mbstate_t>
1490 constinit
locale::id codecvt
<char, char, mbstate_t>::id
;
1492 codecvt
<char, char, mbstate_t>::~codecvt()
1496 codecvt
<char, char, mbstate_t>::result
1497 codecvt
<char, char, mbstate_t>::do_out(state_type
&,
1498 const intern_type
* frm
, const intern_type
*, const intern_type
*& frm_nxt
,
1499 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1506 codecvt
<char, char, mbstate_t>::result
1507 codecvt
<char, char, mbstate_t>::do_in(state_type
&,
1508 const extern_type
* frm
, const extern_type
*, const extern_type
*& frm_nxt
,
1509 intern_type
* to
, intern_type
*, intern_type
*& to_nxt
) const
1516 codecvt
<char, char, mbstate_t>::result
1517 codecvt
<char, char, mbstate_t>::do_unshift(state_type
&,
1518 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1525 codecvt
<char, char, mbstate_t>::do_encoding() const noexcept
1531 codecvt
<char, char, mbstate_t>::do_always_noconv() const noexcept
1537 codecvt
<char, char, mbstate_t>::do_length(state_type
&,
1538 const extern_type
* frm
, const extern_type
* end
, size_t mx
) const
1540 return static_cast<int>(min
<size_t>(mx
, static_cast<size_t>(end
-frm
)));
1544 codecvt
<char, char, mbstate_t>::do_max_length() const noexcept
1549 // template <> class codecvt<wchar_t, char, mbstate_t>
1551 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1552 constinit
locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
1554 codecvt
<wchar_t, char, mbstate_t>::codecvt(size_t refs
)
1555 : locale::facet(refs
),
1556 __l_(_LIBCPP_GET_C_LOCALE
)
1560 codecvt
<wchar_t, char, mbstate_t>::codecvt(const char* nm
, size_t refs
)
1561 : locale::facet(refs
),
1562 __l_(newlocale(LC_ALL_MASK
, nm
, 0))
1565 __throw_runtime_error(("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1566 " failed to construct for " + string(nm
)).c_str());
1569 codecvt
<wchar_t, char, mbstate_t>::~codecvt()
1571 if (__l_
!= _LIBCPP_GET_C_LOCALE
)
1575 codecvt
<wchar_t, char, mbstate_t>::result
1576 codecvt
<wchar_t, char, mbstate_t>::do_out(state_type
& st
,
1577 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
1578 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1580 // look for first internal null in frm
1581 const intern_type
* fend
= frm
;
1582 for (; fend
!= frm_end
; ++fend
)
1585 // loop over all null-terminated sequences in frm
1587 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1589 // save state in case it is needed to recover to_nxt on error
1590 mbstate_t save_state
= st
;
1591 size_t n
= __libcpp_wcsnrtombs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1592 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1593 if (n
== size_t(-1))
1595 // need to recover to_nxt
1596 for (to_nxt
= to
; frm
!= frm_nxt
; ++frm
)
1598 n
= __libcpp_wcrtomb_l(to_nxt
, *frm
, &save_state
, __l_
);
1599 if (n
== size_t(-1))
1609 if (to_nxt
== to_end
)
1611 if (fend
!= frm_end
) // set up next null terminated sequence
1613 // Try to write the terminating null
1614 extern_type tmp
[MB_LEN_MAX
];
1615 n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1616 if (n
== size_t(-1)) // on error
1618 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1620 for (extern_type
* p
= tmp
; n
; --n
) // write it
1623 // look for next null in frm
1624 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1629 return frm_nxt
== frm_end
? ok
: partial
;
1632 codecvt
<wchar_t, char, mbstate_t>::result
1633 codecvt
<wchar_t, char, mbstate_t>::do_in(state_type
& st
,
1634 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
1635 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
1637 // look for first internal null in frm
1638 const extern_type
* fend
= frm
;
1639 for (; fend
!= frm_end
; ++fend
)
1642 // loop over all null-terminated sequences in frm
1644 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1646 // save state in case it is needed to recover to_nxt on error
1647 mbstate_t save_state
= st
;
1648 size_t n
= __libcpp_mbsnrtowcs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1649 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1650 if (n
== size_t(-1))
1652 // need to recover to_nxt
1653 for (to_nxt
= to
; frm
!= frm_nxt
; ++to_nxt
)
1655 n
= __libcpp_mbrtowc_l(to_nxt
, frm
, static_cast<size_t>(fend
-frm
),
1674 return frm_nxt
== frm_end
? ok
: partial
;
1676 if (n
== size_t(-1))
1679 if (to_nxt
== to_end
)
1681 if (fend
!= frm_end
) // set up next null terminated sequence
1683 // Try to write the terminating null
1684 n
= __libcpp_mbrtowc_l(to_nxt
, frm_nxt
, 1, &st
, __l_
);
1685 if (n
!= 0) // on error
1689 // look for next null in frm
1690 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1695 return frm_nxt
== frm_end
? ok
: partial
;
1698 codecvt
<wchar_t, char, mbstate_t>::result
1699 codecvt
<wchar_t, char, mbstate_t>::do_unshift(state_type
& st
,
1700 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1703 extern_type tmp
[MB_LEN_MAX
];
1704 size_t n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1705 if (n
== size_t(-1) || n
== 0) // on error
1708 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1710 for (extern_type
* p
= tmp
; n
; --n
) // write it
1716 codecvt
<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1718 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX
, __l_
) != 0)
1721 // stateless encoding
1722 if (__l_
== 0 || __libcpp_mb_cur_max_l(__l_
) == 1) // there are no known constant length encodings
1723 return 1; // which take more than 1 char to form a wchar_t
1728 codecvt
<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1734 codecvt
<wchar_t, char, mbstate_t>::do_length(state_type
& st
,
1735 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
1738 for (size_t nwchar_t
= 0; nwchar_t
< mx
&& frm
!= frm_end
; ++nwchar_t
)
1740 size_t n
= __libcpp_mbrlen_l(frm
, static_cast<size_t>(frm_end
-frm
), &st
, __l_
);
1760 codecvt
<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1762 return __l_
== 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_
));
1764 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1767 // UTF-32 UTF-16 UTF-8 # of code points
1768 // first second first second third fourth
1769 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1770 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1771 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1772 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1773 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1774 // 00D800 - 00DFFF invalid
1775 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1776 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1777 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1778 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1780 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1782 codecvt_base::result
1783 utf16_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
1784 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1785 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1789 if (mode
& generate_header
)
1791 if (to_end
-to_nxt
< 3)
1792 return codecvt_base::partial
;
1793 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1794 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1795 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1797 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1799 uint16_t wc1
= *frm_nxt
;
1801 return codecvt_base::error
;
1804 if (to_end
-to_nxt
< 1)
1805 return codecvt_base::partial
;
1806 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1808 else if (wc1
< 0x0800)
1810 if (to_end
-to_nxt
< 2)
1811 return codecvt_base::partial
;
1812 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1813 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1815 else if (wc1
< 0xD800)
1817 if (to_end
-to_nxt
< 3)
1818 return codecvt_base::partial
;
1819 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1820 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1821 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1823 else if (wc1
< 0xDC00)
1825 if (frm_end
-frm_nxt
< 2)
1826 return codecvt_base::partial
;
1827 uint16_t wc2
= frm_nxt
[1];
1828 if ((wc2
& 0xFC00) != 0xDC00)
1829 return codecvt_base::error
;
1830 if (to_end
-to_nxt
< 4)
1831 return codecvt_base::partial
;
1832 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1833 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1834 return codecvt_base::error
;
1836 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1837 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1838 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1839 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1840 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1842 else if (wc1
< 0xE000)
1844 return codecvt_base::error
;
1848 if (to_end
-to_nxt
< 3)
1849 return codecvt_base::partial
;
1850 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1851 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1852 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1855 return codecvt_base::ok
;
1859 codecvt_base::result
1860 utf16_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
1861 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1862 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1866 if (mode
& generate_header
)
1868 if (to_end
-to_nxt
< 3)
1869 return codecvt_base::partial
;
1870 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1871 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1872 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1874 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1876 uint16_t wc1
= static_cast<uint16_t>(*frm_nxt
);
1878 return codecvt_base::error
;
1881 if (to_end
-to_nxt
< 1)
1882 return codecvt_base::partial
;
1883 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1885 else if (wc1
< 0x0800)
1887 if (to_end
-to_nxt
< 2)
1888 return codecvt_base::partial
;
1889 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1890 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1892 else if (wc1
< 0xD800)
1894 if (to_end
-to_nxt
< 3)
1895 return codecvt_base::partial
;
1896 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1897 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1898 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1900 else if (wc1
< 0xDC00)
1902 if (frm_end
-frm_nxt
< 2)
1903 return codecvt_base::partial
;
1904 uint16_t wc2
= static_cast<uint16_t>(frm_nxt
[1]);
1905 if ((wc2
& 0xFC00) != 0xDC00)
1906 return codecvt_base::error
;
1907 if (to_end
-to_nxt
< 4)
1908 return codecvt_base::partial
;
1909 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1910 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1911 return codecvt_base::error
;
1913 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1914 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1915 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1916 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1917 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1919 else if (wc1
< 0xE000)
1921 return codecvt_base::error
;
1925 if (to_end
-to_nxt
< 3)
1926 return codecvt_base::partial
;
1927 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1928 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1929 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1932 return codecvt_base::ok
;
1936 codecvt_base::result
1937 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
1938 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
1939 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1943 if (mode
& consume_header
)
1945 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
1949 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
1951 uint8_t c1
= *frm_nxt
;
1953 return codecvt_base::error
;
1956 *to_nxt
= static_cast<uint16_t>(c1
);
1961 return codecvt_base::error
;
1965 if (frm_end
-frm_nxt
< 2)
1966 return codecvt_base::partial
;
1967 uint8_t c2
= frm_nxt
[1];
1968 if ((c2
& 0xC0) != 0x80)
1969 return codecvt_base::error
;
1970 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
1972 return codecvt_base::error
;
1978 if (frm_end
-frm_nxt
< 2)
1979 return codecvt_base::partial
;
1980 uint8_t c2
= frm_nxt
[1];
1984 if ((c2
& 0xE0) != 0xA0)
1985 return codecvt_base::error
;
1988 if ((c2
& 0xE0) != 0x80)
1989 return codecvt_base::error
;
1992 if ((c2
& 0xC0) != 0x80)
1993 return codecvt_base::error
;
1996 if (frm_end
-frm_nxt
< 3)
1997 return codecvt_base::partial
;
1998 uint8_t c3
= frm_nxt
[2];
1999 if ((c3
& 0xC0) != 0x80)
2000 return codecvt_base::error
;
2001 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2002 | ((c2
& 0x3F) << 6)
2005 return codecvt_base::error
;
2011 if (frm_end
-frm_nxt
< 2)
2012 return codecvt_base::partial
;
2013 uint8_t c2
= frm_nxt
[1];
2017 if (!(0x90 <= c2
&& c2
<= 0xBF))
2018 return codecvt_base::error
;
2021 if ((c2
& 0xF0) != 0x80)
2022 return codecvt_base::error
;
2025 if ((c2
& 0xC0) != 0x80)
2026 return codecvt_base::error
;
2029 if (frm_end
-frm_nxt
< 3)
2030 return codecvt_base::partial
;
2031 uint8_t c3
= frm_nxt
[2];
2032 if ((c3
& 0xC0) != 0x80)
2033 return codecvt_base::error
;
2034 if (frm_end
-frm_nxt
< 4)
2035 return codecvt_base::partial
;
2036 uint8_t c4
= frm_nxt
[3];
2037 if ((c4
& 0xC0) != 0x80)
2038 return codecvt_base::error
;
2039 if (to_end
-to_nxt
< 2)
2040 return codecvt_base::partial
;
2041 if ((((c1
& 7UL) << 18) +
2042 ((c2
& 0x3FUL
) << 12) +
2043 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2044 return codecvt_base::error
;
2045 *to_nxt
= static_cast<uint16_t>(
2047 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2048 | ((c2
& 0x0F) << 2)
2049 | ((c3
& 0x30) >> 4));
2050 *++to_nxt
= static_cast<uint16_t>(
2052 | ((c3
& 0x0F) << 6)
2058 return codecvt_base::error
;
2061 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2065 codecvt_base::result
2066 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2067 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2068 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2072 if (mode
& consume_header
)
2074 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2078 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2080 uint8_t c1
= *frm_nxt
;
2082 return codecvt_base::error
;
2085 *to_nxt
= static_cast<uint32_t>(c1
);
2090 return codecvt_base::error
;
2094 if (frm_end
-frm_nxt
< 2)
2095 return codecvt_base::partial
;
2096 uint8_t c2
= frm_nxt
[1];
2097 if ((c2
& 0xC0) != 0x80)
2098 return codecvt_base::error
;
2099 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2101 return codecvt_base::error
;
2102 *to_nxt
= static_cast<uint32_t>(t
);
2107 if (frm_end
-frm_nxt
< 2)
2108 return codecvt_base::partial
;
2109 uint8_t c2
= frm_nxt
[1];
2113 if ((c2
& 0xE0) != 0xA0)
2114 return codecvt_base::error
;
2117 if ((c2
& 0xE0) != 0x80)
2118 return codecvt_base::error
;
2121 if ((c2
& 0xC0) != 0x80)
2122 return codecvt_base::error
;
2125 if (frm_end
-frm_nxt
< 3)
2126 return codecvt_base::partial
;
2127 uint8_t c3
= frm_nxt
[2];
2128 if ((c3
& 0xC0) != 0x80)
2129 return codecvt_base::error
;
2130 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2131 | ((c2
& 0x3F) << 6)
2134 return codecvt_base::error
;
2135 *to_nxt
= static_cast<uint32_t>(t
);
2140 if (frm_end
-frm_nxt
< 2)
2141 return codecvt_base::partial
;
2142 uint8_t c2
= frm_nxt
[1];
2146 if (!(0x90 <= c2
&& c2
<= 0xBF))
2147 return codecvt_base::error
;
2150 if ((c2
& 0xF0) != 0x80)
2151 return codecvt_base::error
;
2154 if ((c2
& 0xC0) != 0x80)
2155 return codecvt_base::error
;
2158 if (frm_end
-frm_nxt
< 3)
2159 return codecvt_base::partial
;
2160 uint8_t c3
= frm_nxt
[2];
2161 if ((c3
& 0xC0) != 0x80)
2162 return codecvt_base::error
;
2163 if (frm_end
-frm_nxt
< 4)
2164 return codecvt_base::partial
;
2165 uint8_t c4
= frm_nxt
[3];
2166 if ((c4
& 0xC0) != 0x80)
2167 return codecvt_base::error
;
2168 if (to_end
-to_nxt
< 2)
2169 return codecvt_base::partial
;
2170 if ((((c1
& 7UL) << 18) +
2171 ((c2
& 0x3FUL
) << 12) +
2172 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2173 return codecvt_base::error
;
2174 *to_nxt
= static_cast<uint32_t>(
2176 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2177 | ((c2
& 0x0F) << 2)
2178 | ((c3
& 0x30) >> 4));
2179 *++to_nxt
= static_cast<uint32_t>(
2181 | ((c3
& 0x0F) << 6)
2187 return codecvt_base::error
;
2190 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2195 utf8_to_utf16_length(const uint8_t* frm
, const uint8_t* frm_end
,
2196 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2197 codecvt_mode mode
= codecvt_mode(0))
2199 const uint8_t* frm_nxt
= frm
;
2200 if (mode
& consume_header
)
2202 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2206 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
&& nchar16_t
< mx
; ++nchar16_t
)
2208 uint8_t c1
= *frm_nxt
;
2221 if ((frm_end
-frm_nxt
< 2) || (frm_nxt
[1] & 0xC0) != 0x80)
2223 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (frm_nxt
[1] & 0x3F));
2230 if (frm_end
-frm_nxt
< 3)
2232 uint8_t c2
= frm_nxt
[1];
2233 uint8_t c3
= frm_nxt
[2];
2237 if ((c2
& 0xE0) != 0xA0)
2238 return static_cast<int>(frm_nxt
- frm
);
2241 if ((c2
& 0xE0) != 0x80)
2242 return static_cast<int>(frm_nxt
- frm
);
2245 if ((c2
& 0xC0) != 0x80)
2246 return static_cast<int>(frm_nxt
- frm
);
2249 if ((c3
& 0xC0) != 0x80)
2251 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2257 if (frm_end
-frm_nxt
< 4 || mx
-nchar16_t
< 2)
2259 uint8_t c2
= frm_nxt
[1];
2260 uint8_t c3
= frm_nxt
[2];
2261 uint8_t c4
= frm_nxt
[3];
2265 if (!(0x90 <= c2
&& c2
<= 0xBF))
2266 return static_cast<int>(frm_nxt
- frm
);
2269 if ((c2
& 0xF0) != 0x80)
2270 return static_cast<int>(frm_nxt
- frm
);
2273 if ((c2
& 0xC0) != 0x80)
2274 return static_cast<int>(frm_nxt
- frm
);
2277 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2279 if ((((c1
& 7UL) << 18) +
2280 ((c2
& 0x3FUL
) << 12) +
2281 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2291 return static_cast<int>(frm_nxt
- frm
);
2295 codecvt_base::result
2296 ucs4_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2297 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2298 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2302 if (mode
& generate_header
)
2304 if (to_end
-to_nxt
< 3)
2305 return codecvt_base::partial
;
2306 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2307 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2308 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2310 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2312 uint32_t wc
= *frm_nxt
;
2313 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2314 return codecvt_base::error
;
2317 if (to_end
-to_nxt
< 1)
2318 return codecvt_base::partial
;
2319 *to_nxt
++ = static_cast<uint8_t>(wc
);
2321 else if (wc
< 0x000800)
2323 if (to_end
-to_nxt
< 2)
2324 return codecvt_base::partial
;
2325 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2326 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2328 else if (wc
< 0x010000)
2330 if (to_end
-to_nxt
< 3)
2331 return codecvt_base::partial
;
2332 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2333 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2334 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2336 else // if (wc < 0x110000)
2338 if (to_end
-to_nxt
< 4)
2339 return codecvt_base::partial
;
2340 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (wc
>> 18));
2341 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x03F000) >> 12));
2342 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x000FC0) >> 6));
2343 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x00003F));
2346 return codecvt_base::ok
;
2350 codecvt_base::result
2351 utf8_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2352 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2353 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2357 if (mode
& consume_header
)
2359 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2363 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2365 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2369 return codecvt_base::error
;
2370 *to_nxt
= static_cast<uint32_t>(c1
);
2375 return codecvt_base::error
;
2379 if (frm_end
-frm_nxt
< 2)
2380 return codecvt_base::partial
;
2381 uint8_t c2
= frm_nxt
[1];
2382 if ((c2
& 0xC0) != 0x80)
2383 return codecvt_base::error
;
2384 uint32_t t
= static_cast<uint32_t>(((c1
& 0x1F) << 6)
2387 return codecvt_base::error
;
2393 if (frm_end
-frm_nxt
< 2)
2394 return codecvt_base::partial
;
2395 uint8_t c2
= frm_nxt
[1];
2399 if ((c2
& 0xE0) != 0xA0)
2400 return codecvt_base::error
;
2403 if ((c2
& 0xE0) != 0x80)
2404 return codecvt_base::error
;
2407 if ((c2
& 0xC0) != 0x80)
2408 return codecvt_base::error
;
2411 if (frm_end
-frm_nxt
< 3)
2412 return codecvt_base::partial
;
2413 uint8_t c3
= frm_nxt
[2];
2414 if ((c3
& 0xC0) != 0x80)
2415 return codecvt_base::error
;
2416 uint32_t t
= static_cast<uint32_t>(((c1
& 0x0F) << 12)
2417 | ((c2
& 0x3F) << 6)
2420 return codecvt_base::error
;
2426 if (frm_end
-frm_nxt
< 2)
2427 return codecvt_base::partial
;
2428 uint8_t c2
= frm_nxt
[1];
2432 if (!(0x90 <= c2
&& c2
<= 0xBF))
2433 return codecvt_base::error
;
2436 if ((c2
& 0xF0) != 0x80)
2437 return codecvt_base::error
;
2440 if ((c2
& 0xC0) != 0x80)
2441 return codecvt_base::error
;
2444 if (frm_end
-frm_nxt
< 3)
2445 return codecvt_base::partial
;
2446 uint8_t c3
= frm_nxt
[2];
2447 if ((c3
& 0xC0) != 0x80)
2448 return codecvt_base::error
;
2449 if (frm_end
-frm_nxt
< 4)
2450 return codecvt_base::partial
;
2451 uint8_t c4
= frm_nxt
[3];
2452 if ((c4
& 0xC0) != 0x80)
2453 return codecvt_base::error
;
2454 uint32_t t
= static_cast<uint32_t>(((c1
& 0x07) << 18)
2455 | ((c2
& 0x3F) << 12)
2456 | ((c3
& 0x3F) << 6)
2459 return codecvt_base::error
;
2465 return codecvt_base::error
;
2468 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2473 utf8_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2474 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2475 codecvt_mode mode
= codecvt_mode(0))
2477 const uint8_t* frm_nxt
= frm
;
2478 if (mode
& consume_header
)
2480 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2484 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2486 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2499 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2501 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2507 if (frm_end
-frm_nxt
< 3)
2509 uint8_t c2
= frm_nxt
[1];
2510 uint8_t c3
= frm_nxt
[2];
2514 if ((c2
& 0xE0) != 0xA0)
2515 return static_cast<int>(frm_nxt
- frm
);
2518 if ((c2
& 0xE0) != 0x80)
2519 return static_cast<int>(frm_nxt
- frm
);
2522 if ((c2
& 0xC0) != 0x80)
2523 return static_cast<int>(frm_nxt
- frm
);
2526 if ((c3
& 0xC0) != 0x80)
2528 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2534 if (frm_end
-frm_nxt
< 4)
2536 uint8_t c2
= frm_nxt
[1];
2537 uint8_t c3
= frm_nxt
[2];
2538 uint8_t c4
= frm_nxt
[3];
2542 if (!(0x90 <= c2
&& c2
<= 0xBF))
2543 return static_cast<int>(frm_nxt
- frm
);
2546 if ((c2
& 0xF0) != 0x80)
2547 return static_cast<int>(frm_nxt
- frm
);
2550 if ((c2
& 0xC0) != 0x80)
2551 return static_cast<int>(frm_nxt
- frm
);
2554 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2556 if ((((c1
& 0x07u
) << 18) | ((c2
& 0x3Fu
) << 12) |
2557 ((c3
& 0x3Fu
) << 6) | (c4
& 0x3Fu
)) > Maxcode
)
2566 return static_cast<int>(frm_nxt
- frm
);
2570 codecvt_base::result
2571 ucs2_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
2572 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2573 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2577 if (mode
& generate_header
)
2579 if (to_end
-to_nxt
< 3)
2580 return codecvt_base::partial
;
2581 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2582 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2583 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2585 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2587 uint16_t wc
= *frm_nxt
;
2588 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2589 return codecvt_base::error
;
2592 if (to_end
-to_nxt
< 1)
2593 return codecvt_base::partial
;
2594 *to_nxt
++ = static_cast<uint8_t>(wc
);
2596 else if (wc
< 0x0800)
2598 if (to_end
-to_nxt
< 2)
2599 return codecvt_base::partial
;
2600 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2601 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2603 else // if (wc <= 0xFFFF)
2605 if (to_end
-to_nxt
< 3)
2606 return codecvt_base::partial
;
2607 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2608 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2609 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2612 return codecvt_base::ok
;
2616 codecvt_base::result
2617 utf8_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2618 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
2619 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2623 if (mode
& consume_header
)
2625 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2629 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2631 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2635 return codecvt_base::error
;
2636 *to_nxt
= static_cast<uint16_t>(c1
);
2641 return codecvt_base::error
;
2645 if (frm_end
-frm_nxt
< 2)
2646 return codecvt_base::partial
;
2647 uint8_t c2
= frm_nxt
[1];
2648 if ((c2
& 0xC0) != 0x80)
2649 return codecvt_base::error
;
2650 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6)
2653 return codecvt_base::error
;
2659 if (frm_end
-frm_nxt
< 2)
2660 return codecvt_base::partial
;
2661 uint8_t c2
= frm_nxt
[1];
2665 if ((c2
& 0xE0) != 0xA0)
2666 return codecvt_base::error
;
2669 if ((c2
& 0xE0) != 0x80)
2670 return codecvt_base::error
;
2673 if ((c2
& 0xC0) != 0x80)
2674 return codecvt_base::error
;
2677 if (frm_end
-frm_nxt
< 3)
2678 return codecvt_base::partial
;
2679 uint8_t c3
= frm_nxt
[2];
2680 if ((c3
& 0xC0) != 0x80)
2681 return codecvt_base::error
;
2682 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2683 | ((c2
& 0x3F) << 6)
2686 return codecvt_base::error
;
2692 return codecvt_base::error
;
2695 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2700 utf8_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
2701 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2702 codecvt_mode mode
= codecvt_mode(0))
2704 const uint8_t* frm_nxt
= frm
;
2705 if (mode
& consume_header
)
2707 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2711 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2713 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2726 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2728 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2734 if (frm_end
-frm_nxt
< 3)
2736 uint8_t c2
= frm_nxt
[1];
2737 uint8_t c3
= frm_nxt
[2];
2741 if ((c2
& 0xE0) != 0xA0)
2742 return static_cast<int>(frm_nxt
- frm
);
2745 if ((c2
& 0xE0) != 0x80)
2746 return static_cast<int>(frm_nxt
- frm
);
2749 if ((c2
& 0xC0) != 0x80)
2750 return static_cast<int>(frm_nxt
- frm
);
2753 if ((c3
& 0xC0) != 0x80)
2755 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2764 return static_cast<int>(frm_nxt
- frm
);
2768 codecvt_base::result
2769 ucs4_to_utf16be(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2770 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2771 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2775 if (mode
& generate_header
)
2777 if (to_end
-to_nxt
< 2)
2778 return codecvt_base::partial
;
2779 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2780 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2782 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2784 uint32_t wc
= *frm_nxt
;
2785 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2786 return codecvt_base::error
;
2789 if (to_end
-to_nxt
< 2)
2790 return codecvt_base::partial
;
2791 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2792 *to_nxt
++ = static_cast<uint8_t>(wc
);
2796 if (to_end
-to_nxt
< 4)
2797 return codecvt_base::partial
;
2798 uint16_t t
= static_cast<uint16_t>(
2800 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2801 | ((wc
& 0x00FC00) >> 10));
2802 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2803 *to_nxt
++ = static_cast<uint8_t>(t
);
2804 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2805 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2806 *to_nxt
++ = static_cast<uint8_t>(t
);
2809 return codecvt_base::ok
;
2813 codecvt_base::result
2814 utf16be_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2815 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2816 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2820 if (mode
& consume_header
)
2822 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2825 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2827 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2828 if ((c1
& 0xFC00) == 0xDC00)
2829 return codecvt_base::error
;
2830 if ((c1
& 0xFC00) != 0xD800)
2833 return codecvt_base::error
;
2834 *to_nxt
= static_cast<uint32_t>(c1
);
2839 if (frm_end
-frm_nxt
< 4)
2840 return codecvt_base::partial
;
2841 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2842 if ((c2
& 0xFC00) != 0xDC00)
2843 return codecvt_base::error
;
2844 uint32_t t
= static_cast<uint32_t>(
2845 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2846 | ((c1
& 0x003F) << 10)
2849 return codecvt_base::error
;
2854 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2859 utf16be_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2860 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2861 codecvt_mode mode
= codecvt_mode(0))
2863 const uint8_t* frm_nxt
= frm
;
2864 if (mode
& consume_header
)
2866 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2869 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2871 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2872 if ((c1
& 0xFC00) == 0xDC00)
2874 if ((c1
& 0xFC00) != 0xD800)
2882 if (frm_end
-frm_nxt
< 4)
2884 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2885 if ((c2
& 0xFC00) != 0xDC00)
2887 uint32_t t
= static_cast<uint32_t>(
2888 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2889 | ((c1
& 0x003F) << 10)
2896 return static_cast<int>(frm_nxt
- frm
);
2900 codecvt_base::result
2901 ucs4_to_utf16le(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2902 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2903 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2907 if (mode
& generate_header
)
2909 if (to_end
- to_nxt
< 2)
2910 return codecvt_base::partial
;
2911 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2912 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2914 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2916 uint32_t wc
= *frm_nxt
;
2917 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2918 return codecvt_base::error
;
2921 if (to_end
-to_nxt
< 2)
2922 return codecvt_base::partial
;
2923 *to_nxt
++ = static_cast<uint8_t>(wc
);
2924 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2928 if (to_end
-to_nxt
< 4)
2929 return codecvt_base::partial
;
2930 uint16_t t
= static_cast<uint16_t>(
2932 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2933 | ((wc
& 0x00FC00) >> 10));
2934 *to_nxt
++ = static_cast<uint8_t>(t
);
2935 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2936 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2937 *to_nxt
++ = static_cast<uint8_t>(t
);
2938 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2941 return codecvt_base::ok
;
2945 codecvt_base::result
2946 utf16le_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2947 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2948 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2952 if (mode
& consume_header
)
2954 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2957 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2959 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2960 if ((c1
& 0xFC00) == 0xDC00)
2961 return codecvt_base::error
;
2962 if ((c1
& 0xFC00) != 0xD800)
2965 return codecvt_base::error
;
2966 *to_nxt
= static_cast<uint32_t>(c1
);
2971 if (frm_end
-frm_nxt
< 4)
2972 return codecvt_base::partial
;
2973 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2974 if ((c2
& 0xFC00) != 0xDC00)
2975 return codecvt_base::error
;
2976 uint32_t t
= static_cast<uint32_t>(
2977 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2978 | ((c1
& 0x003F) << 10)
2981 return codecvt_base::error
;
2986 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2991 utf16le_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2992 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2993 codecvt_mode mode
= codecvt_mode(0))
2995 const uint8_t* frm_nxt
= frm
;
2996 if (mode
& consume_header
)
2998 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3001 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
3003 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3004 if ((c1
& 0xFC00) == 0xDC00)
3006 if ((c1
& 0xFC00) != 0xD800)
3014 if (frm_end
-frm_nxt
< 4)
3016 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
3017 if ((c2
& 0xFC00) != 0xDC00)
3019 uint32_t t
= static_cast<uint32_t>(
3020 ((((c1
& 0x03C0) >> 6) + 1) << 16)
3021 | ((c1
& 0x003F) << 10)
3028 return static_cast<int>(frm_nxt
- frm
);
3032 codecvt_base::result
3033 ucs2_to_utf16be(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3034 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3035 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3039 if (mode
& generate_header
)
3041 if (to_end
-to_nxt
< 2)
3042 return codecvt_base::partial
;
3043 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3044 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3046 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3048 uint16_t wc
= *frm_nxt
;
3049 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3050 return codecvt_base::error
;
3051 if (to_end
-to_nxt
< 2)
3052 return codecvt_base::partial
;
3053 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3054 *to_nxt
++ = static_cast<uint8_t>(wc
);
3056 return codecvt_base::ok
;
3060 codecvt_base::result
3061 utf16be_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3062 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3063 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3067 if (mode
& consume_header
)
3069 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3072 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3074 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3075 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3076 return codecvt_base::error
;
3080 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3085 utf16be_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3086 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3087 codecvt_mode mode
= codecvt_mode(0))
3089 const uint8_t* frm_nxt
= frm
;
3090 if (mode
& consume_header
)
3092 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3095 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3097 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3098 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3102 return static_cast<int>(frm_nxt
- frm
);
3106 codecvt_base::result
3107 ucs2_to_utf16le(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3108 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3109 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3113 if (mode
& generate_header
)
3115 if (to_end
-to_nxt
< 2)
3116 return codecvt_base::partial
;
3117 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3118 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3120 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3122 uint16_t wc
= *frm_nxt
;
3123 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3124 return codecvt_base::error
;
3125 if (to_end
-to_nxt
< 2)
3126 return codecvt_base::partial
;
3127 *to_nxt
++ = static_cast<uint8_t>(wc
);
3128 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3130 return codecvt_base::ok
;
3134 codecvt_base::result
3135 utf16le_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3136 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3137 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3141 if (mode
& consume_header
)
3143 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3146 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3148 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3149 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3150 return codecvt_base::error
;
3154 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3159 utf16le_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3160 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3161 codecvt_mode mode
= codecvt_mode(0))
3163 const uint8_t* frm_nxt
= frm
;
3165 if (mode
& consume_header
)
3167 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3170 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3172 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3173 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3177 return static_cast<int>(frm_nxt
- frm
);
3180 _LIBCPP_SUPPRESS_DEPRECATED_POP
3182 // template <> class codecvt<char16_t, char, mbstate_t>
3184 constinit
locale::id codecvt
<char16_t
, char, mbstate_t>::id
;
3186 codecvt
<char16_t
, char, mbstate_t>::~codecvt()
3190 codecvt
<char16_t
, char, mbstate_t>::result
3191 codecvt
<char16_t
, char, mbstate_t>::do_out(state_type
&,
3192 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3193 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3195 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3196 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3197 const uint16_t* _frm_nxt
= _frm
;
3198 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3199 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3200 uint8_t* _to_nxt
= _to
;
3201 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3202 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3203 to_nxt
= to
+ (_to_nxt
- _to
);
3207 codecvt
<char16_t
, char, mbstate_t>::result
3208 codecvt
<char16_t
, char, mbstate_t>::do_in(state_type
&,
3209 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3210 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3212 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3213 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3214 const uint8_t* _frm_nxt
= _frm
;
3215 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3216 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3217 uint16_t* _to_nxt
= _to
;
3218 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3219 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3220 to_nxt
= to
+ (_to_nxt
- _to
);
3224 codecvt
<char16_t
, char, mbstate_t>::result
3225 codecvt
<char16_t
, char, mbstate_t>::do_unshift(state_type
&,
3226 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3233 codecvt
<char16_t
, char, mbstate_t>::do_encoding() const noexcept
3239 codecvt
<char16_t
, char, mbstate_t>::do_always_noconv() const noexcept
3245 codecvt
<char16_t
, char, mbstate_t>::do_length(state_type
&,
3246 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3248 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3249 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3250 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3254 codecvt
<char16_t
, char, mbstate_t>::do_max_length() const noexcept
3259 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3261 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3263 constinit
locale::id codecvt
<char16_t
, char8_t
, mbstate_t>::id
;
3265 codecvt
<char16_t
, char8_t
, mbstate_t>::~codecvt()
3269 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3270 codecvt
<char16_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3271 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3272 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3274 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3275 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3276 const uint16_t* _frm_nxt
= _frm
;
3277 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3278 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3279 uint8_t* _to_nxt
= _to
;
3280 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3281 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3282 to_nxt
= to
+ (_to_nxt
- _to
);
3286 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3287 codecvt
<char16_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3288 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3289 intern_type
* to
, intern_type
* to_end
, 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 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3295 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3296 uint16_t* _to_nxt
= _to
;
3297 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3298 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3299 to_nxt
= to
+ (_to_nxt
- _to
);
3303 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3304 codecvt
<char16_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3305 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3312 codecvt
<char16_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3318 codecvt
<char16_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3324 codecvt
<char16_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3325 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3327 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3328 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3329 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3333 codecvt
<char16_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3340 // template <> class codecvt<char32_t, char, mbstate_t>
3342 constinit
locale::id codecvt
<char32_t
, char, mbstate_t>::id
;
3344 codecvt
<char32_t
, char, mbstate_t>::~codecvt()
3348 codecvt
<char32_t
, char, mbstate_t>::result
3349 codecvt
<char32_t
, char, mbstate_t>::do_out(state_type
&,
3350 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3351 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3353 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3354 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3355 const uint32_t* _frm_nxt
= _frm
;
3356 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3357 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3358 uint8_t* _to_nxt
= _to
;
3359 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3360 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3361 to_nxt
= to
+ (_to_nxt
- _to
);
3365 codecvt
<char32_t
, char, mbstate_t>::result
3366 codecvt
<char32_t
, char, mbstate_t>::do_in(state_type
&,
3367 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3368 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3370 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3371 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3372 const uint8_t* _frm_nxt
= _frm
;
3373 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3374 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3375 uint32_t* _to_nxt
= _to
;
3376 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3377 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3378 to_nxt
= to
+ (_to_nxt
- _to
);
3382 codecvt
<char32_t
, char, mbstate_t>::result
3383 codecvt
<char32_t
, char, mbstate_t>::do_unshift(state_type
&,
3384 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3391 codecvt
<char32_t
, char, mbstate_t>::do_encoding() const noexcept
3397 codecvt
<char32_t
, char, mbstate_t>::do_always_noconv() const noexcept
3403 codecvt
<char32_t
, char, mbstate_t>::do_length(state_type
&,
3404 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3406 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3407 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3408 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3412 codecvt
<char32_t
, char, mbstate_t>::do_max_length() const noexcept
3417 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3419 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3421 constinit
locale::id codecvt
<char32_t
, char8_t
, mbstate_t>::id
;
3423 codecvt
<char32_t
, char8_t
, mbstate_t>::~codecvt()
3427 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3428 codecvt
<char32_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3429 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3430 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3432 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3433 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3434 const uint32_t* _frm_nxt
= _frm
;
3435 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3436 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3437 uint8_t* _to_nxt
= _to
;
3438 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3439 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3440 to_nxt
= to
+ (_to_nxt
- _to
);
3444 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3445 codecvt
<char32_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3446 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3447 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3449 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3450 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3451 const uint8_t* _frm_nxt
= _frm
;
3452 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3453 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3454 uint32_t* _to_nxt
= _to
;
3455 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3456 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3457 to_nxt
= to
+ (_to_nxt
- _to
);
3461 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3462 codecvt
<char32_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3463 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3470 codecvt
<char32_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3476 codecvt
<char32_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3482 codecvt
<char32_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3483 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3485 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3486 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3487 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3491 codecvt
<char32_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3498 // __codecvt_utf8<wchar_t>
3500 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3501 __codecvt_utf8
<wchar_t>::result
3502 __codecvt_utf8
<wchar_t>::do_out(state_type
&,
3503 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3504 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3506 #if defined(_LIBCPP_SHORT_WCHAR)
3507 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3508 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3509 const uint16_t* _frm_nxt
= _frm
;
3511 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3512 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3513 const uint32_t* _frm_nxt
= _frm
;
3515 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3516 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3517 uint8_t* _to_nxt
= _to
;
3518 #if defined(_LIBCPP_SHORT_WCHAR)
3519 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3520 __maxcode_
, __mode_
);
3522 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3523 __maxcode_
, __mode_
);
3525 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3526 to_nxt
= to
+ (_to_nxt
- _to
);
3530 __codecvt_utf8
<wchar_t>::result
3531 __codecvt_utf8
<wchar_t>::do_in(state_type
&,
3532 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3533 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3535 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3536 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3537 const uint8_t* _frm_nxt
= _frm
;
3538 #if defined(_LIBCPP_SHORT_WCHAR)
3539 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3540 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3541 uint16_t* _to_nxt
= _to
;
3542 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3543 __maxcode_
, __mode_
);
3545 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3546 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3547 uint32_t* _to_nxt
= _to
;
3548 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3549 __maxcode_
, __mode_
);
3551 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3552 to_nxt
= to
+ (_to_nxt
- _to
);
3556 __codecvt_utf8
<wchar_t>::result
3557 __codecvt_utf8
<wchar_t>::do_unshift(state_type
&,
3558 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3565 __codecvt_utf8
<wchar_t>::do_encoding() const noexcept
3571 __codecvt_utf8
<wchar_t>::do_always_noconv() const noexcept
3577 __codecvt_utf8
<wchar_t>::do_length(state_type
&,
3578 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3580 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3581 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3582 #if defined(_LIBCPP_SHORT_WCHAR)
3583 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3585 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3589 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3591 __codecvt_utf8
<wchar_t>::do_max_length() const noexcept
3593 #if defined(_LIBCPP_SHORT_WCHAR)
3594 if (__mode_
& consume_header
)
3598 if (__mode_
& consume_header
)
3603 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3605 // __codecvt_utf8<char16_t>
3607 __codecvt_utf8
<char16_t
>::result
3608 __codecvt_utf8
<char16_t
>::do_out(state_type
&,
3609 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3610 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3612 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3613 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3614 const uint16_t* _frm_nxt
= _frm
;
3615 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3616 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3617 uint8_t* _to_nxt
= _to
;
3618 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3619 __maxcode_
, __mode_
);
3620 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3621 to_nxt
= to
+ (_to_nxt
- _to
);
3625 __codecvt_utf8
<char16_t
>::result
3626 __codecvt_utf8
<char16_t
>::do_in(state_type
&,
3627 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3628 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3630 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3631 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3632 const uint8_t* _frm_nxt
= _frm
;
3633 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3634 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3635 uint16_t* _to_nxt
= _to
;
3636 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3637 __maxcode_
, __mode_
);
3638 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3639 to_nxt
= to
+ (_to_nxt
- _to
);
3643 __codecvt_utf8
<char16_t
>::result
3644 __codecvt_utf8
<char16_t
>::do_unshift(state_type
&,
3645 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3652 __codecvt_utf8
<char16_t
>::do_encoding() const noexcept
3658 __codecvt_utf8
<char16_t
>::do_always_noconv() const noexcept
3664 __codecvt_utf8
<char16_t
>::do_length(state_type
&,
3665 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) 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 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3672 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3674 __codecvt_utf8
<char16_t
>::do_max_length() const noexcept
3676 if (__mode_
& consume_header
)
3680 _LIBCPP_SUPPRESS_DEPRECATED_POP
3682 // __codecvt_utf8<char32_t>
3684 __codecvt_utf8
<char32_t
>::result
3685 __codecvt_utf8
<char32_t
>::do_out(state_type
&,
3686 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3687 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3689 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3690 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3691 const uint32_t* _frm_nxt
= _frm
;
3692 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3693 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3694 uint8_t* _to_nxt
= _to
;
3695 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3696 __maxcode_
, __mode_
);
3697 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3698 to_nxt
= to
+ (_to_nxt
- _to
);
3702 __codecvt_utf8
<char32_t
>::result
3703 __codecvt_utf8
<char32_t
>::do_in(state_type
&,
3704 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3705 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3707 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3708 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3709 const uint8_t* _frm_nxt
= _frm
;
3710 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3711 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3712 uint32_t* _to_nxt
= _to
;
3713 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3714 __maxcode_
, __mode_
);
3715 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3716 to_nxt
= to
+ (_to_nxt
- _to
);
3720 __codecvt_utf8
<char32_t
>::result
3721 __codecvt_utf8
<char32_t
>::do_unshift(state_type
&,
3722 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3729 __codecvt_utf8
<char32_t
>::do_encoding() const noexcept
3735 __codecvt_utf8
<char32_t
>::do_always_noconv() const noexcept
3741 __codecvt_utf8
<char32_t
>::do_length(state_type
&,
3742 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3744 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3745 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3746 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3749 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3751 __codecvt_utf8
<char32_t
>::do_max_length() const noexcept
3753 if (__mode_
& consume_header
)
3757 _LIBCPP_SUPPRESS_DEPRECATED_POP
3759 // __codecvt_utf16<wchar_t, false>
3761 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3762 __codecvt_utf16
<wchar_t, false>::result
3763 __codecvt_utf16
<wchar_t, false>::do_out(state_type
&,
3764 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3765 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3767 #if defined(_LIBCPP_SHORT_WCHAR)
3768 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3769 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3770 const uint16_t* _frm_nxt
= _frm
;
3772 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3773 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3774 const uint32_t* _frm_nxt
= _frm
;
3776 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3777 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3778 uint8_t* _to_nxt
= _to
;
3779 #if defined(_LIBCPP_SHORT_WCHAR)
3780 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3781 __maxcode_
, __mode_
);
3783 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3784 __maxcode_
, __mode_
);
3786 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3787 to_nxt
= to
+ (_to_nxt
- _to
);
3791 __codecvt_utf16
<wchar_t, false>::result
3792 __codecvt_utf16
<wchar_t, false>::do_in(state_type
&,
3793 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3794 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3796 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3797 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3798 const uint8_t* _frm_nxt
= _frm
;
3799 #if defined(_LIBCPP_SHORT_WCHAR)
3800 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3801 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3802 uint16_t* _to_nxt
= _to
;
3803 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3804 __maxcode_
, __mode_
);
3806 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3807 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3808 uint32_t* _to_nxt
= _to
;
3809 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3810 __maxcode_
, __mode_
);
3812 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3813 to_nxt
= to
+ (_to_nxt
- _to
);
3817 __codecvt_utf16
<wchar_t, false>::result
3818 __codecvt_utf16
<wchar_t, false>::do_unshift(state_type
&,
3819 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3826 __codecvt_utf16
<wchar_t, false>::do_encoding() const noexcept
3832 __codecvt_utf16
<wchar_t, false>::do_always_noconv() const noexcept
3838 __codecvt_utf16
<wchar_t, false>::do_length(state_type
&,
3839 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3841 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3842 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3843 #if defined(_LIBCPP_SHORT_WCHAR)
3844 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3846 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3851 __codecvt_utf16
<wchar_t, false>::do_max_length() const noexcept
3853 #if defined(_LIBCPP_SHORT_WCHAR)
3854 if (__mode_
& consume_header
)
3858 if (__mode_
& consume_header
)
3864 // __codecvt_utf16<wchar_t, true>
3866 __codecvt_utf16
<wchar_t, true>::result
3867 __codecvt_utf16
<wchar_t, true>::do_out(state_type
&,
3868 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3869 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3871 #if defined(_LIBCPP_SHORT_WCHAR)
3872 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3873 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3874 const uint16_t* _frm_nxt
= _frm
;
3876 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3877 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3878 const uint32_t* _frm_nxt
= _frm
;
3880 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3881 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3882 uint8_t* _to_nxt
= _to
;
3883 #if defined(_LIBCPP_SHORT_WCHAR)
3884 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3885 __maxcode_
, __mode_
);
3887 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3888 __maxcode_
, __mode_
);
3890 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3891 to_nxt
= to
+ (_to_nxt
- _to
);
3895 __codecvt_utf16
<wchar_t, true>::result
3896 __codecvt_utf16
<wchar_t, true>::do_in(state_type
&,
3897 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3898 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3900 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3901 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3902 const uint8_t* _frm_nxt
= _frm
;
3903 #if defined(_LIBCPP_SHORT_WCHAR)
3904 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3905 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3906 uint16_t* _to_nxt
= _to
;
3907 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3908 __maxcode_
, __mode_
);
3910 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3911 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3912 uint32_t* _to_nxt
= _to
;
3913 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3914 __maxcode_
, __mode_
);
3916 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3917 to_nxt
= to
+ (_to_nxt
- _to
);
3921 __codecvt_utf16
<wchar_t, true>::result
3922 __codecvt_utf16
<wchar_t, true>::do_unshift(state_type
&,
3923 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3930 __codecvt_utf16
<wchar_t, true>::do_encoding() const noexcept
3936 __codecvt_utf16
<wchar_t, true>::do_always_noconv() const noexcept
3942 __codecvt_utf16
<wchar_t, true>::do_length(state_type
&,
3943 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3945 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3946 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3947 #if defined(_LIBCPP_SHORT_WCHAR)
3948 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3950 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3955 __codecvt_utf16
<wchar_t, true>::do_max_length() const noexcept
3957 #if defined(_LIBCPP_SHORT_WCHAR)
3958 if (__mode_
& consume_header
)
3962 if (__mode_
& consume_header
)
3967 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3969 // __codecvt_utf16<char16_t, false>
3971 __codecvt_utf16
<char16_t
, false>::result
3972 __codecvt_utf16
<char16_t
, false>::do_out(state_type
&,
3973 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3974 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3976 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3977 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3978 const uint16_t* _frm_nxt
= _frm
;
3979 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3980 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3981 uint8_t* _to_nxt
= _to
;
3982 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3983 __maxcode_
, __mode_
);
3984 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3985 to_nxt
= to
+ (_to_nxt
- _to
);
3989 __codecvt_utf16
<char16_t
, false>::result
3990 __codecvt_utf16
<char16_t
, false>::do_in(state_type
&,
3991 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3992 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3994 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3995 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3996 const uint8_t* _frm_nxt
= _frm
;
3997 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3998 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3999 uint16_t* _to_nxt
= _to
;
4000 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4001 __maxcode_
, __mode_
);
4002 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4003 to_nxt
= to
+ (_to_nxt
- _to
);
4007 __codecvt_utf16
<char16_t
, false>::result
4008 __codecvt_utf16
<char16_t
, false>::do_unshift(state_type
&,
4009 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4016 __codecvt_utf16
<char16_t
, false>::do_encoding() const noexcept
4022 __codecvt_utf16
<char16_t
, false>::do_always_noconv() const noexcept
4028 __codecvt_utf16
<char16_t
, false>::do_length(state_type
&,
4029 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4031 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4032 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4033 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4036 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4038 __codecvt_utf16
<char16_t
, false>::do_max_length() const noexcept
4040 if (__mode_
& consume_header
)
4044 _LIBCPP_SUPPRESS_DEPRECATED_POP
4046 // __codecvt_utf16<char16_t, true>
4048 __codecvt_utf16
<char16_t
, true>::result
4049 __codecvt_utf16
<char16_t
, true>::do_out(state_type
&,
4050 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4051 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4053 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4054 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4055 const uint16_t* _frm_nxt
= _frm
;
4056 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4057 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4058 uint8_t* _to_nxt
= _to
;
4059 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4060 __maxcode_
, __mode_
);
4061 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4062 to_nxt
= to
+ (_to_nxt
- _to
);
4066 __codecvt_utf16
<char16_t
, true>::result
4067 __codecvt_utf16
<char16_t
, true>::do_in(state_type
&,
4068 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4069 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4071 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4072 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4073 const uint8_t* _frm_nxt
= _frm
;
4074 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4075 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4076 uint16_t* _to_nxt
= _to
;
4077 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4078 __maxcode_
, __mode_
);
4079 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4080 to_nxt
= to
+ (_to_nxt
- _to
);
4084 __codecvt_utf16
<char16_t
, true>::result
4085 __codecvt_utf16
<char16_t
, true>::do_unshift(state_type
&,
4086 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4093 __codecvt_utf16
<char16_t
, true>::do_encoding() const noexcept
4099 __codecvt_utf16
<char16_t
, true>::do_always_noconv() const noexcept
4105 __codecvt_utf16
<char16_t
, true>::do_length(state_type
&,
4106 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4108 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4109 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4110 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4113 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4115 __codecvt_utf16
<char16_t
, true>::do_max_length() const noexcept
4117 if (__mode_
& consume_header
)
4121 _LIBCPP_SUPPRESS_DEPRECATED_POP
4123 // __codecvt_utf16<char32_t, false>
4125 __codecvt_utf16
<char32_t
, false>::result
4126 __codecvt_utf16
<char32_t
, false>::do_out(state_type
&,
4127 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4128 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4130 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4131 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4132 const uint32_t* _frm_nxt
= _frm
;
4133 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4134 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4135 uint8_t* _to_nxt
= _to
;
4136 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4137 __maxcode_
, __mode_
);
4138 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4139 to_nxt
= to
+ (_to_nxt
- _to
);
4143 __codecvt_utf16
<char32_t
, false>::result
4144 __codecvt_utf16
<char32_t
, false>::do_in(state_type
&,
4145 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4146 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4148 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4149 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4150 const uint8_t* _frm_nxt
= _frm
;
4151 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4152 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4153 uint32_t* _to_nxt
= _to
;
4154 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4155 __maxcode_
, __mode_
);
4156 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4157 to_nxt
= to
+ (_to_nxt
- _to
);
4161 __codecvt_utf16
<char32_t
, false>::result
4162 __codecvt_utf16
<char32_t
, false>::do_unshift(state_type
&,
4163 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4170 __codecvt_utf16
<char32_t
, false>::do_encoding() const noexcept
4176 __codecvt_utf16
<char32_t
, false>::do_always_noconv() const noexcept
4182 __codecvt_utf16
<char32_t
, false>::do_length(state_type
&,
4183 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4185 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4186 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4187 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4190 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4192 __codecvt_utf16
<char32_t
, false>::do_max_length() const noexcept
4194 if (__mode_
& consume_header
)
4198 _LIBCPP_SUPPRESS_DEPRECATED_POP
4200 // __codecvt_utf16<char32_t, true>
4202 __codecvt_utf16
<char32_t
, true>::result
4203 __codecvt_utf16
<char32_t
, true>::do_out(state_type
&,
4204 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4205 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4207 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4208 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4209 const uint32_t* _frm_nxt
= _frm
;
4210 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4211 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4212 uint8_t* _to_nxt
= _to
;
4213 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4214 __maxcode_
, __mode_
);
4215 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4216 to_nxt
= to
+ (_to_nxt
- _to
);
4220 __codecvt_utf16
<char32_t
, true>::result
4221 __codecvt_utf16
<char32_t
, true>::do_in(state_type
&,
4222 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4223 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4225 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4226 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4227 const uint8_t* _frm_nxt
= _frm
;
4228 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4229 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4230 uint32_t* _to_nxt
= _to
;
4231 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4232 __maxcode_
, __mode_
);
4233 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4234 to_nxt
= to
+ (_to_nxt
- _to
);
4238 __codecvt_utf16
<char32_t
, true>::result
4239 __codecvt_utf16
<char32_t
, true>::do_unshift(state_type
&,
4240 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4247 __codecvt_utf16
<char32_t
, true>::do_encoding() const noexcept
4253 __codecvt_utf16
<char32_t
, true>::do_always_noconv() const noexcept
4259 __codecvt_utf16
<char32_t
, true>::do_length(state_type
&,
4260 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4262 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4263 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4264 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4267 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4269 __codecvt_utf16
<char32_t
, true>::do_max_length() const noexcept
4271 if (__mode_
& consume_header
)
4275 _LIBCPP_SUPPRESS_DEPRECATED_POP
4277 // __codecvt_utf8_utf16<wchar_t>
4279 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4280 __codecvt_utf8_utf16
<wchar_t>::result
4281 __codecvt_utf8_utf16
<wchar_t>::do_out(state_type
&,
4282 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4283 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4285 #if defined(_LIBCPP_SHORT_WCHAR)
4286 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4287 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4288 const uint16_t* _frm_nxt
= _frm
;
4290 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4291 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4292 const uint32_t* _frm_nxt
= _frm
;
4294 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4295 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4296 uint8_t* _to_nxt
= _to
;
4297 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4298 __maxcode_
, __mode_
);
4299 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4300 to_nxt
= to
+ (_to_nxt
- _to
);
4304 __codecvt_utf8_utf16
<wchar_t>::result
4305 __codecvt_utf8_utf16
<wchar_t>::do_in(state_type
&,
4306 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4307 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4309 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4310 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4311 const uint8_t* _frm_nxt
= _frm
;
4312 #if defined(_LIBCPP_SHORT_WCHAR)
4313 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4314 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4315 uint16_t* _to_nxt
= _to
;
4317 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4318 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4319 uint32_t* _to_nxt
= _to
;
4321 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4322 __maxcode_
, __mode_
);
4323 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4324 to_nxt
= to
+ (_to_nxt
- _to
);
4328 __codecvt_utf8_utf16
<wchar_t>::result
4329 __codecvt_utf8_utf16
<wchar_t>::do_unshift(state_type
&,
4330 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4337 __codecvt_utf8_utf16
<wchar_t>::do_encoding() const noexcept
4343 __codecvt_utf8_utf16
<wchar_t>::do_always_noconv() const noexcept
4349 __codecvt_utf8_utf16
<wchar_t>::do_length(state_type
&,
4350 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4352 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4353 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4354 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4358 __codecvt_utf8_utf16
<wchar_t>::do_max_length() const noexcept
4360 if (__mode_
& consume_header
)
4364 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4366 // __codecvt_utf8_utf16<char16_t>
4368 __codecvt_utf8_utf16
<char16_t
>::result
4369 __codecvt_utf8_utf16
<char16_t
>::do_out(state_type
&,
4370 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4371 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4373 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4374 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4375 const uint16_t* _frm_nxt
= _frm
;
4376 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4377 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4378 uint8_t* _to_nxt
= _to
;
4379 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4380 __maxcode_
, __mode_
);
4381 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4382 to_nxt
= to
+ (_to_nxt
- _to
);
4386 __codecvt_utf8_utf16
<char16_t
>::result
4387 __codecvt_utf8_utf16
<char16_t
>::do_in(state_type
&,
4388 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4389 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4391 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4392 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4393 const uint8_t* _frm_nxt
= _frm
;
4394 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4395 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4396 uint16_t* _to_nxt
= _to
;
4397 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4398 __maxcode_
, __mode_
);
4399 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4400 to_nxt
= to
+ (_to_nxt
- _to
);
4404 __codecvt_utf8_utf16
<char16_t
>::result
4405 __codecvt_utf8_utf16
<char16_t
>::do_unshift(state_type
&,
4406 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4413 __codecvt_utf8_utf16
<char16_t
>::do_encoding() const noexcept
4419 __codecvt_utf8_utf16
<char16_t
>::do_always_noconv() const noexcept
4425 __codecvt_utf8_utf16
<char16_t
>::do_length(state_type
&,
4426 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4428 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4429 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4430 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4433 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4435 __codecvt_utf8_utf16
<char16_t
>::do_max_length() const noexcept
4437 if (__mode_
& consume_header
)
4441 _LIBCPP_SUPPRESS_DEPRECATED_POP
4443 // __codecvt_utf8_utf16<char32_t>
4445 __codecvt_utf8_utf16
<char32_t
>::result
4446 __codecvt_utf8_utf16
<char32_t
>::do_out(state_type
&,
4447 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4448 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4450 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4451 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4452 const uint32_t* _frm_nxt
= _frm
;
4453 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4454 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4455 uint8_t* _to_nxt
= _to
;
4456 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4457 __maxcode_
, __mode_
);
4458 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4459 to_nxt
= to
+ (_to_nxt
- _to
);
4463 __codecvt_utf8_utf16
<char32_t
>::result
4464 __codecvt_utf8_utf16
<char32_t
>::do_in(state_type
&,
4465 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4466 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4468 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4469 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4470 const uint8_t* _frm_nxt
= _frm
;
4471 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4472 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4473 uint32_t* _to_nxt
= _to
;
4474 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4475 __maxcode_
, __mode_
);
4476 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4477 to_nxt
= to
+ (_to_nxt
- _to
);
4481 __codecvt_utf8_utf16
<char32_t
>::result
4482 __codecvt_utf8_utf16
<char32_t
>::do_unshift(state_type
&,
4483 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4490 __codecvt_utf8_utf16
<char32_t
>::do_encoding() const noexcept
4496 __codecvt_utf8_utf16
<char32_t
>::do_always_noconv() const noexcept
4502 __codecvt_utf8_utf16
<char32_t
>::do_length(state_type
&,
4503 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4505 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4506 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4507 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4510 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4512 __codecvt_utf8_utf16
<char32_t
>::do_max_length() const noexcept
4514 if (__mode_
& consume_header
)
4518 _LIBCPP_SUPPRESS_DEPRECATED_POP
4520 // __narrow_to_utf8<16>
4522 __narrow_to_utf8
<16>::~__narrow_to_utf8()
4526 // __narrow_to_utf8<32>
4528 __narrow_to_utf8
<32>::~__narrow_to_utf8()
4532 // __widen_from_utf8<16>
4534 __widen_from_utf8
<16>::~__widen_from_utf8()
4538 // __widen_from_utf8<32>
4540 __widen_from_utf8
<32>::~__widen_from_utf8()
4544 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4545 static bool checked_string_to_wchar_convert(wchar_t& dest
,
4552 size_t ret
= __libcpp_mbrtowc_l(&out
, ptr
, strlen(ptr
), &mb
, loc
);
4553 if (ret
== static_cast<size_t>(-1) || ret
== static_cast<size_t>(-2)) {
4559 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4561 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4562 static bool is_narrow_non_breaking_space(const char* ptr
) {
4563 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4564 return ptr
[0] == '\xe2' && ptr
[1] == '\x80' && ptr
[2] == '\xaf';
4567 static bool is_non_breaking_space(const char* ptr
) {
4568 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4569 return ptr
[0] == '\xc2' && ptr
[1] == '\xa0';
4571 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4573 static bool checked_string_to_char_convert(char& dest
,
4583 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4584 // First convert the MBS into a wide char then attempt to narrow it using
4587 if (!checked_string_to_wchar_convert(wout
, ptr
, __loc
))
4590 if ((res
= __libcpp_wctob_l(wout
, __loc
)) != char_traits
<char>::eof()) {
4594 // FIXME: Work around specific multibyte sequences that we can reasonably
4595 // translate into a different single byte.
4597 case L
'\u202F': // narrow non-breaking space
4598 case L
'\u00A0': // non-breaking space
4604 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4605 // FIXME: Work around specific multibyte sequences that we can reasonably
4606 // translate into a different single byte.
4607 if (is_narrow_non_breaking_space(ptr
) || is_non_breaking_space(ptr
)) {
4613 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4614 __libcpp_unreachable();
4618 // numpunct<char> && numpunct<wchar_t>
4620 constinit
locale::id numpunct
<char>::id
;
4621 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4622 constinit
locale::id numpunct
<wchar_t>::id
;
4625 numpunct
<char>::numpunct(size_t refs
)
4626 : locale::facet(refs
),
4627 __decimal_point_('.'),
4628 __thousands_sep_(',')
4632 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4633 numpunct
<wchar_t>::numpunct(size_t refs
)
4634 : locale::facet(refs
),
4635 __decimal_point_(L
'.'),
4636 __thousands_sep_(L
',')
4641 numpunct
<char>::~numpunct()
4645 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4646 numpunct
<wchar_t>::~numpunct()
4651 char numpunct
< char >::do_decimal_point() const {return __decimal_point_
;}
4652 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4653 wchar_t numpunct
<wchar_t>::do_decimal_point() const {return __decimal_point_
;}
4656 char numpunct
< char >::do_thousands_sep() const {return __thousands_sep_
;}
4657 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4658 wchar_t numpunct
<wchar_t>::do_thousands_sep() const {return __thousands_sep_
;}
4661 string numpunct
< char >::do_grouping() const {return __grouping_
;}
4662 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4663 string numpunct
<wchar_t>::do_grouping() const {return __grouping_
;}
4666 string numpunct
< char >::do_truename() const {return "true";}
4667 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4668 wstring numpunct
<wchar_t>::do_truename() const {return L
"true";}
4671 string numpunct
< char >::do_falsename() const {return "false";}
4672 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4673 wstring numpunct
<wchar_t>::do_falsename() const {return L
"false";}
4676 // numpunct_byname<char>
4678 numpunct_byname
<char>::numpunct_byname(const char* nm
, size_t refs
)
4679 : numpunct
<char>(refs
)
4684 numpunct_byname
<char>::numpunct_byname(const string
& nm
, size_t refs
)
4685 : numpunct
<char>(refs
)
4690 numpunct_byname
<char>::~numpunct_byname()
4695 numpunct_byname
<char>::__init(const char* nm
)
4697 typedef numpunct
<char> base
;
4698 if (strcmp(nm
, "C") != 0)
4700 __libcpp_unique_locale
loc(nm
);
4702 __throw_runtime_error(("numpunct_byname<char>::numpunct_byname"
4703 " failed to construct for " + string(nm
)).c_str());
4705 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4706 if (!checked_string_to_char_convert(__decimal_point_
, lc
->decimal_point
,
4708 __decimal_point_
= base::do_decimal_point();
4709 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->thousands_sep
,
4711 __thousands_sep_
= base::do_thousands_sep();
4712 __grouping_
= lc
->grouping
;
4713 // localization for truename and falsename is not available
4717 // numpunct_byname<wchar_t>
4719 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4720 numpunct_byname
<wchar_t>::numpunct_byname(const char* nm
, size_t refs
)
4721 : numpunct
<wchar_t>(refs
)
4726 numpunct_byname
<wchar_t>::numpunct_byname(const string
& nm
, size_t refs
)
4727 : numpunct
<wchar_t>(refs
)
4732 numpunct_byname
<wchar_t>::~numpunct_byname()
4737 numpunct_byname
<wchar_t>::__init(const char* nm
)
4739 if (strcmp(nm
, "C") != 0)
4741 __libcpp_unique_locale
loc(nm
);
4743 __throw_runtime_error(("numpunct_byname<wchar_t>::numpunct_byname"
4744 " failed to construct for " + string(nm
)).c_str());
4746 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4747 checked_string_to_wchar_convert(__decimal_point_
, lc
->decimal_point
,
4749 checked_string_to_wchar_convert(__thousands_sep_
, lc
->thousands_sep
,
4751 __grouping_
= lc
->grouping
;
4752 // localization for truename and falsename is not available
4755 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4760 __num_get_base::__get_base(ios_base
& iob
)
4762 ios_base::fmtflags __basefield
= iob
.flags() & ios_base::basefield
;
4763 if (__basefield
== ios_base::oct
)
4765 else if (__basefield
== ios_base::hex
)
4767 else if (__basefield
== 0)
4772 const char __num_get_base::__src
[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4775 __check_grouping(const string
& __grouping
, unsigned* __g
, unsigned* __g_end
,
4776 ios_base::iostate
& __err
)
4778 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4779 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4780 if (__grouping
.size() != 0 && __g_end
- __g
> 1)
4782 reverse(__g
, __g_end
);
4783 const char* __ig
= __grouping
.data();
4784 const char* __eg
= __ig
+ __grouping
.size();
4785 for (unsigned* __r
= __g
; __r
< __g_end
-1; ++__r
)
4787 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4789 if (static_cast<unsigned>(*__ig
) != *__r
)
4791 __err
= ios_base::failbit
;
4795 if (__eg
- __ig
> 1)
4798 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4800 if (static_cast<unsigned>(*__ig
) < __g_end
[-1] || __g_end
[-1] == 0)
4801 __err
= ios_base::failbit
;
4807 __num_put_base::__format_int(char* __fmtp
, const char* __len
, bool __signd
,
4808 ios_base::fmtflags __flags
)
4810 if ((__flags
& ios_base::showpos
) &&
4811 (__flags
& ios_base::basefield
) != ios_base::oct
&&
4812 (__flags
& ios_base::basefield
) != ios_base::hex
&&
4815 if (__flags
& ios_base::showbase
)
4818 *__fmtp
++ = *__len
++;
4819 if ((__flags
& ios_base::basefield
) == ios_base::oct
)
4821 else if ((__flags
& ios_base::basefield
) == ios_base::hex
)
4823 if (__flags
& ios_base::uppercase
)
4835 __num_put_base::__format_float(char* __fmtp
, const char* __len
,
4836 ios_base::fmtflags __flags
)
4838 bool specify_precision
= true;
4839 if (__flags
& ios_base::showpos
)
4841 if (__flags
& ios_base::showpoint
)
4843 ios_base::fmtflags floatfield
= __flags
& ios_base::floatfield
;
4844 bool uppercase
= (__flags
& ios_base::uppercase
) != 0;
4845 if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4846 specify_precision
= false;
4853 *__fmtp
++ = *__len
++;
4854 if (floatfield
== ios_base::fixed
)
4861 else if (floatfield
== ios_base::scientific
)
4868 else if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4882 return specify_precision
;
4886 __num_put_base::__identify_padding(char* __nb
, char* __ne
,
4887 const ios_base
& __iob
)
4889 switch (__iob
.flags() & ios_base::adjustfield
)
4891 case ios_base::internal
:
4892 if (__nb
[0] == '-' || __nb
[0] == '+')
4894 if (__ne
- __nb
>= 2 && __nb
[0] == '0'
4895 && (__nb
[1] == 'x' || __nb
[1] == 'X'))
4898 case ios_base::left
:
4900 case ios_base::right
:
4913 static string weeks
[14];
4914 weeks
[0] = "Sunday";
4915 weeks
[1] = "Monday";
4916 weeks
[2] = "Tuesday";
4917 weeks
[3] = "Wednesday";
4918 weeks
[4] = "Thursday";
4919 weeks
[5] = "Friday";
4920 weeks
[6] = "Saturday";
4931 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4936 static wstring weeks
[14];
4937 weeks
[0] = L
"Sunday";
4938 weeks
[1] = L
"Monday";
4939 weeks
[2] = L
"Tuesday";
4940 weeks
[3] = L
"Wednesday";
4941 weeks
[4] = L
"Thursday";
4942 weeks
[5] = L
"Friday";
4943 weeks
[6] = L
"Saturday";
4957 __time_get_c_storage
<char>::__weeks() const
4959 static const string
* weeks
= init_weeks();
4963 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4966 __time_get_c_storage
<wchar_t>::__weeks() const
4968 static const wstring
* weeks
= init_wweeks();
4977 static string months
[24];
4978 months
[0] = "January";
4979 months
[1] = "February";
4980 months
[2] = "March";
4981 months
[3] = "April";
4985 months
[7] = "August";
4986 months
[8] = "September";
4987 months
[9] = "October";
4988 months
[10] = "November";
4989 months
[11] = "December";
5005 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5010 static wstring months
[24];
5011 months
[0] = L
"January";
5012 months
[1] = L
"February";
5013 months
[2] = L
"March";
5014 months
[3] = L
"April";
5016 months
[5] = L
"June";
5017 months
[6] = L
"July";
5018 months
[7] = L
"August";
5019 months
[8] = L
"September";
5020 months
[9] = L
"October";
5021 months
[10] = L
"November";
5022 months
[11] = L
"December";
5023 months
[12] = L
"Jan";
5024 months
[13] = L
"Feb";
5025 months
[14] = L
"Mar";
5026 months
[15] = L
"Apr";
5027 months
[16] = L
"May";
5028 months
[17] = L
"Jun";
5029 months
[18] = L
"Jul";
5030 months
[19] = L
"Aug";
5031 months
[20] = L
"Sep";
5032 months
[21] = L
"Oct";
5033 months
[22] = L
"Nov";
5034 months
[23] = L
"Dec";
5041 __time_get_c_storage
<char>::__months() const
5043 static const string
* months
= init_months();
5047 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5050 __time_get_c_storage
<wchar_t>::__months() const
5052 static const wstring
* months
= init_wmonths();
5061 static string am_pm
[2];
5067 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5072 static wstring am_pm
[2];
5081 __time_get_c_storage
<char>::__am_pm() const
5083 static const string
* am_pm
= init_am_pm();
5087 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5090 __time_get_c_storage
<wchar_t>::__am_pm() const
5092 static const wstring
* am_pm
= init_wam_pm();
5099 __time_get_c_storage
<char>::__x() const
5101 static string
s("%m/%d/%y");
5105 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5108 __time_get_c_storage
<wchar_t>::__x() const
5110 static wstring
s(L
"%m/%d/%y");
5117 __time_get_c_storage
<char>::__X() const
5119 static string
s("%H:%M:%S");
5123 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5126 __time_get_c_storage
<wchar_t>::__X() const
5128 static wstring
s(L
"%H:%M:%S");
5135 __time_get_c_storage
<char>::__c() const
5137 static string
s("%a %b %d %H:%M:%S %Y");
5141 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5144 __time_get_c_storage
<wchar_t>::__c() const
5146 static wstring
s(L
"%a %b %d %H:%M:%S %Y");
5153 __time_get_c_storage
<char>::__r() const
5155 static string
s("%I:%M:%S %p");
5159 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5162 __time_get_c_storage
<wchar_t>::__r() const
5164 static wstring
s(L
"%I:%M:%S %p");
5171 __time_get::__time_get(const char* nm
)
5172 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5175 __throw_runtime_error(("time_get_byname failed to construct for " + string(nm
)).c_str());
5178 __time_get::__time_get(const string
& nm
)
5179 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5182 __throw_runtime_error(("time_get_byname failed to construct for " + nm
).c_str());
5185 __time_get::~__time_get()
5190 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5194 __time_get_storage
<char>::__analyze(char fmt
, const ctype
<char>& ct
)
5210 size_t n
= strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5216 if (ct
.is(ctype_base::space
, *bb
))
5218 result
.push_back(' ');
5219 for (++bb
; bb
!= be
&& ct
.is(ctype_base::space
, *bb
); ++bb
)
5224 ios_base::iostate err
= ios_base::goodbit
;
5225 ptrdiff_t i
= __scan_keyword(w
, be
, this->__weeks_
, this->__weeks_
+14,
5230 result
.push_back('%');
5232 result
.push_back('A');
5234 result
.push_back('a');
5239 i
= __scan_keyword(w
, be
, this->__months_
, this->__months_
+24,
5244 result
.push_back('%');
5246 result
.push_back('B');
5248 result
.push_back('b');
5249 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5250 result
.back() = 'm';
5254 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5257 i
= __scan_keyword(w
, be
, this->__am_pm_
, this->__am_pm_
+2,
5258 ct
, err
, false) - this->__am_pm_
;
5261 result
.push_back('%');
5262 result
.push_back('p');
5268 if (ct
.is(ctype_base::digit
, *bb
))
5270 switch(__get_up_to_n_digits(bb
, be
, err
, ct
, 4))
5273 result
.push_back('%');
5274 result
.push_back('w');
5277 result
.push_back('%');
5278 result
.push_back('u');
5281 result
.push_back('%');
5282 result
.push_back('I');
5285 result
.push_back('%');
5286 result
.push_back('m');
5289 result
.push_back('%');
5290 result
.push_back('H');
5293 result
.push_back('%');
5294 result
.push_back('d');
5297 result
.push_back('%');
5298 result
.push_back('M');
5301 result
.push_back('%');
5302 result
.push_back('S');
5305 result
.push_back('%');
5306 result
.push_back('y');
5309 result
.push_back('%');
5310 result
.push_back('j');
5313 result
.push_back('%');
5314 result
.push_back('Y');
5317 for (; w
!= bb
; ++w
)
5318 result
.push_back(*w
);
5325 result
.push_back('%');
5326 result
.push_back('%');
5330 result
.push_back(*bb
);
5336 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5338 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5341 __time_get_storage
<wchar_t>::__analyze(char fmt
, const ctype
<wchar_t>& ct
)
5357 strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5359 wchar_t* wbb
= wbuf
;
5361 const char* bb
= buf
;
5362 size_t j
= __libcpp_mbsrtowcs_l( wbb
, &bb
, countof(wbuf
), &mb
, __loc_
);
5363 if (j
== size_t(-1))
5364 __throw_runtime_error("locale not supported");
5365 wchar_t* wbe
= wbb
+ j
;
5369 if (ct
.is(ctype_base::space
, *wbb
))
5371 result
.push_back(L
' ');
5372 for (++wbb
; wbb
!= wbe
&& ct
.is(ctype_base::space
, *wbb
); ++wbb
)
5377 ios_base::iostate err
= ios_base::goodbit
;
5378 ptrdiff_t i
= __scan_keyword(w
, wbe
, this->__weeks_
, this->__weeks_
+14,
5383 result
.push_back(L
'%');
5385 result
.push_back(L
'A');
5387 result
.push_back(L
'a');
5392 i
= __scan_keyword(w
, wbe
, this->__months_
, this->__months_
+24,
5397 result
.push_back(L
'%');
5399 result
.push_back(L
'B');
5401 result
.push_back(L
'b');
5402 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5403 result
.back() = L
'm';
5407 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5410 i
= __scan_keyword(w
, wbe
, this->__am_pm_
, this->__am_pm_
+2,
5411 ct
, err
, false) - this->__am_pm_
;
5414 result
.push_back(L
'%');
5415 result
.push_back(L
'p');
5421 if (ct
.is(ctype_base::digit
, *wbb
))
5423 switch(__get_up_to_n_digits(wbb
, wbe
, err
, ct
, 4))
5426 result
.push_back(L
'%');
5427 result
.push_back(L
'w');
5430 result
.push_back(L
'%');
5431 result
.push_back(L
'u');
5434 result
.push_back(L
'%');
5435 result
.push_back(L
'I');
5438 result
.push_back(L
'%');
5439 result
.push_back(L
'm');
5442 result
.push_back(L
'%');
5443 result
.push_back(L
'H');
5446 result
.push_back(L
'%');
5447 result
.push_back(L
'd');
5450 result
.push_back(L
'%');
5451 result
.push_back(L
'M');
5454 result
.push_back(L
'%');
5455 result
.push_back(L
'S');
5458 result
.push_back(L
'%');
5459 result
.push_back(L
'y');
5462 result
.push_back(L
'%');
5463 result
.push_back(L
'j');
5466 result
.push_back(L
'%');
5467 result
.push_back(L
'Y');
5470 for (; w
!= wbb
; ++w
)
5471 result
.push_back(*w
);
5476 if (ct
.narrow(*wbb
, 0) == '%')
5478 result
.push_back(L
'%');
5479 result
.push_back(L
'%');
5483 result
.push_back(*wbb
);
5488 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5492 __time_get_storage
<char>::init(const ctype
<char>& ct
)
5497 for (int i
= 0; i
< 7; ++i
)
5500 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5502 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5503 __weeks_
[i
+7] = buf
;
5506 for (int i
= 0; i
< 12; ++i
)
5509 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5511 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5512 __months_
[i
+12] = buf
;
5516 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5519 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5521 __c_
= __analyze('c', ct
);
5522 __r_
= __analyze('r', ct
);
5523 __x_
= __analyze('x', ct
);
5524 __X_
= __analyze('X', ct
);
5527 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5530 __time_get_storage
<wchar_t>::init(const ctype
<wchar_t>& ct
)
5538 for (int i
= 0; i
< 7; ++i
)
5541 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5543 const char* bb
= buf
;
5544 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5545 if (j
== size_t(-1) || j
== 0)
5546 __throw_runtime_error("locale not supported");
5548 __weeks_
[i
].assign(wbuf
, wbe
);
5549 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5552 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5553 if (j
== size_t(-1) || j
== 0)
5554 __throw_runtime_error("locale not supported");
5556 __weeks_
[i
+7].assign(wbuf
, wbe
);
5559 for (int i
= 0; i
< 12; ++i
)
5562 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5564 const char* bb
= buf
;
5565 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5566 if (j
== size_t(-1) || j
== 0)
5567 __throw_runtime_error("locale not supported");
5569 __months_
[i
].assign(wbuf
, wbe
);
5570 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5573 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5574 if (j
== size_t(-1) || j
== 0)
5575 __throw_runtime_error("locale not supported");
5577 __months_
[i
+12].assign(wbuf
, wbe
);
5581 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5583 const char* bb
= buf
;
5584 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5585 if (j
== size_t(-1))
5586 __throw_runtime_error("locale not supported");
5588 __am_pm_
[0].assign(wbuf
, wbe
);
5590 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5593 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5594 if (j
== size_t(-1))
5595 __throw_runtime_error("locale not supported");
5597 __am_pm_
[1].assign(wbuf
, wbe
);
5598 __c_
= __analyze('c', ct
);
5599 __r_
= __analyze('r', ct
);
5600 __x_
= __analyze('x', ct
);
5601 __X_
= __analyze('X', ct
);
5603 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5605 template <class CharT
>
5606 struct _LIBCPP_HIDDEN __time_get_temp
5607 : public ctype_byname
<CharT
>
5609 explicit __time_get_temp(const char* nm
)
5610 : ctype_byname
<CharT
>(nm
, 1) {}
5611 explicit __time_get_temp(const string
& nm
)
5612 : ctype_byname
<CharT
>(nm
, 1) {}
5616 __time_get_storage
<char>::__time_get_storage(const char* __nm
)
5619 const __time_get_temp
<char> ct(__nm
);
5624 __time_get_storage
<char>::__time_get_storage(const string
& __nm
)
5627 const __time_get_temp
<char> ct(__nm
);
5631 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5633 __time_get_storage
<wchar_t>::__time_get_storage(const char* __nm
)
5636 const __time_get_temp
<wchar_t> ct(__nm
);
5641 __time_get_storage
<wchar_t>::__time_get_storage(const string
& __nm
)
5644 const __time_get_temp
<wchar_t> ct(__nm
);
5647 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5650 time_base::dateorder
5651 __time_get_storage
<char>::__do_date_order() const
5654 for (i
= 0; i
< __x_
.size(); ++i
)
5662 for (++i
; i
< __x_
.size(); ++i
)
5665 if (i
== __x_
.size())
5671 for (++i
; i
< __x_
.size(); ++i
)
5674 if (i
== __x_
.size())
5678 return time_base::ymd
;
5681 for (++i
; i
< __x_
.size(); ++i
)
5684 if (i
== __x_
.size())
5688 return time_base::ydm
;
5693 for (++i
; i
< __x_
.size(); ++i
)
5696 if (i
== __x_
.size())
5701 for (++i
; i
< __x_
.size(); ++i
)
5704 if (i
== __x_
.size())
5707 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5708 return time_base::mdy
;
5713 for (++i
; i
< __x_
.size(); ++i
)
5716 if (i
== __x_
.size())
5721 for (++i
; i
< __x_
.size(); ++i
)
5724 if (i
== __x_
.size())
5727 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5728 return time_base::dmy
;
5733 return time_base::no_order
;
5736 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5738 time_base::dateorder
5739 __time_get_storage
<wchar_t>::__do_date_order() const
5742 for (i
= 0; i
< __x_
.size(); ++i
)
5743 if (__x_
[i
] == L
'%')
5750 for (++i
; i
< __x_
.size(); ++i
)
5751 if (__x_
[i
] == L
'%')
5753 if (i
== __x_
.size())
5759 for (++i
; i
< __x_
.size(); ++i
)
5760 if (__x_
[i
] == L
'%')
5762 if (i
== __x_
.size())
5765 if (__x_
[i
] == L
'd')
5766 return time_base::ymd
;
5769 for (++i
; i
< __x_
.size(); ++i
)
5770 if (__x_
[i
] == L
'%')
5772 if (i
== __x_
.size())
5775 if (__x_
[i
] == L
'm')
5776 return time_base::ydm
;
5781 for (++i
; i
< __x_
.size(); ++i
)
5782 if (__x_
[i
] == L
'%')
5784 if (i
== __x_
.size())
5787 if (__x_
[i
] == L
'd')
5789 for (++i
; i
< __x_
.size(); ++i
)
5790 if (__x_
[i
] == L
'%')
5792 if (i
== __x_
.size())
5795 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5796 return time_base::mdy
;
5801 for (++i
; i
< __x_
.size(); ++i
)
5802 if (__x_
[i
] == L
'%')
5804 if (i
== __x_
.size())
5807 if (__x_
[i
] == L
'm')
5809 for (++i
; i
< __x_
.size(); ++i
)
5810 if (__x_
[i
] == L
'%')
5812 if (i
== __x_
.size())
5815 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5816 return time_base::dmy
;
5821 return time_base::no_order
;
5823 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5827 __time_put::__time_put(const char* nm
)
5828 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5831 __throw_runtime_error(("time_put_byname failed to construct for " + string(nm
)).c_str());
5834 __time_put::__time_put(const string
& nm
)
5835 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5838 __throw_runtime_error(("time_put_byname failed to construct for " + nm
).c_str());
5841 __time_put::~__time_put()
5843 if (__loc_
!= _LIBCPP_GET_C_LOCALE
)
5848 __time_put::__do_put(char* __nb
, char*& __ne
, const tm
* __tm
,
5849 char __fmt
, char __mod
) const
5851 char fmt
[] = {'%', __fmt
, __mod
, 0};
5853 swap(fmt
[1], fmt
[2]);
5854 size_t n
= strftime_l(__nb
, countof(__nb
, __ne
), fmt
, __tm
, __loc_
);
5858 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5860 __time_put::__do_put(wchar_t* __wb
, wchar_t*& __we
, const tm
* __tm
,
5861 char __fmt
, char __mod
) const
5864 char* __ne
= __nar
+ 100;
5865 __do_put(__nar
, __ne
, __tm
, __fmt
, __mod
);
5867 const char* __nb
= __nar
;
5868 size_t j
= __libcpp_mbsrtowcs_l(__wb
, &__nb
, countof(__wb
, __we
), &mb
, __loc_
);
5869 if (j
== size_t(-1))
5870 __throw_runtime_error("locale not supported");
5873 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5875 // moneypunct_byname
5877 template <class charT
>
5880 __init_pat(money_base::pattern
& pat
, basic_string
<charT
>& __curr_symbol_
,
5881 bool intl
, char cs_precedes
, char sep_by_space
, char sign_posn
,
5884 const char sign
= static_cast<char>(money_base::sign
);
5885 const char space
= static_cast<char>(money_base::space
);
5886 const char none
= static_cast<char>(money_base::none
);
5887 const char symbol
= static_cast<char>(money_base::symbol
);
5888 const char value
= static_cast<char>(money_base::value
);
5889 const bool symbol_contains_sep
= intl
&& __curr_symbol_
.size() == 4;
5891 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5892 // function'. "Space between sign and symbol or value" means that
5893 // if the sign is adjacent to the symbol, there's a space between
5894 // them, and otherwise there's a space between the sign and value.
5896 // C11's localeconv specifies that the fourth character of an
5897 // international curr_symbol is used to separate the sign and
5898 // value when sep_by_space says to do so. C++ can't represent
5899 // that, so we just use a space. When sep_by_space says to
5900 // separate the symbol and value-or-sign with a space, we rearrange the
5901 // curr_symbol to put its spacing character on the correct side of
5904 // We also need to avoid adding an extra space between the sign
5905 // and value when the currency symbol is suppressed (by not
5906 // setting showbase). We match glibc's strfmon by interpreting
5907 // sep_by_space==1 as "omit the space when the currency symbol is
5910 // Users who want to get this right should use ICU instead.
5912 switch (cs_precedes
)
5914 case 0: // value before curr_symbol
5915 if (symbol_contains_sep
) {
5916 // Move the separator to before the symbol, to place it
5917 // between the value and symbol.
5918 rotate(__curr_symbol_
.begin(), __curr_symbol_
.begin() + 3,
5919 __curr_symbol_
.end());
5923 case 0: // Parentheses surround the quantity and currency symbol.
5924 pat
.field
[0] = sign
;
5925 pat
.field
[1] = value
;
5926 pat
.field
[2] = none
; // Any space appears in the symbol.
5927 pat
.field
[3] = symbol
;
5928 switch (sep_by_space
)
5930 case 0: // No space separates the currency symbol and value.
5931 // This case may have changed between C99 and C11;
5932 // assume the currency symbol matches the intention.
5933 case 2: // Space between sign and currency or value.
5934 // The "sign" is two parentheses, so no space here either.
5936 case 1: // Space between currency-and-sign or currency and value.
5937 if (!symbol_contains_sep
) {
5938 // We insert the space into the symbol instead of
5939 // setting pat.field[2]=space so that when
5940 // showbase is not set, the space goes away too.
5941 __curr_symbol_
.insert(0, 1, space_char
);
5948 case 1: // The sign string precedes the quantity and currency symbol.
5949 pat
.field
[0] = sign
;
5950 pat
.field
[3] = symbol
;
5951 switch (sep_by_space
)
5953 case 0: // No space separates the currency symbol and value.
5954 pat
.field
[1] = value
;
5955 pat
.field
[2] = none
;
5957 case 1: // Space between currency-and-sign or currency and value.
5958 pat
.field
[1] = value
;
5959 pat
.field
[2] = none
;
5960 if (!symbol_contains_sep
) {
5961 // We insert the space into the symbol instead of
5962 // setting pat.field[2]=space so that when
5963 // showbase is not set, the space goes away too.
5964 __curr_symbol_
.insert(0, 1, space_char
);
5967 case 2: // Space between sign and currency or value.
5968 pat
.field
[1] = space
;
5969 pat
.field
[2] = value
;
5970 if (symbol_contains_sep
) {
5971 // Remove the separator from the symbol, since it
5972 // has already appeared after the sign.
5973 __curr_symbol_
.erase(__curr_symbol_
.begin());
5980 case 2: // The sign string succeeds the quantity and currency symbol.
5981 pat
.field
[0] = value
;
5982 pat
.field
[3] = sign
;
5983 switch (sep_by_space
)
5985 case 0: // No space separates the currency symbol and value.
5986 pat
.field
[1] = none
;
5987 pat
.field
[2] = symbol
;
5989 case 1: // Space between currency-and-sign or currency and value.
5990 if (!symbol_contains_sep
) {
5991 // We insert the space into the symbol instead of
5992 // setting pat.field[1]=space so that when
5993 // showbase is not set, the space goes away too.
5994 __curr_symbol_
.insert(0, 1, space_char
);
5996 pat
.field
[1] = none
;
5997 pat
.field
[2] = symbol
;
5999 case 2: // Space between sign and currency or value.
6000 pat
.field
[1] = symbol
;
6001 pat
.field
[2] = space
;
6002 if (symbol_contains_sep
) {
6003 // Remove the separator from the symbol, since it
6004 // should not be removed if showbase is absent.
6005 __curr_symbol_
.erase(__curr_symbol_
.begin());
6012 case 3: // The sign string immediately precedes the currency symbol.
6013 pat
.field
[0] = value
;
6014 pat
.field
[3] = symbol
;
6015 switch (sep_by_space
)
6017 case 0: // No space separates the currency symbol and value.
6018 pat
.field
[1] = none
;
6019 pat
.field
[2] = sign
;
6021 case 1: // Space between currency-and-sign or currency and value.
6022 pat
.field
[1] = space
;
6023 pat
.field
[2] = sign
;
6024 if (symbol_contains_sep
) {
6025 // Remove the separator from the symbol, since it
6026 // has already appeared before the sign.
6027 __curr_symbol_
.erase(__curr_symbol_
.begin());
6030 case 2: // Space between sign and currency or value.
6031 pat
.field
[1] = sign
;
6032 pat
.field
[2] = none
;
6033 if (!symbol_contains_sep
) {
6034 // We insert the space into the symbol instead of
6035 // setting pat.field[2]=space so that when
6036 // showbase is not set, the space goes away too.
6037 __curr_symbol_
.insert(0, 1, space_char
);
6044 case 4: // The sign string immediately succeeds the currency symbol.
6045 pat
.field
[0] = value
;
6046 pat
.field
[3] = sign
;
6047 switch (sep_by_space
)
6049 case 0: // No space separates the currency symbol and value.
6050 pat
.field
[1] = none
;
6051 pat
.field
[2] = symbol
;
6053 case 1: // Space between currency-and-sign or currency and value.
6054 pat
.field
[1] = none
;
6055 pat
.field
[2] = symbol
;
6056 if (!symbol_contains_sep
) {
6057 // We insert the space into the symbol instead of
6058 // setting pat.field[1]=space so that when
6059 // showbase is not set, the space goes away too.
6060 __curr_symbol_
.insert(0, 1, space_char
);
6063 case 2: // Space between sign and currency or value.
6064 pat
.field
[1] = symbol
;
6065 pat
.field
[2] = space
;
6066 if (symbol_contains_sep
) {
6067 // Remove the separator from the symbol, since it
6068 // should not disappear when showbase is absent.
6069 __curr_symbol_
.erase(__curr_symbol_
.begin());
6080 case 1: // curr_symbol before value
6083 case 0: // Parentheses surround the quantity and currency symbol.
6084 pat
.field
[0] = sign
;
6085 pat
.field
[1] = symbol
;
6086 pat
.field
[2] = none
; // Any space appears in the symbol.
6087 pat
.field
[3] = value
;
6088 switch (sep_by_space
)
6090 case 0: // No space separates the currency symbol and value.
6091 // This case may have changed between C99 and C11;
6092 // assume the currency symbol matches the intention.
6093 case 2: // Space between sign and currency or value.
6094 // The "sign" is two parentheses, so no space here either.
6096 case 1: // Space between currency-and-sign or currency and value.
6097 if (!symbol_contains_sep
) {
6098 // We insert the space into the symbol instead of
6099 // setting pat.field[2]=space so that when
6100 // showbase is not set, the space goes away too.
6101 __curr_symbol_
.insert(0, 1, space_char
);
6108 case 1: // The sign string precedes the quantity and currency symbol.
6109 pat
.field
[0] = sign
;
6110 pat
.field
[3] = value
;
6111 switch (sep_by_space
)
6113 case 0: // No space separates the currency symbol and value.
6114 pat
.field
[1] = symbol
;
6115 pat
.field
[2] = none
;
6117 case 1: // Space between currency-and-sign or currency and value.
6118 pat
.field
[1] = symbol
;
6119 pat
.field
[2] = none
;
6120 if (!symbol_contains_sep
) {
6121 // We insert the space into the symbol instead of
6122 // setting pat.field[2]=space so that when
6123 // showbase is not set, the space goes away too.
6124 __curr_symbol_
.push_back(space_char
);
6127 case 2: // Space between sign and currency or value.
6128 pat
.field
[1] = space
;
6129 pat
.field
[2] = symbol
;
6130 if (symbol_contains_sep
) {
6131 // Remove the separator from the symbol, since it
6132 // has already appeared after the sign.
6133 __curr_symbol_
.pop_back();
6140 case 2: // The sign string succeeds the quantity and currency symbol.
6141 pat
.field
[0] = symbol
;
6142 pat
.field
[3] = sign
;
6143 switch (sep_by_space
)
6145 case 0: // No space separates the currency symbol and value.
6146 pat
.field
[1] = none
;
6147 pat
.field
[2] = value
;
6149 case 1: // Space between currency-and-sign or currency and value.
6150 pat
.field
[1] = none
;
6151 pat
.field
[2] = value
;
6152 if (!symbol_contains_sep
) {
6153 // We insert the space into the symbol instead of
6154 // setting pat.field[1]=space so that when
6155 // showbase is not set, the space goes away too.
6156 __curr_symbol_
.push_back(space_char
);
6159 case 2: // Space between sign and currency or value.
6160 pat
.field
[1] = value
;
6161 pat
.field
[2] = space
;
6162 if (symbol_contains_sep
) {
6163 // Remove the separator from the symbol, since it
6164 // will appear before the sign.
6165 __curr_symbol_
.pop_back();
6172 case 3: // The sign string immediately precedes the currency symbol.
6173 pat
.field
[0] = sign
;
6174 pat
.field
[3] = value
;
6175 switch (sep_by_space
)
6177 case 0: // No space separates the currency symbol and value.
6178 pat
.field
[1] = symbol
;
6179 pat
.field
[2] = none
;
6181 case 1: // Space between currency-and-sign or currency and value.
6182 pat
.field
[1] = symbol
;
6183 pat
.field
[2] = none
;
6184 if (!symbol_contains_sep
) {
6185 // We insert the space into the symbol instead of
6186 // setting pat.field[2]=space so that when
6187 // showbase is not set, the space goes away too.
6188 __curr_symbol_
.push_back(space_char
);
6191 case 2: // Space between sign and currency or value.
6192 pat
.field
[1] = space
;
6193 pat
.field
[2] = symbol
;
6194 if (symbol_contains_sep
) {
6195 // Remove the separator from the symbol, since it
6196 // has already appeared after the sign.
6197 __curr_symbol_
.pop_back();
6204 case 4: // The sign string immediately succeeds the currency symbol.
6205 pat
.field
[0] = symbol
;
6206 pat
.field
[3] = value
;
6207 switch (sep_by_space
)
6209 case 0: // No space separates the currency symbol and value.
6210 pat
.field
[1] = sign
;
6211 pat
.field
[2] = none
;
6213 case 1: // Space between currency-and-sign or currency and value.
6214 pat
.field
[1] = sign
;
6215 pat
.field
[2] = space
;
6216 if (symbol_contains_sep
) {
6217 // Remove the separator from the symbol, since it
6218 // should not disappear when showbase is absent.
6219 __curr_symbol_
.pop_back();
6222 case 2: // Space between sign and currency or value.
6223 pat
.field
[1] = none
;
6224 pat
.field
[2] = sign
;
6225 if (!symbol_contains_sep
) {
6226 // We insert the space into the symbol instead of
6227 // setting pat.field[1]=space so that when
6228 // showbase is not set, the space goes away too.
6229 __curr_symbol_
.push_back(space_char
);
6243 pat
.field
[0] = symbol
;
6244 pat
.field
[1] = sign
;
6245 pat
.field
[2] = none
;
6246 pat
.field
[3] = value
;
6251 moneypunct_byname
<char, false>::init(const char* nm
)
6253 typedef moneypunct
<char, false> base
;
6254 __libcpp_unique_locale
loc(nm
);
6256 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6258 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6259 if (!checked_string_to_char_convert(__decimal_point_
,
6260 lc
->mon_decimal_point
,
6262 __decimal_point_
= base::do_decimal_point();
6263 if (!checked_string_to_char_convert(__thousands_sep_
,
6264 lc
->mon_thousands_sep
,
6266 __thousands_sep_
= base::do_thousands_sep();
6268 __grouping_
= lc
->mon_grouping
;
6269 __curr_symbol_
= lc
->currency_symbol
;
6270 if (lc
->frac_digits
!= CHAR_MAX
)
6271 __frac_digits_
= lc
->frac_digits
;
6273 __frac_digits_
= base::do_frac_digits();
6274 if (lc
->p_sign_posn
== 0)
6275 __positive_sign_
= "()";
6277 __positive_sign_
= lc
->positive_sign
;
6278 if (lc
->n_sign_posn
== 0)
6279 __negative_sign_
= "()";
6281 __negative_sign_
= lc
->negative_sign
;
6282 // Assume the positive and negative formats will want spaces in
6283 // the same places in curr_symbol since there's no way to
6284 // represent anything else.
6285 string_type __dummy_curr_symbol
= __curr_symbol_
;
6286 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6287 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6288 __init_pat(__neg_format_
, __curr_symbol_
, false,
6289 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6294 moneypunct_byname
<char, true>::init(const char* nm
)
6296 typedef moneypunct
<char, true> base
;
6297 __libcpp_unique_locale
loc(nm
);
6299 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6301 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6302 if (!checked_string_to_char_convert(__decimal_point_
,
6303 lc
->mon_decimal_point
,
6305 __decimal_point_
= base::do_decimal_point();
6306 if (!checked_string_to_char_convert(__thousands_sep_
,
6307 lc
->mon_thousands_sep
,
6309 __thousands_sep_
= base::do_thousands_sep();
6310 __grouping_
= lc
->mon_grouping
;
6311 __curr_symbol_
= lc
->int_curr_symbol
;
6312 if (lc
->int_frac_digits
!= CHAR_MAX
)
6313 __frac_digits_
= lc
->int_frac_digits
;
6315 __frac_digits_
= base::do_frac_digits();
6316 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6317 if (lc
->p_sign_posn
== 0)
6318 #else // _LIBCPP_MSVCRT
6319 if (lc
->int_p_sign_posn
== 0)
6320 #endif // !_LIBCPP_MSVCRT
6321 __positive_sign_
= "()";
6323 __positive_sign_
= lc
->positive_sign
;
6324 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6325 if(lc
->n_sign_posn
== 0)
6326 #else // _LIBCPP_MSVCRT
6327 if (lc
->int_n_sign_posn
== 0)
6328 #endif // !_LIBCPP_MSVCRT
6329 __negative_sign_
= "()";
6331 __negative_sign_
= lc
->negative_sign
;
6332 // Assume the positive and negative formats will want spaces in
6333 // the same places in curr_symbol since there's no way to
6334 // represent anything else.
6335 string_type __dummy_curr_symbol
= __curr_symbol_
;
6336 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6337 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6338 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6339 __init_pat(__neg_format_
, __curr_symbol_
, true,
6340 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6341 #else // _LIBCPP_MSVCRT
6342 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6343 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6344 lc
->int_p_sign_posn
, ' ');
6345 __init_pat(__neg_format_
, __curr_symbol_
, true,
6346 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6347 lc
->int_n_sign_posn
, ' ');
6348 #endif // !_LIBCPP_MSVCRT
6351 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6354 moneypunct_byname
<wchar_t, false>::init(const char* nm
)
6356 typedef moneypunct
<wchar_t, false> base
;
6357 __libcpp_unique_locale
loc(nm
);
6359 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6360 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6361 if (!checked_string_to_wchar_convert(__decimal_point_
,
6362 lc
->mon_decimal_point
,
6364 __decimal_point_
= base::do_decimal_point();
6365 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6366 lc
->mon_thousands_sep
,
6368 __thousands_sep_
= base::do_thousands_sep();
6369 __grouping_
= lc
->mon_grouping
;
6372 const char* bb
= lc
->currency_symbol
;
6373 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6374 if (j
== size_t(-1))
6375 __throw_runtime_error("locale not supported");
6376 wchar_t* wbe
= wbuf
+ j
;
6377 __curr_symbol_
.assign(wbuf
, wbe
);
6378 if (lc
->frac_digits
!= CHAR_MAX
)
6379 __frac_digits_
= lc
->frac_digits
;
6381 __frac_digits_
= base::do_frac_digits();
6382 if (lc
->p_sign_posn
== 0)
6383 __positive_sign_
= L
"()";
6387 bb
= lc
->positive_sign
;
6388 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6389 if (j
== size_t(-1))
6390 __throw_runtime_error("locale not supported");
6392 __positive_sign_
.assign(wbuf
, wbe
);
6394 if (lc
->n_sign_posn
== 0)
6395 __negative_sign_
= L
"()";
6399 bb
= lc
->negative_sign
;
6400 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6401 if (j
== size_t(-1))
6402 __throw_runtime_error("locale not supported");
6404 __negative_sign_
.assign(wbuf
, wbe
);
6406 // Assume the positive and negative formats will want spaces in
6407 // the same places in curr_symbol since there's no way to
6408 // represent anything else.
6409 string_type __dummy_curr_symbol
= __curr_symbol_
;
6410 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6411 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6412 __init_pat(__neg_format_
, __curr_symbol_
, false,
6413 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6418 moneypunct_byname
<wchar_t, true>::init(const char* nm
)
6420 typedef moneypunct
<wchar_t, true> base
;
6421 __libcpp_unique_locale
loc(nm
);
6423 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6425 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6426 if (!checked_string_to_wchar_convert(__decimal_point_
,
6427 lc
->mon_decimal_point
,
6429 __decimal_point_
= base::do_decimal_point();
6430 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6431 lc
->mon_thousands_sep
,
6433 __thousands_sep_
= base::do_thousands_sep();
6434 __grouping_
= lc
->mon_grouping
;
6437 const char* bb
= lc
->int_curr_symbol
;
6438 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6439 if (j
== size_t(-1))
6440 __throw_runtime_error("locale not supported");
6441 wchar_t* wbe
= wbuf
+ j
;
6442 __curr_symbol_
.assign(wbuf
, wbe
);
6443 if (lc
->int_frac_digits
!= CHAR_MAX
)
6444 __frac_digits_
= lc
->int_frac_digits
;
6446 __frac_digits_
= base::do_frac_digits();
6447 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6448 if (lc
->p_sign_posn
== 0)
6449 #else // _LIBCPP_MSVCRT
6450 if (lc
->int_p_sign_posn
== 0)
6451 #endif // !_LIBCPP_MSVCRT
6452 __positive_sign_
= L
"()";
6456 bb
= lc
->positive_sign
;
6457 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6458 if (j
== size_t(-1))
6459 __throw_runtime_error("locale not supported");
6461 __positive_sign_
.assign(wbuf
, wbe
);
6463 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6464 if (lc
->n_sign_posn
== 0)
6465 #else // _LIBCPP_MSVCRT
6466 if (lc
->int_n_sign_posn
== 0)
6467 #endif // !_LIBCPP_MSVCRT
6468 __negative_sign_
= L
"()";
6472 bb
= lc
->negative_sign
;
6473 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6474 if (j
== size_t(-1))
6475 __throw_runtime_error("locale not supported");
6477 __negative_sign_
.assign(wbuf
, wbe
);
6479 // Assume the positive and negative formats will want spaces in
6480 // the same places in curr_symbol since there's no way to
6481 // represent anything else.
6482 string_type __dummy_curr_symbol
= __curr_symbol_
;
6483 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6484 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6485 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6486 __init_pat(__neg_format_
, __curr_symbol_
, true,
6487 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6488 #else // _LIBCPP_MSVCRT
6489 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6490 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6491 lc
->int_p_sign_posn
, L
' ');
6492 __init_pat(__neg_format_
, __curr_symbol_
, true,
6493 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6494 lc
->int_n_sign_posn
, L
' ');
6495 #endif // !_LIBCPP_MSVCRT
6497 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6499 void __do_nothing(void*) {}
6501 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<char>;
6502 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<wchar_t>;)
6504 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<char>;
6505 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<wchar_t>;)
6507 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<char>;
6508 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<wchar_t>;)
6510 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<char>;
6511 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<wchar_t>;)
6513 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<char>;
6514 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<wchar_t>;)
6516 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<char>;
6517 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<wchar_t>;)
6519 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<char>;
6520 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<wchar_t>;)
6522 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<char>;
6523 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<wchar_t>;)
6525 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<char>;
6526 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<wchar_t>;)
6528 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, false>;
6529 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, true>;
6530 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, false>;)
6531 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, true>;)
6533 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, false>;
6534 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, true>;
6535 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, false>;)
6536 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, true>;)
6538 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<char>;
6539 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<wchar_t>;)
6541 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<char>;
6542 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<wchar_t>;)
6544 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<char>;
6545 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<wchar_t>;)
6547 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<char>;
6548 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<wchar_t>;)
6550 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<char>;
6551 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<wchar_t>;)
6553 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<char>;
6554 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<wchar_t>;)
6556 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char, char, mbstate_t>;
6557 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<wchar_t, char, mbstate_t>;)
6558 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char, mbstate_t>;
6559 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char, mbstate_t>;
6560 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6561 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char8_t
, mbstate_t>;
6562 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char8_t
, mbstate_t>;
6565 _LIBCPP_END_NAMESPACE_STD