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/unreachable.h>
18 #include <type_traits>
22 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
27 # include <sys/localedef.h> // for __lc_ctype_ptr
30 #if defined(_LIBCPP_MSVCRT)
31 # define _CTYPE_DISABLE_MACROS
34 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
35 # include "__support/win32/locale_win32.h"
36 #elif !defined(__BIONIC__) && !defined(__NuttX__)
37 # include <langinfo.h>
40 #include "include/atomic_support.h"
41 #include "include/sso_allocator.h"
43 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
44 // lots of noise in the build log, but no bugs that I know of.
45 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
48 #include <__undef_macros>
50 _LIBCPP_BEGIN_NAMESPACE_STD
52 struct __libcpp_unique_locale
{
53 __libcpp_unique_locale(const char* nm
) : __loc_(newlocale(LC_ALL_MASK
, nm
, 0)) {}
55 ~__libcpp_unique_locale() {
60 explicit operator bool() const { return __loc_
; }
62 locale_t
& get() { return __loc_
; }
66 __libcpp_unique_locale(__libcpp_unique_locale
const&);
67 __libcpp_unique_locale
& operator=(__libcpp_unique_locale
const&);
72 // In theory this could create a race condition. In practice
73 // the race condition is non-fatal since it will just create
74 // a little resource leak. Better approach would be appreciated.
75 static locale_t result
= newlocale(LC_ALL_MASK
, "C", 0);
78 #endif // __cloc_defined
84 void operator()(locale::facet
* p
) {p
->__release_shared();}
87 template <class T
, class ...Args
>
90 static typename aligned_storage
<sizeof(T
)>::type buf
;
91 auto *obj
= ::new (&buf
) T(args
...);
95 template <typename T
, size_t N
>
99 countof(const T (&)[N
])
104 template <typename T
>
108 countof(const T
* const begin
, const T
* const end
)
110 return static_cast<size_t>(end
- begin
);
116 build_name(const string
& other
, const string
& one
, locale::category c
) {
117 if (other
== "*" || one
== "*")
119 if (c
== locale::none
|| other
== one
)
122 // FIXME: Handle the more complicated cases, such as when the locale has
123 // different names for different categories.
127 const locale::category
locale::none
;
128 const locale::category
locale::collate
;
129 const locale::category
locale::ctype
;
130 const locale::category
locale::monetary
;
131 const locale::category
locale::numeric
;
132 const locale::category
locale::time
;
133 const locale::category
locale::messages
;
134 const locale::category
locale::all
;
136 class _LIBCPP_HIDDEN
locale::__imp
140 vector
<facet
*, __sso_allocator
<facet
*, N
> > facets_
;
143 explicit __imp(size_t refs
= 0);
144 explicit __imp(const string
& name
, size_t refs
= 0);
146 __imp(const __imp
&, const string
&, locale::category c
);
147 __imp(const __imp
& other
, const __imp
& one
, locale::category c
);
148 __imp(const __imp
&, facet
* f
, long id
);
151 const string
& name() const {return name_
;}
152 bool has_facet(long id
) const
153 {return static_cast<size_t>(id
) < facets_
.size() && facets_
[static_cast<size_t>(id
)];}
154 const locale::facet
* use_facet(long id
) const;
156 static const locale
& make_classic();
157 static locale
& make_global();
159 void install(facet
* f
, long id
);
160 template <class F
> void install(F
* f
) {install(f
, f
->id
.__get());}
161 template <class F
> void install_from(const __imp
& other
);
164 locale::__imp::__imp(size_t refs
)
170 install(&make
<_VSTD::collate
<char> >(1u));
171 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
172 install(&make
<_VSTD::collate
<wchar_t> >(1u));
174 install(&make
<_VSTD::ctype
<char> >(nullptr, false, 1u));
175 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
176 install(&make
<_VSTD::ctype
<wchar_t> >(1u));
178 install(&make
<codecvt
<char, char, mbstate_t> >(1u));
179 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
180 install(&make
<codecvt
<wchar_t, char, mbstate_t> >(1u));
182 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
183 install(&make
<codecvt
<char16_t
, char, mbstate_t> >(1u));
184 install(&make
<codecvt
<char32_t
, char, mbstate_t> >(1u));
185 _LIBCPP_SUPPRESS_DEPRECATED_POP
186 #ifndef _LIBCPP_HAS_NO_CHAR8_T
187 install(&make
<codecvt
<char16_t
, char8_t
, mbstate_t> >(1u));
188 install(&make
<codecvt
<char32_t
, char8_t
, mbstate_t> >(1u));
190 install(&make
<numpunct
<char> >(1u));
191 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
192 install(&make
<numpunct
<wchar_t> >(1u));
194 install(&make
<num_get
<char> >(1u));
195 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
196 install(&make
<num_get
<wchar_t> >(1u));
198 install(&make
<num_put
<char> >(1u));
199 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
200 install(&make
<num_put
<wchar_t> >(1u));
202 install(&make
<moneypunct
<char, false> >(1u));
203 install(&make
<moneypunct
<char, true> >(1u));
204 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
205 install(&make
<moneypunct
<wchar_t, false> >(1u));
206 install(&make
<moneypunct
<wchar_t, true> >(1u));
208 install(&make
<money_get
<char> >(1u));
209 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
210 install(&make
<money_get
<wchar_t> >(1u));
212 install(&make
<money_put
<char> >(1u));
213 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
214 install(&make
<money_put
<wchar_t> >(1u));
216 install(&make
<time_get
<char> >(1u));
217 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
218 install(&make
<time_get
<wchar_t> >(1u));
220 install(&make
<time_put
<char> >(1u));
221 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
222 install(&make
<time_put
<wchar_t> >(1u));
224 install(&make
<_VSTD::messages
<char> >(1u));
225 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
226 install(&make
<_VSTD::messages
<wchar_t> >(1u));
230 locale::__imp::__imp(const string
& name
, size_t refs
)
235 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
238 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
239 facets_
= locale::classic().__locale_
->facets_
;
240 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
242 facets_
[i
]->__add_shared();
243 install(new collate_byname
<char>(name_
));
244 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
245 install(new collate_byname
<wchar_t>(name_
));
247 install(new ctype_byname
<char>(name_
));
248 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
249 install(new ctype_byname
<wchar_t>(name_
));
251 install(new codecvt_byname
<char, char, mbstate_t>(name_
));
252 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
253 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name_
));
255 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
256 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name_
));
257 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name_
));
258 _LIBCPP_SUPPRESS_DEPRECATED_POP
259 #ifndef _LIBCPP_HAS_NO_CHAR8_T
260 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name_
));
261 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name_
));
263 install(new numpunct_byname
<char>(name_
));
264 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
265 install(new numpunct_byname
<wchar_t>(name_
));
267 install(new moneypunct_byname
<char, false>(name_
));
268 install(new moneypunct_byname
<char, true>(name_
));
269 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
270 install(new moneypunct_byname
<wchar_t, false>(name_
));
271 install(new moneypunct_byname
<wchar_t, true>(name_
));
273 install(new time_get_byname
<char>(name_
));
274 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
275 install(new time_get_byname
<wchar_t>(name_
));
277 install(new time_put_byname
<char>(name_
));
278 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
279 install(new time_put_byname
<wchar_t>(name_
));
281 install(new messages_byname
<char>(name_
));
282 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
283 install(new messages_byname
<wchar_t>(name_
));
285 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
289 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
291 facets_
[i
]->__release_shared();
294 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
297 locale::__imp::__imp(const __imp
& other
)
298 : facets_(max
<size_t>(N
, other
.facets_
.size())),
301 facets_
= other
.facets_
;
302 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
304 facets_
[i
]->__add_shared();
307 locale::__imp::__imp(const __imp
& other
, const string
& name
, locale::category c
)
308 : facets_(N
), name_(build_name(other
.name_
, name
, c
))
310 facets_
= other
.facets_
;
311 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
313 facets_
[i
]->__add_shared();
314 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
317 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
318 if (c
& locale::collate
)
320 install(new collate_byname
<char>(name
));
321 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
322 install(new collate_byname
<wchar_t>(name
));
325 if (c
& locale::ctype
)
327 install(new ctype_byname
<char>(name
));
328 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
329 install(new ctype_byname
<wchar_t>(name
));
331 install(new codecvt_byname
<char, char, mbstate_t>(name
));
332 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
333 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name
));
335 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
336 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name
));
337 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name
));
338 _LIBCPP_SUPPRESS_DEPRECATED_POP
339 #ifndef _LIBCPP_HAS_NO_CHAR8_T
340 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name
));
341 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name
));
344 if (c
& locale::monetary
)
346 install(new moneypunct_byname
<char, false>(name
));
347 install(new moneypunct_byname
<char, true>(name
));
348 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
349 install(new moneypunct_byname
<wchar_t, false>(name
));
350 install(new moneypunct_byname
<wchar_t, true>(name
));
353 if (c
& locale::numeric
)
355 install(new numpunct_byname
<char>(name
));
356 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
357 install(new numpunct_byname
<wchar_t>(name
));
360 if (c
& locale::time
)
362 install(new time_get_byname
<char>(name
));
363 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
364 install(new time_get_byname
<wchar_t>(name
));
366 install(new time_put_byname
<char>(name
));
367 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
368 install(new time_put_byname
<wchar_t>(name
));
371 if (c
& locale::messages
)
373 install(new messages_byname
<char>(name
));
374 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
375 install(new messages_byname
<wchar_t>(name
));
378 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
382 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
384 facets_
[i
]->__release_shared();
387 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
393 locale::__imp::install_from(const locale::__imp
& one
)
395 long id
= F::id
.__get();
396 install(const_cast<F
*>(static_cast<const F
*>(one
.use_facet(id
))), id
);
399 locale::__imp::__imp(const __imp
& other
, const __imp
& one
, locale::category c
)
400 : facets_(N
), name_(build_name(other
.name_
, one
.name_
, c
))
402 facets_
= other
.facets_
;
403 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
405 facets_
[i
]->__add_shared();
406 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
409 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
410 if (c
& locale::collate
)
412 install_from
<_VSTD::collate
<char> >(one
);
413 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
414 install_from
<_VSTD::collate
<wchar_t> >(one
);
417 if (c
& locale::ctype
)
419 install_from
<_VSTD::ctype
<char> >(one
);
420 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
421 install_from
<_VSTD::ctype
<wchar_t> >(one
);
423 install_from
<_VSTD::codecvt
<char, char, mbstate_t> >(one
);
424 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
425 install_from
<_VSTD::codecvt
<char16_t
, char, mbstate_t> >(one
);
426 install_from
<_VSTD::codecvt
<char32_t
, char, mbstate_t> >(one
);
427 _LIBCPP_SUPPRESS_DEPRECATED_POP
428 #ifndef _LIBCPP_HAS_NO_CHAR8_T
429 install_from
<_VSTD::codecvt
<char16_t
, char8_t
, mbstate_t> >(one
);
430 install_from
<_VSTD::codecvt
<char32_t
, char8_t
, mbstate_t> >(one
);
432 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
433 install_from
<_VSTD::codecvt
<wchar_t, char, mbstate_t> >(one
);
436 if (c
& locale::monetary
)
438 install_from
<moneypunct
<char, false> >(one
);
439 install_from
<moneypunct
<char, true> >(one
);
440 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
441 install_from
<moneypunct
<wchar_t, false> >(one
);
442 install_from
<moneypunct
<wchar_t, true> >(one
);
444 install_from
<money_get
<char> >(one
);
445 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
446 install_from
<money_get
<wchar_t> >(one
);
448 install_from
<money_put
<char> >(one
);
449 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
450 install_from
<money_put
<wchar_t> >(one
);
453 if (c
& locale::numeric
)
455 install_from
<numpunct
<char> >(one
);
456 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
457 install_from
<numpunct
<wchar_t> >(one
);
459 install_from
<num_get
<char> >(one
);
460 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461 install_from
<num_get
<wchar_t> >(one
);
463 install_from
<num_put
<char> >(one
);
464 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
465 install_from
<num_put
<wchar_t> >(one
);
468 if (c
& locale::time
)
470 install_from
<time_get
<char> >(one
);
471 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
472 install_from
<time_get
<wchar_t> >(one
);
474 install_from
<time_put
<char> >(one
);
475 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
476 install_from
<time_put
<wchar_t> >(one
);
479 if (c
& locale::messages
)
481 install_from
<_VSTD::messages
<char> >(one
);
482 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
483 install_from
<_VSTD::messages
<wchar_t> >(one
);
486 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
490 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
492 facets_
[i
]->__release_shared();
495 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
498 locale::__imp::__imp(const __imp
& other
, facet
* f
, long id
)
499 : facets_(max
<size_t>(N
, other
.facets_
.size()+1)),
503 unique_ptr
<facet
, release
> hold(f
);
504 facets_
= other
.facets_
;
505 for (unsigned i
= 0; i
< other
.facets_
.size(); ++i
)
507 facets_
[i
]->__add_shared();
508 install(hold
.get(), id
);
511 locale::__imp::~__imp()
513 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
515 facets_
[i
]->__release_shared();
519 locale::__imp::install(facet
* f
, long id
)
522 unique_ptr
<facet
, release
> hold(f
);
523 if (static_cast<size_t>(id
) >= facets_
.size())
524 facets_
.resize(static_cast<size_t>(id
+1));
525 if (facets_
[static_cast<size_t>(id
)])
526 facets_
[static_cast<size_t>(id
)]->__release_shared();
527 facets_
[static_cast<size_t>(id
)] = hold
.release();
531 locale::__imp::use_facet(long id
) const
535 return facets_
[static_cast<size_t>(id
)];
541 locale::__imp::make_classic()
543 // only one thread can get in here and it only gets in once
544 static aligned_storage
<sizeof(locale
)>::type buf
;
545 locale
* c
= reinterpret_cast<locale
*>(&buf
);
546 c
->__locale_
= &make
<__imp
>(1u);
553 static const locale
& c
= __imp::make_classic();
558 locale::__imp::make_global()
560 // only one thread can get in here and it only gets in once
561 static aligned_storage
<sizeof(locale
)>::type buf
;
562 auto *obj
= ::new (&buf
) locale(locale::classic());
569 static locale
& g
= __imp::make_global();
573 locale::locale() noexcept
574 : __locale_(__global().__locale_
)
576 __locale_
->__add_shared();
579 locale::locale(const locale
& l
) noexcept
580 : __locale_(l
.__locale_
)
582 __locale_
->__add_shared();
587 __locale_
->__release_shared();
591 locale::operator=(const locale
& other
) noexcept
593 other
.__locale_
->__add_shared();
594 __locale_
->__release_shared();
595 __locale_
= other
.__locale_
;
599 locale::locale(const char* name
)
600 : __locale_(name
? new __imp(name
)
601 : (__throw_runtime_error("locale constructed with null"), nullptr))
603 __locale_
->__add_shared();
606 locale::locale(const string
& name
)
607 : __locale_(new __imp(name
))
609 __locale_
->__add_shared();
612 locale::locale(const locale
& other
, const char* name
, category c
)
613 : __locale_(name
? new __imp(*other
.__locale_
, name
, c
)
614 : (__throw_runtime_error("locale constructed with null"), nullptr))
616 __locale_
->__add_shared();
619 locale::locale(const locale
& other
, const string
& name
, category c
)
620 : __locale_(new __imp(*other
.__locale_
, name
, c
))
622 __locale_
->__add_shared();
625 locale::locale(const locale
& other
, const locale
& one
, category c
)
626 : __locale_(new __imp(*other
.__locale_
, *one
.__locale_
, c
))
628 __locale_
->__add_shared();
634 return __locale_
->name();
638 locale::__install_ctor(const locale
& other
, facet
* f
, long id
)
641 __locale_
= new __imp(*other
.__locale_
, f
, id
);
643 __locale_
= other
.__locale_
;
644 __locale_
->__add_shared();
648 locale::global(const locale
& loc
)
650 locale
& g
= __global();
654 setlocale(LC_ALL
, g
.name().c_str());
659 locale::has_facet(id
& x
) const
661 return __locale_
->has_facet(x
.__get());
665 locale::use_facet(id
& x
) const
667 return __locale_
->use_facet(x
.__get());
671 locale::operator==(const locale
& y
) const
673 return (__locale_
== y
.__locale_
)
674 || (__locale_
->name() != "*" && __locale_
->name() == y
.__locale_
->name());
679 locale::facet::~facet()
684 locale::facet::__on_zero_shared() noexcept
691 constinit
int32_t locale::id::__next_id
= 0;
693 long locale::id::__get() {
694 call_once(__flag_
, [&] { __id_
= __libcpp_atomic_add(&__next_id
, 1); });
698 // template <> class collate_byname<char>
700 collate_byname
<char>::collate_byname(const char* n
, size_t refs
)
701 : collate
<char>(refs
),
702 __l_(newlocale(LC_ALL_MASK
, n
, 0))
705 __throw_runtime_error(("collate_byname<char>::collate_byname"
706 " failed to construct for " + string(n
)).c_str());
709 collate_byname
<char>::collate_byname(const string
& name
, size_t refs
)
710 : collate
<char>(refs
),
711 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
714 __throw_runtime_error(("collate_byname<char>::collate_byname"
715 " failed to construct for " + name
).c_str());
718 collate_byname
<char>::~collate_byname()
724 collate_byname
<char>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
725 const char_type
* __lo2
, const char_type
* __hi2
) const
727 string_type
lhs(__lo1
, __hi1
);
728 string_type
rhs(__lo2
, __hi2
);
729 int r
= strcoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
737 collate_byname
<char>::string_type
738 collate_byname
<char>::do_transform(const char_type
* lo
, const char_type
* hi
) const
740 const string_type
in(lo
, hi
);
741 string_type
out(strxfrm_l(0, in
.c_str(), 0, __l_
), char());
742 strxfrm_l(const_cast<char*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
746 // template <> class collate_byname<wchar_t>
748 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
749 collate_byname
<wchar_t>::collate_byname(const char* n
, size_t refs
)
750 : collate
<wchar_t>(refs
),
751 __l_(newlocale(LC_ALL_MASK
, n
, 0))
754 __throw_runtime_error(("collate_byname<wchar_t>::collate_byname(size_t refs)"
755 " failed to construct for " + string(n
)).c_str());
758 collate_byname
<wchar_t>::collate_byname(const string
& name
, size_t refs
)
759 : collate
<wchar_t>(refs
),
760 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
763 __throw_runtime_error(("collate_byname<wchar_t>::collate_byname(size_t refs)"
764 " failed to construct for " + name
).c_str());
767 collate_byname
<wchar_t>::~collate_byname()
773 collate_byname
<wchar_t>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
774 const char_type
* __lo2
, const char_type
* __hi2
) const
776 string_type
lhs(__lo1
, __hi1
);
777 string_type
rhs(__lo2
, __hi2
);
778 int r
= wcscoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
786 collate_byname
<wchar_t>::string_type
787 collate_byname
<wchar_t>::do_transform(const char_type
* lo
, const char_type
* hi
) const
789 const string_type
in(lo
, hi
);
790 string_type
out(wcsxfrm_l(0, in
.c_str(), 0, __l_
), wchar_t());
791 wcsxfrm_l(const_cast<wchar_t*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
794 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
796 const ctype_base::mask
ctype_base::space
;
797 const ctype_base::mask
ctype_base::print
;
798 const ctype_base::mask
ctype_base::cntrl
;
799 const ctype_base::mask
ctype_base::upper
;
800 const ctype_base::mask
ctype_base::lower
;
801 const ctype_base::mask
ctype_base::alpha
;
802 const ctype_base::mask
ctype_base::digit
;
803 const ctype_base::mask
ctype_base::punct
;
804 const ctype_base::mask
ctype_base::xdigit
;
805 const ctype_base::mask
ctype_base::blank
;
806 const ctype_base::mask
ctype_base::alnum
;
807 const ctype_base::mask
ctype_base::graph
;
809 // template <> class ctype<wchar_t>;
811 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
812 constinit
locale::id ctype
<wchar_t>::id
;
814 ctype
<wchar_t>::~ctype()
819 ctype
<wchar_t>::do_is(mask m
, char_type c
) const
821 return isascii(c
) ? (ctype
<char>::classic_table()[c
] & m
) != 0 : false;
825 ctype
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
827 for (; low
!= high
; ++low
, ++vec
)
828 *vec
= static_cast<mask
>(isascii(*low
) ?
829 ctype
<char>::classic_table()[*low
] : 0);
834 ctype
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
836 for (; low
!= high
; ++low
)
837 if (isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
))
843 ctype
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
845 for (; low
!= high
; ++low
)
846 if (!(isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
)))
852 ctype
<wchar_t>::do_toupper(char_type c
) const
854 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
855 return isascii(c
) ? _DefaultRuneLocale
.__mapupper
[c
] : c
;
856 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
857 defined(__NetBSD__) || defined(__MVS__)
858 return isascii(c
) ? ctype
<char>::__classic_upper_table()[c
] : c
;
860 return (isascii(c
) && iswlower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'a'+L
'A' : c
;
865 ctype
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
867 for (; low
!= high
; ++low
)
868 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
869 *low
= isascii(*low
) ? _DefaultRuneLocale
.__mapupper
[*low
] : *low
;
870 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
871 defined(__NetBSD__) || defined(__MVS__)
872 *low
= isascii(*low
) ? ctype
<char>::__classic_upper_table()[*low
]
875 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? (*low
-L
'a'+L
'A') : *low
;
881 ctype
<wchar_t>::do_tolower(char_type c
) const
883 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
884 return isascii(c
) ? _DefaultRuneLocale
.__maplower
[c
] : c
;
885 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
886 defined(__NetBSD__) || defined(__MVS__)
887 return isascii(c
) ? ctype
<char>::__classic_lower_table()[c
] : c
;
889 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'A'+'a' : c
;
894 ctype
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
896 for (; low
!= high
; ++low
)
897 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
898 *low
= isascii(*low
) ? _DefaultRuneLocale
.__maplower
[*low
] : *low
;
899 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
900 defined(__NetBSD__) || defined(__MVS__)
901 *low
= isascii(*low
) ? ctype
<char>::__classic_lower_table()[*low
]
904 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-L
'A'+L
'a' : *low
;
910 ctype
<wchar_t>::do_widen(char c
) const
916 ctype
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
918 for (; low
!= high
; ++low
, ++dest
)
924 ctype
<wchar_t>::do_narrow(char_type c
, char dfault
) const
927 return static_cast<char>(c
);
932 ctype
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
934 for (; low
!= high
; ++low
, ++dest
)
936 *dest
= static_cast<char>(*low
);
941 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
943 // template <> class ctype<char>;
945 constinit
locale::id ctype
<char>::id
;
947 const size_t ctype
<char>::table_size
;
949 ctype
<char>::ctype(const mask
* tab
, bool del
, size_t refs
)
950 : locale::facet(refs
),
955 __tab_
= classic_table();
958 ctype
<char>::~ctype()
960 if (__tab_
&& __del_
)
965 ctype
<char>::do_toupper(char_type c
) const
967 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
969 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(c
)]) : c
;
970 #elif defined(__NetBSD__)
971 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]);
972 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
974 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]) : c
;
976 return (isascii(c
) && islower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'a'+'A' : c
;
981 ctype
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
983 for (; low
!= high
; ++low
)
984 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
985 *low
= isascii(*low
) ?
986 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(*low
)]) : *low
;
987 #elif defined(__NetBSD__)
988 *low
= static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low
)]);
989 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
990 *low
= isascii(*low
) ?
991 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low
)]) : *low
;
993 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'a'+'A' : *low
;
999 ctype
<char>::do_tolower(char_type c
) const
1001 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1003 static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(c
)]) : c
;
1004 #elif defined(__NetBSD__)
1005 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c
)]);
1006 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1008 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c
)]) : c
;
1010 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'A'+'a' : c
;
1015 ctype
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1017 for (; low
!= high
; ++low
)
1018 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1019 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(*low
)]) : *low
;
1020 #elif defined(__NetBSD__)
1021 *low
= static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low
)]);
1022 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1023 *low
= isascii(*low
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low
)]) : *low
;
1025 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'A'+'a' : *low
;
1031 ctype
<char>::do_widen(char c
) const
1037 ctype
<char>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1039 for (; low
!= high
; ++low
, ++dest
)
1045 ctype
<char>::do_narrow(char_type c
, char dfault
) const
1048 return static_cast<char>(c
);
1053 ctype
<char>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1055 for (; low
!= high
; ++low
, ++dest
)
1063 #if defined(__EMSCRIPTEN__)
1064 extern "C" const unsigned short ** __ctype_b_loc();
1065 extern "C" const int ** __ctype_tolower_loc();
1066 extern "C" const int ** __ctype_toupper_loc();
1069 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1070 const ctype
<char>::mask
*
1071 ctype
<char>::classic_table() noexcept
1073 static constexpr const ctype
<char>::mask builtin_table
[table_size
] = {
1078 cntrl
, cntrl
| space
| blank
,
1079 cntrl
| space
, cntrl
| space
,
1080 cntrl
| space
, cntrl
| space
,
1090 space
| blank
| print
, punct
| print
,
1091 punct
| print
, punct
| print
,
1092 punct
| print
, punct
| print
,
1093 punct
| print
, punct
| print
,
1094 punct
| print
, punct
| print
,
1095 punct
| print
, punct
| print
,
1096 punct
| print
, punct
| print
,
1097 punct
| print
, punct
| print
,
1098 digit
| print
| xdigit
, digit
| print
| xdigit
,
1099 digit
| print
| xdigit
, digit
| print
| xdigit
,
1100 digit
| print
| xdigit
, digit
| print
| xdigit
,
1101 digit
| print
| xdigit
, digit
| print
| xdigit
,
1102 digit
| print
| xdigit
, digit
| print
| xdigit
,
1103 punct
| print
, punct
| print
,
1104 punct
| print
, punct
| print
,
1105 punct
| print
, punct
| print
,
1106 punct
| print
, upper
| xdigit
| print
| alpha
,
1107 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1108 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1109 upper
| xdigit
| print
| alpha
, upper
| print
| alpha
,
1110 upper
| print
| alpha
, upper
| print
| alpha
,
1111 upper
| print
| alpha
, upper
| print
| alpha
,
1112 upper
| print
| alpha
, upper
| print
| alpha
,
1113 upper
| print
| alpha
, upper
| print
| alpha
,
1114 upper
| print
| alpha
, upper
| print
| alpha
,
1115 upper
| print
| alpha
, upper
| print
| alpha
,
1116 upper
| print
| alpha
, upper
| print
| alpha
,
1117 upper
| print
| alpha
, upper
| print
| alpha
,
1118 upper
| print
| alpha
, upper
| print
| alpha
,
1119 upper
| print
| alpha
, punct
| print
,
1120 punct
| print
, punct
| print
,
1121 punct
| print
, punct
| print
,
1122 punct
| print
, lower
| xdigit
| print
| alpha
,
1123 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1124 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1125 lower
| xdigit
| print
| alpha
, lower
| print
| alpha
,
1126 lower
| print
| alpha
, lower
| print
| alpha
,
1127 lower
| print
| alpha
, lower
| print
| alpha
,
1128 lower
| print
| alpha
, lower
| print
| alpha
,
1129 lower
| print
| alpha
, lower
| print
| alpha
,
1130 lower
| print
| alpha
, lower
| print
| alpha
,
1131 lower
| print
| alpha
, lower
| print
| alpha
,
1132 lower
| print
| alpha
, lower
| print
| alpha
,
1133 lower
| print
| alpha
, lower
| print
| alpha
,
1134 lower
| print
| alpha
, lower
| print
| alpha
,
1135 lower
| print
| alpha
, punct
| print
,
1136 punct
| print
, punct
| print
,
1137 punct
| print
, cntrl
,
1138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1147 return builtin_table
;
1150 const ctype
<char>::mask
*
1151 ctype
<char>::classic_table() noexcept
1153 #if defined(__APPLE__) || defined(__FreeBSD__)
1154 return _DefaultRuneLocale
.__runetype
;
1155 #elif defined(__NetBSD__)
1156 return _C_ctype_tab_
+ 1;
1157 #elif defined(__GLIBC__)
1158 return _LIBCPP_GET_C_LOCALE
->__ctype_b
;
1159 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1160 return __pctype_func();
1161 #elif defined(__EMSCRIPTEN__)
1162 return *__ctype_b_loc();
1163 #elif defined(_NEWLIB_VERSION)
1164 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1167 return (const unsigned int *)__lc_ctype_ptr
->obj
->mask
;
1168 #elif defined(__MVS__)
1169 # if defined(__NATIVE_ASCII_F)
1170 return const_cast<const ctype
<char>::mask
*> (__OBJ_DATA(__lc_ctype_a
)->mask
);
1172 return const_cast<const ctype
<char>::mask
*> (__ctypec
);
1175 // Platform not supported: abort so the person doing the port knows what to
1177 # warning ctype<char>::classic_table() is not implemented
1178 printf("ctype<char>::classic_table() is not implemented\n");
1185 #if defined(__GLIBC__)
1187 ctype
<char>::__classic_lower_table() noexcept
1189 return _LIBCPP_GET_C_LOCALE
->__ctype_tolower
;
1193 ctype
<char>::__classic_upper_table() noexcept
1195 return _LIBCPP_GET_C_LOCALE
->__ctype_toupper
;
1197 #elif defined(__NetBSD__)
1199 ctype
<char>::__classic_lower_table() noexcept
1201 return _C_tolower_tab_
+ 1;
1205 ctype
<char>::__classic_upper_table() noexcept
1207 return _C_toupper_tab_
+ 1;
1210 #elif defined(__EMSCRIPTEN__)
1212 ctype
<char>::__classic_lower_table() noexcept
1214 return *__ctype_tolower_loc();
1218 ctype
<char>::__classic_upper_table() noexcept
1220 return *__ctype_toupper_loc();
1222 #elif defined(__MVS__)
1223 const unsigned short*
1224 ctype
<char>::__classic_lower_table() _NOEXCEPT
1226 # if defined(__NATIVE_ASCII_F)
1227 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->lower
);
1229 return const_cast<const unsigned short*>(__ctype
+ __TOLOWER_INDEX
);
1232 const unsigned short *
1233 ctype
<char>::__classic_upper_table() _NOEXCEPT
1235 # if defined(__NATIVE_ASCII_F)
1236 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->upper
);
1238 return const_cast<const unsigned short*>(__ctype
+ __TOUPPER_INDEX
);
1241 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1243 // template <> class ctype_byname<char>
1245 ctype_byname
<char>::ctype_byname(const char* name
, size_t refs
)
1246 : ctype
<char>(0, false, refs
),
1247 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1250 __throw_runtime_error(("ctype_byname<char>::ctype_byname"
1251 " failed to construct for " + string(name
)).c_str());
1254 ctype_byname
<char>::ctype_byname(const string
& name
, size_t refs
)
1255 : ctype
<char>(0, false, refs
),
1256 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1259 __throw_runtime_error(("ctype_byname<char>::ctype_byname"
1260 " failed to construct for " + name
).c_str());
1263 ctype_byname
<char>::~ctype_byname()
1269 ctype_byname
<char>::do_toupper(char_type c
) const
1271 return static_cast<char>(toupper_l(static_cast<unsigned char>(c
), __l_
));
1275 ctype_byname
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
1277 for (; low
!= high
; ++low
)
1278 *low
= static_cast<char>(toupper_l(static_cast<unsigned char>(*low
), __l_
));
1283 ctype_byname
<char>::do_tolower(char_type c
) const
1285 return static_cast<char>(tolower_l(static_cast<unsigned char>(c
), __l_
));
1289 ctype_byname
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1291 for (; low
!= high
; ++low
)
1292 *low
= static_cast<char>(tolower_l(static_cast<unsigned char>(*low
), __l_
));
1296 // template <> class ctype_byname<wchar_t>
1298 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1299 ctype_byname
<wchar_t>::ctype_byname(const char* name
, size_t refs
)
1300 : ctype
<wchar_t>(refs
),
1301 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1304 __throw_runtime_error(("ctype_byname<wchar_t>::ctype_byname"
1305 " failed to construct for " + string(name
)).c_str());
1308 ctype_byname
<wchar_t>::ctype_byname(const string
& name
, size_t refs
)
1309 : ctype
<wchar_t>(refs
),
1310 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1313 __throw_runtime_error(("ctype_byname<wchar_t>::ctype_byname"
1314 " failed to construct for " + name
).c_str());
1317 ctype_byname
<wchar_t>::~ctype_byname()
1323 ctype_byname
<wchar_t>::do_is(mask m
, char_type c
) const
1325 #ifdef _LIBCPP_WCTYPE_IS_MASK
1326 return static_cast<bool>(iswctype_l(c
, m
, __l_
));
1328 bool result
= false;
1329 wint_t ch
= static_cast<wint_t>(c
);
1330 if ((m
& space
) == space
) result
|= (iswspace_l(ch
, __l_
) != 0);
1331 if ((m
& print
) == print
) result
|= (iswprint_l(ch
, __l_
) != 0);
1332 if ((m
& cntrl
) == cntrl
) result
|= (iswcntrl_l(ch
, __l_
) != 0);
1333 if ((m
& upper
) == upper
) result
|= (iswupper_l(ch
, __l_
) != 0);
1334 if ((m
& lower
) == lower
) result
|= (iswlower_l(ch
, __l_
) != 0);
1335 if ((m
& alpha
) == alpha
) result
|= (iswalpha_l(ch
, __l_
) != 0);
1336 if ((m
& digit
) == digit
) result
|= (iswdigit_l(ch
, __l_
) != 0);
1337 if ((m
& punct
) == punct
) result
|= (iswpunct_l(ch
, __l_
) != 0);
1338 if ((m
& xdigit
) == xdigit
) result
|= (iswxdigit_l(ch
, __l_
) != 0);
1339 if ((m
& blank
) == blank
) result
|= (iswblank_l(ch
, __l_
) != 0);
1345 ctype_byname
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
1347 for (; low
!= high
; ++low
, ++vec
)
1350 *vec
= static_cast<mask
>(ctype
<char>::classic_table()[*low
]);
1354 wint_t ch
= static_cast<wint_t>(*low
);
1355 if (iswspace_l(ch
, __l_
))
1357 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1358 if (iswprint_l(ch
, __l_
))
1361 if (iswcntrl_l(ch
, __l_
))
1363 if (iswupper_l(ch
, __l_
))
1365 if (iswlower_l(ch
, __l_
))
1367 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1368 if (iswalpha_l(ch
, __l_
))
1371 if (iswdigit_l(ch
, __l_
))
1373 if (iswpunct_l(ch
, __l_
))
1375 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1376 if (iswxdigit_l(ch
, __l_
))
1379 if (iswblank_l(ch
, __l_
))
1387 ctype_byname
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
1389 for (; low
!= high
; ++low
)
1391 #ifdef _LIBCPP_WCTYPE_IS_MASK
1392 if (iswctype_l(*low
, m
, __l_
))
1395 wint_t ch
= static_cast<wint_t>(*low
);
1396 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) break;
1397 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) break;
1398 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) break;
1399 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) break;
1400 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) break;
1401 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) break;
1402 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) break;
1403 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) break;
1404 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) break;
1405 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) break;
1412 ctype_byname
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
1414 for (; low
!= high
; ++low
)
1416 #ifdef _LIBCPP_WCTYPE_IS_MASK
1417 if (!iswctype_l(*low
, m
, __l_
))
1420 wint_t ch
= static_cast<wint_t>(*low
);
1421 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) continue;
1422 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) continue;
1423 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) continue;
1424 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) continue;
1425 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) continue;
1426 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) continue;
1427 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) continue;
1428 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) continue;
1429 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) continue;
1430 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) continue;
1438 ctype_byname
<wchar_t>::do_toupper(char_type c
) const
1440 return towupper_l(c
, __l_
);
1444 ctype_byname
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
1446 for (; low
!= high
; ++low
)
1447 *low
= towupper_l(*low
, __l_
);
1452 ctype_byname
<wchar_t>::do_tolower(char_type c
) const
1454 return towlower_l(c
, __l_
);
1458 ctype_byname
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
1460 for (; low
!= high
; ++low
)
1461 *low
= towlower_l(*low
, __l_
);
1466 ctype_byname
<wchar_t>::do_widen(char c
) const
1468 return __libcpp_btowc_l(c
, __l_
);
1472 ctype_byname
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1474 for (; low
!= high
; ++low
, ++dest
)
1475 *dest
= __libcpp_btowc_l(*low
, __l_
);
1480 ctype_byname
<wchar_t>::do_narrow(char_type c
, char dfault
) const
1482 int r
= __libcpp_wctob_l(c
, __l_
);
1483 return (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1487 ctype_byname
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1489 for (; low
!= high
; ++low
, ++dest
)
1491 int r
= __libcpp_wctob_l(*low
, __l_
);
1492 *dest
= (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1496 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1498 // template <> class codecvt<char, char, mbstate_t>
1500 constinit
locale::id codecvt
<char, char, mbstate_t>::id
;
1502 codecvt
<char, char, mbstate_t>::~codecvt()
1506 codecvt
<char, char, mbstate_t>::result
1507 codecvt
<char, char, mbstate_t>::do_out(state_type
&,
1508 const intern_type
* frm
, const intern_type
*, const intern_type
*& frm_nxt
,
1509 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1516 codecvt
<char, char, mbstate_t>::result
1517 codecvt
<char, char, mbstate_t>::do_in(state_type
&,
1518 const extern_type
* frm
, const extern_type
*, const extern_type
*& frm_nxt
,
1519 intern_type
* to
, intern_type
*, intern_type
*& to_nxt
) const
1526 codecvt
<char, char, mbstate_t>::result
1527 codecvt
<char, char, mbstate_t>::do_unshift(state_type
&,
1528 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1535 codecvt
<char, char, mbstate_t>::do_encoding() const noexcept
1541 codecvt
<char, char, mbstate_t>::do_always_noconv() const noexcept
1547 codecvt
<char, char, mbstate_t>::do_length(state_type
&,
1548 const extern_type
* frm
, const extern_type
* end
, size_t mx
) const
1550 return static_cast<int>(min
<size_t>(mx
, static_cast<size_t>(end
-frm
)));
1554 codecvt
<char, char, mbstate_t>::do_max_length() const noexcept
1559 // template <> class codecvt<wchar_t, char, mbstate_t>
1561 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1562 constinit
locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
1564 codecvt
<wchar_t, char, mbstate_t>::codecvt(size_t refs
)
1565 : locale::facet(refs
),
1566 __l_(_LIBCPP_GET_C_LOCALE
)
1570 codecvt
<wchar_t, char, mbstate_t>::codecvt(const char* nm
, size_t refs
)
1571 : locale::facet(refs
),
1572 __l_(newlocale(LC_ALL_MASK
, nm
, 0))
1575 __throw_runtime_error(("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1576 " failed to construct for " + string(nm
)).c_str());
1579 codecvt
<wchar_t, char, mbstate_t>::~codecvt()
1581 if (__l_
!= _LIBCPP_GET_C_LOCALE
)
1585 codecvt
<wchar_t, char, mbstate_t>::result
1586 codecvt
<wchar_t, char, mbstate_t>::do_out(state_type
& st
,
1587 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
1588 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1590 // look for first internal null in frm
1591 const intern_type
* fend
= frm
;
1592 for (; fend
!= frm_end
; ++fend
)
1595 // loop over all null-terminated sequences in frm
1597 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1599 // save state in case it is needed to recover to_nxt on error
1600 mbstate_t save_state
= st
;
1601 size_t n
= __libcpp_wcsnrtombs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1602 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1603 if (n
== size_t(-1))
1605 // need to recover to_nxt
1606 for (to_nxt
= to
; frm
!= frm_nxt
; ++frm
)
1608 n
= __libcpp_wcrtomb_l(to_nxt
, *frm
, &save_state
, __l_
);
1609 if (n
== size_t(-1))
1619 if (to_nxt
== to_end
)
1621 if (fend
!= frm_end
) // set up next null terminated sequence
1623 // Try to write the terminating null
1624 extern_type tmp
[MB_LEN_MAX
];
1625 n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1626 if (n
== size_t(-1)) // on error
1628 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1630 for (extern_type
* p
= tmp
; n
; --n
) // write it
1633 // look for next null in frm
1634 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1639 return frm_nxt
== frm_end
? ok
: partial
;
1642 codecvt
<wchar_t, char, mbstate_t>::result
1643 codecvt
<wchar_t, char, mbstate_t>::do_in(state_type
& st
,
1644 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
1645 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
1647 // look for first internal null in frm
1648 const extern_type
* fend
= frm
;
1649 for (; fend
!= frm_end
; ++fend
)
1652 // loop over all null-terminated sequences in frm
1654 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1656 // save state in case it is needed to recover to_nxt on error
1657 mbstate_t save_state
= st
;
1658 size_t n
= __libcpp_mbsnrtowcs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1659 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1660 if (n
== size_t(-1))
1662 // need to recover to_nxt
1663 for (to_nxt
= to
; frm
!= frm_nxt
; ++to_nxt
)
1665 n
= __libcpp_mbrtowc_l(to_nxt
, frm
, static_cast<size_t>(fend
-frm
),
1684 return frm_nxt
== frm_end
? ok
: partial
;
1686 if (n
== size_t(-1))
1689 if (to_nxt
== to_end
)
1691 if (fend
!= frm_end
) // set up next null terminated sequence
1693 // Try to write the terminating null
1694 n
= __libcpp_mbrtowc_l(to_nxt
, frm_nxt
, 1, &st
, __l_
);
1695 if (n
!= 0) // on error
1699 // look for next null in frm
1700 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1705 return frm_nxt
== frm_end
? ok
: partial
;
1708 codecvt
<wchar_t, char, mbstate_t>::result
1709 codecvt
<wchar_t, char, mbstate_t>::do_unshift(state_type
& st
,
1710 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1713 extern_type tmp
[MB_LEN_MAX
];
1714 size_t n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1715 if (n
== size_t(-1) || n
== 0) // on error
1718 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1720 for (extern_type
* p
= tmp
; n
; --n
) // write it
1726 codecvt
<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1728 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX
, __l_
) != 0)
1731 // stateless encoding
1732 if (__l_
== 0 || __libcpp_mb_cur_max_l(__l_
) == 1) // there are no known constant length encodings
1733 return 1; // which take more than 1 char to form a wchar_t
1738 codecvt
<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1744 codecvt
<wchar_t, char, mbstate_t>::do_length(state_type
& st
,
1745 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
1748 for (size_t nwchar_t
= 0; nwchar_t
< mx
&& frm
!= frm_end
; ++nwchar_t
)
1750 size_t n
= __libcpp_mbrlen_l(frm
, static_cast<size_t>(frm_end
-frm
), &st
, __l_
);
1770 codecvt
<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1772 return __l_
== 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_
));
1774 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1777 // UTF-32 UTF-16 UTF-8 # of code points
1778 // first second first second third fourth
1779 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1780 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1781 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1782 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1783 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1784 // 00D800 - 00DFFF invalid
1785 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1786 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1787 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1788 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1790 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1792 codecvt_base::result
1793 utf16_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
1794 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1795 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1799 if (mode
& generate_header
)
1801 if (to_end
-to_nxt
< 3)
1802 return codecvt_base::partial
;
1803 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1804 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1805 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1807 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1809 uint16_t wc1
= *frm_nxt
;
1811 return codecvt_base::error
;
1814 if (to_end
-to_nxt
< 1)
1815 return codecvt_base::partial
;
1816 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1818 else if (wc1
< 0x0800)
1820 if (to_end
-to_nxt
< 2)
1821 return codecvt_base::partial
;
1822 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1823 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1825 else if (wc1
< 0xD800)
1827 if (to_end
-to_nxt
< 3)
1828 return codecvt_base::partial
;
1829 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1830 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1831 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1833 else if (wc1
< 0xDC00)
1835 if (frm_end
-frm_nxt
< 2)
1836 return codecvt_base::partial
;
1837 uint16_t wc2
= frm_nxt
[1];
1838 if ((wc2
& 0xFC00) != 0xDC00)
1839 return codecvt_base::error
;
1840 if (to_end
-to_nxt
< 4)
1841 return codecvt_base::partial
;
1842 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1843 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1844 return codecvt_base::error
;
1846 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1847 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1848 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1849 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1850 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1852 else if (wc1
< 0xE000)
1854 return codecvt_base::error
;
1858 if (to_end
-to_nxt
< 3)
1859 return codecvt_base::partial
;
1860 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1861 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1862 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1865 return codecvt_base::ok
;
1869 codecvt_base::result
1870 utf16_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
1871 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1872 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1876 if (mode
& generate_header
)
1878 if (to_end
-to_nxt
< 3)
1879 return codecvt_base::partial
;
1880 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1881 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1882 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1884 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1886 uint16_t wc1
= static_cast<uint16_t>(*frm_nxt
);
1888 return codecvt_base::error
;
1891 if (to_end
-to_nxt
< 1)
1892 return codecvt_base::partial
;
1893 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1895 else if (wc1
< 0x0800)
1897 if (to_end
-to_nxt
< 2)
1898 return codecvt_base::partial
;
1899 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1900 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1902 else if (wc1
< 0xD800)
1904 if (to_end
-to_nxt
< 3)
1905 return codecvt_base::partial
;
1906 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1907 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1908 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1910 else if (wc1
< 0xDC00)
1912 if (frm_end
-frm_nxt
< 2)
1913 return codecvt_base::partial
;
1914 uint16_t wc2
= static_cast<uint16_t>(frm_nxt
[1]);
1915 if ((wc2
& 0xFC00) != 0xDC00)
1916 return codecvt_base::error
;
1917 if (to_end
-to_nxt
< 4)
1918 return codecvt_base::partial
;
1919 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1920 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1921 return codecvt_base::error
;
1923 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1924 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1925 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1926 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1927 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1929 else if (wc1
< 0xE000)
1931 return codecvt_base::error
;
1935 if (to_end
-to_nxt
< 3)
1936 return codecvt_base::partial
;
1937 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1938 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1939 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1942 return codecvt_base::ok
;
1946 codecvt_base::result
1947 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
1948 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
1949 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1953 if (mode
& consume_header
)
1955 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
1959 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
1961 uint8_t c1
= *frm_nxt
;
1963 return codecvt_base::error
;
1966 *to_nxt
= static_cast<uint16_t>(c1
);
1971 return codecvt_base::error
;
1975 if (frm_end
-frm_nxt
< 2)
1976 return codecvt_base::partial
;
1977 uint8_t c2
= frm_nxt
[1];
1978 if ((c2
& 0xC0) != 0x80)
1979 return codecvt_base::error
;
1980 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
1982 return codecvt_base::error
;
1988 if (frm_end
-frm_nxt
< 3)
1989 return codecvt_base::partial
;
1990 uint8_t c2
= frm_nxt
[1];
1991 uint8_t c3
= frm_nxt
[2];
1995 if ((c2
& 0xE0) != 0xA0)
1996 return codecvt_base::error
;
1999 if ((c2
& 0xE0) != 0x80)
2000 return codecvt_base::error
;
2003 if ((c2
& 0xC0) != 0x80)
2004 return codecvt_base::error
;
2007 if ((c3
& 0xC0) != 0x80)
2008 return codecvt_base::error
;
2009 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2010 | ((c2
& 0x3F) << 6)
2013 return codecvt_base::error
;
2019 if (frm_end
-frm_nxt
< 4)
2020 return codecvt_base::partial
;
2021 uint8_t c2
= frm_nxt
[1];
2022 uint8_t c3
= frm_nxt
[2];
2023 uint8_t c4
= frm_nxt
[3];
2027 if (!(0x90 <= c2
&& c2
<= 0xBF))
2028 return codecvt_base::error
;
2031 if ((c2
& 0xF0) != 0x80)
2032 return codecvt_base::error
;
2035 if ((c2
& 0xC0) != 0x80)
2036 return codecvt_base::error
;
2039 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2040 return codecvt_base::error
;
2041 if (to_end
-to_nxt
< 2)
2042 return codecvt_base::partial
;
2043 if ((((c1
& 7UL) << 18) +
2044 ((c2
& 0x3FUL
) << 12) +
2045 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2046 return codecvt_base::error
;
2047 *to_nxt
= static_cast<uint16_t>(
2049 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2050 | ((c2
& 0x0F) << 2)
2051 | ((c3
& 0x30) >> 4));
2052 *++to_nxt
= static_cast<uint16_t>(
2054 | ((c3
& 0x0F) << 6)
2060 return codecvt_base::error
;
2063 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2067 codecvt_base::result
2068 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2069 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2070 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2074 if (mode
& consume_header
)
2076 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2080 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2082 uint8_t c1
= *frm_nxt
;
2084 return codecvt_base::error
;
2087 *to_nxt
= static_cast<uint32_t>(c1
);
2092 return codecvt_base::error
;
2096 if (frm_end
-frm_nxt
< 2)
2097 return codecvt_base::partial
;
2098 uint8_t c2
= frm_nxt
[1];
2099 if ((c2
& 0xC0) != 0x80)
2100 return codecvt_base::error
;
2101 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2103 return codecvt_base::error
;
2104 *to_nxt
= static_cast<uint32_t>(t
);
2109 if (frm_end
-frm_nxt
< 3)
2110 return codecvt_base::partial
;
2111 uint8_t c2
= frm_nxt
[1];
2112 uint8_t c3
= frm_nxt
[2];
2116 if ((c2
& 0xE0) != 0xA0)
2117 return codecvt_base::error
;
2120 if ((c2
& 0xE0) != 0x80)
2121 return codecvt_base::error
;
2124 if ((c2
& 0xC0) != 0x80)
2125 return codecvt_base::error
;
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
< 4)
2141 return codecvt_base::partial
;
2142 uint8_t c2
= frm_nxt
[1];
2143 uint8_t c3
= frm_nxt
[2];
2144 uint8_t c4
= frm_nxt
[3];
2148 if (!(0x90 <= c2
&& c2
<= 0xBF))
2149 return codecvt_base::error
;
2152 if ((c2
& 0xF0) != 0x80)
2153 return codecvt_base::error
;
2156 if ((c2
& 0xC0) != 0x80)
2157 return codecvt_base::error
;
2160 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2161 return codecvt_base::error
;
2162 if (to_end
-to_nxt
< 2)
2163 return codecvt_base::partial
;
2164 if ((((c1
& 7UL) << 18) +
2165 ((c2
& 0x3FUL
) << 12) +
2166 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2167 return codecvt_base::error
;
2168 *to_nxt
= static_cast<uint32_t>(
2170 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2171 | ((c2
& 0x0F) << 2)
2172 | ((c3
& 0x30) >> 4));
2173 *++to_nxt
= static_cast<uint32_t>(
2175 | ((c3
& 0x0F) << 6)
2181 return codecvt_base::error
;
2184 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2189 utf8_to_utf16_length(const uint8_t* frm
, const uint8_t* frm_end
,
2190 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2191 codecvt_mode mode
= codecvt_mode(0))
2193 const uint8_t* frm_nxt
= frm
;
2194 if (mode
& consume_header
)
2196 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2200 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
&& nchar16_t
< mx
; ++nchar16_t
)
2202 uint8_t c1
= *frm_nxt
;
2215 if ((frm_end
-frm_nxt
< 2) || (frm_nxt
[1] & 0xC0) != 0x80)
2217 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (frm_nxt
[1] & 0x3F));
2224 if (frm_end
-frm_nxt
< 3)
2226 uint8_t c2
= frm_nxt
[1];
2227 uint8_t c3
= frm_nxt
[2];
2231 if ((c2
& 0xE0) != 0xA0)
2232 return static_cast<int>(frm_nxt
- frm
);
2235 if ((c2
& 0xE0) != 0x80)
2236 return static_cast<int>(frm_nxt
- frm
);
2239 if ((c2
& 0xC0) != 0x80)
2240 return static_cast<int>(frm_nxt
- frm
);
2243 if ((c3
& 0xC0) != 0x80)
2245 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2251 if (frm_end
-frm_nxt
< 4 || mx
-nchar16_t
< 2)
2253 uint8_t c2
= frm_nxt
[1];
2254 uint8_t c3
= frm_nxt
[2];
2255 uint8_t c4
= frm_nxt
[3];
2259 if (!(0x90 <= c2
&& c2
<= 0xBF))
2260 return static_cast<int>(frm_nxt
- frm
);
2263 if ((c2
& 0xF0) != 0x80)
2264 return static_cast<int>(frm_nxt
- frm
);
2267 if ((c2
& 0xC0) != 0x80)
2268 return static_cast<int>(frm_nxt
- frm
);
2271 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2273 if ((((c1
& 7UL) << 18) +
2274 ((c2
& 0x3FUL
) << 12) +
2275 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2285 return static_cast<int>(frm_nxt
- frm
);
2289 codecvt_base::result
2290 ucs4_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2291 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2292 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2296 if (mode
& generate_header
)
2298 if (to_end
-to_nxt
< 3)
2299 return codecvt_base::partial
;
2300 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2301 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2302 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2304 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2306 uint32_t wc
= *frm_nxt
;
2307 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2308 return codecvt_base::error
;
2311 if (to_end
-to_nxt
< 1)
2312 return codecvt_base::partial
;
2313 *to_nxt
++ = static_cast<uint8_t>(wc
);
2315 else if (wc
< 0x000800)
2317 if (to_end
-to_nxt
< 2)
2318 return codecvt_base::partial
;
2319 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2320 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2322 else if (wc
< 0x010000)
2324 if (to_end
-to_nxt
< 3)
2325 return codecvt_base::partial
;
2326 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2327 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2328 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2330 else // if (wc < 0x110000)
2332 if (to_end
-to_nxt
< 4)
2333 return codecvt_base::partial
;
2334 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (wc
>> 18));
2335 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x03F000) >> 12));
2336 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x000FC0) >> 6));
2337 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x00003F));
2340 return codecvt_base::ok
;
2344 codecvt_base::result
2345 utf8_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2346 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2347 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2351 if (mode
& consume_header
)
2353 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2357 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2359 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2363 return codecvt_base::error
;
2364 *to_nxt
= static_cast<uint32_t>(c1
);
2369 return codecvt_base::error
;
2373 if (frm_end
-frm_nxt
< 2)
2374 return codecvt_base::partial
;
2375 uint8_t c2
= frm_nxt
[1];
2376 if ((c2
& 0xC0) != 0x80)
2377 return codecvt_base::error
;
2378 uint32_t t
= static_cast<uint32_t>(((c1
& 0x1F) << 6)
2381 return codecvt_base::error
;
2387 if (frm_end
-frm_nxt
< 3)
2388 return codecvt_base::partial
;
2389 uint8_t c2
= frm_nxt
[1];
2390 uint8_t c3
= frm_nxt
[2];
2394 if ((c2
& 0xE0) != 0xA0)
2395 return codecvt_base::error
;
2398 if ((c2
& 0xE0) != 0x80)
2399 return codecvt_base::error
;
2402 if ((c2
& 0xC0) != 0x80)
2403 return codecvt_base::error
;
2406 if ((c3
& 0xC0) != 0x80)
2407 return codecvt_base::error
;
2408 uint32_t t
= static_cast<uint32_t>(((c1
& 0x0F) << 12)
2409 | ((c2
& 0x3F) << 6)
2412 return codecvt_base::error
;
2418 if (frm_end
-frm_nxt
< 4)
2419 return codecvt_base::partial
;
2420 uint8_t c2
= frm_nxt
[1];
2421 uint8_t c3
= frm_nxt
[2];
2422 uint8_t c4
= frm_nxt
[3];
2426 if (!(0x90 <= c2
&& c2
<= 0xBF))
2427 return codecvt_base::error
;
2430 if ((c2
& 0xF0) != 0x80)
2431 return codecvt_base::error
;
2434 if ((c2
& 0xC0) != 0x80)
2435 return codecvt_base::error
;
2438 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2439 return codecvt_base::error
;
2440 uint32_t t
= static_cast<uint32_t>(((c1
& 0x07) << 18)
2441 | ((c2
& 0x3F) << 12)
2442 | ((c3
& 0x3F) << 6)
2445 return codecvt_base::error
;
2451 return codecvt_base::error
;
2454 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2459 utf8_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2460 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2461 codecvt_mode mode
= codecvt_mode(0))
2463 const uint8_t* frm_nxt
= frm
;
2464 if (mode
& consume_header
)
2466 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2470 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2472 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2485 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2487 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2493 if (frm_end
-frm_nxt
< 3)
2495 uint8_t c2
= frm_nxt
[1];
2496 uint8_t c3
= frm_nxt
[2];
2500 if ((c2
& 0xE0) != 0xA0)
2501 return static_cast<int>(frm_nxt
- frm
);
2504 if ((c2
& 0xE0) != 0x80)
2505 return static_cast<int>(frm_nxt
- frm
);
2508 if ((c2
& 0xC0) != 0x80)
2509 return static_cast<int>(frm_nxt
- frm
);
2512 if ((c3
& 0xC0) != 0x80)
2514 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2520 if (frm_end
-frm_nxt
< 4)
2522 uint8_t c2
= frm_nxt
[1];
2523 uint8_t c3
= frm_nxt
[2];
2524 uint8_t c4
= frm_nxt
[3];
2528 if (!(0x90 <= c2
&& c2
<= 0xBF))
2529 return static_cast<int>(frm_nxt
- frm
);
2532 if ((c2
& 0xF0) != 0x80)
2533 return static_cast<int>(frm_nxt
- frm
);
2536 if ((c2
& 0xC0) != 0x80)
2537 return static_cast<int>(frm_nxt
- frm
);
2540 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2542 if ((((c1
& 0x07u
) << 18) | ((c2
& 0x3Fu
) << 12) |
2543 ((c3
& 0x3Fu
) << 6) | (c4
& 0x3Fu
)) > Maxcode
)
2552 return static_cast<int>(frm_nxt
- frm
);
2556 codecvt_base::result
2557 ucs2_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
2558 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2559 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2563 if (mode
& generate_header
)
2565 if (to_end
-to_nxt
< 3)
2566 return codecvt_base::partial
;
2567 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2568 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2569 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2571 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2573 uint16_t wc
= *frm_nxt
;
2574 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2575 return codecvt_base::error
;
2578 if (to_end
-to_nxt
< 1)
2579 return codecvt_base::partial
;
2580 *to_nxt
++ = static_cast<uint8_t>(wc
);
2582 else if (wc
< 0x0800)
2584 if (to_end
-to_nxt
< 2)
2585 return codecvt_base::partial
;
2586 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2587 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2589 else // if (wc <= 0xFFFF)
2591 if (to_end
-to_nxt
< 3)
2592 return codecvt_base::partial
;
2593 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2594 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2595 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2598 return codecvt_base::ok
;
2602 codecvt_base::result
2603 utf8_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2604 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
2605 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2609 if (mode
& consume_header
)
2611 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2615 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2617 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2621 return codecvt_base::error
;
2622 *to_nxt
= static_cast<uint16_t>(c1
);
2627 return codecvt_base::error
;
2631 if (frm_end
-frm_nxt
< 2)
2632 return codecvt_base::partial
;
2633 uint8_t c2
= frm_nxt
[1];
2634 if ((c2
& 0xC0) != 0x80)
2635 return codecvt_base::error
;
2636 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6)
2639 return codecvt_base::error
;
2645 if (frm_end
-frm_nxt
< 3)
2646 return codecvt_base::partial
;
2647 uint8_t c2
= frm_nxt
[1];
2648 uint8_t c3
= frm_nxt
[2];
2652 if ((c2
& 0xE0) != 0xA0)
2653 return codecvt_base::error
;
2656 if ((c2
& 0xE0) != 0x80)
2657 return codecvt_base::error
;
2660 if ((c2
& 0xC0) != 0x80)
2661 return codecvt_base::error
;
2664 if ((c3
& 0xC0) != 0x80)
2665 return codecvt_base::error
;
2666 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2667 | ((c2
& 0x3F) << 6)
2670 return codecvt_base::error
;
2676 return codecvt_base::error
;
2679 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2684 utf8_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
2685 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2686 codecvt_mode mode
= codecvt_mode(0))
2688 const uint8_t* frm_nxt
= frm
;
2689 if (mode
& consume_header
)
2691 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2695 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2697 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2710 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2712 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2718 if (frm_end
-frm_nxt
< 3)
2720 uint8_t c2
= frm_nxt
[1];
2721 uint8_t c3
= frm_nxt
[2];
2725 if ((c2
& 0xE0) != 0xA0)
2726 return static_cast<int>(frm_nxt
- frm
);
2729 if ((c2
& 0xE0) != 0x80)
2730 return static_cast<int>(frm_nxt
- frm
);
2733 if ((c2
& 0xC0) != 0x80)
2734 return static_cast<int>(frm_nxt
- frm
);
2737 if ((c3
& 0xC0) != 0x80)
2739 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2748 return static_cast<int>(frm_nxt
- frm
);
2752 codecvt_base::result
2753 ucs4_to_utf16be(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2754 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2755 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2759 if (mode
& generate_header
)
2761 if (to_end
-to_nxt
< 2)
2762 return codecvt_base::partial
;
2763 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2764 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2766 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2768 uint32_t wc
= *frm_nxt
;
2769 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2770 return codecvt_base::error
;
2773 if (to_end
-to_nxt
< 2)
2774 return codecvt_base::partial
;
2775 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2776 *to_nxt
++ = static_cast<uint8_t>(wc
);
2780 if (to_end
-to_nxt
< 4)
2781 return codecvt_base::partial
;
2782 uint16_t t
= static_cast<uint16_t>(
2784 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2785 | ((wc
& 0x00FC00) >> 10));
2786 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2787 *to_nxt
++ = static_cast<uint8_t>(t
);
2788 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2789 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2790 *to_nxt
++ = static_cast<uint8_t>(t
);
2793 return codecvt_base::ok
;
2797 codecvt_base::result
2798 utf16be_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2799 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2800 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2804 if (mode
& consume_header
)
2806 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2809 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2811 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2812 if ((c1
& 0xFC00) == 0xDC00)
2813 return codecvt_base::error
;
2814 if ((c1
& 0xFC00) != 0xD800)
2817 return codecvt_base::error
;
2818 *to_nxt
= static_cast<uint32_t>(c1
);
2823 if (frm_end
-frm_nxt
< 4)
2824 return codecvt_base::partial
;
2825 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2826 if ((c2
& 0xFC00) != 0xDC00)
2827 return codecvt_base::error
;
2828 uint32_t t
= static_cast<uint32_t>(
2829 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2830 | ((c1
& 0x003F) << 10)
2833 return codecvt_base::error
;
2838 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2843 utf16be_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2844 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2845 codecvt_mode mode
= codecvt_mode(0))
2847 const uint8_t* frm_nxt
= frm
;
2848 if (mode
& consume_header
)
2850 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2853 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2855 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2856 if ((c1
& 0xFC00) == 0xDC00)
2858 if ((c1
& 0xFC00) != 0xD800)
2866 if (frm_end
-frm_nxt
< 4)
2868 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2869 if ((c2
& 0xFC00) != 0xDC00)
2871 uint32_t t
= static_cast<uint32_t>(
2872 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2873 | ((c1
& 0x003F) << 10)
2880 return static_cast<int>(frm_nxt
- frm
);
2884 codecvt_base::result
2885 ucs4_to_utf16le(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2886 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2887 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2891 if (mode
& generate_header
)
2893 if (to_end
- to_nxt
< 2)
2894 return codecvt_base::partial
;
2895 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2896 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2898 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2900 uint32_t wc
= *frm_nxt
;
2901 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2902 return codecvt_base::error
;
2905 if (to_end
-to_nxt
< 2)
2906 return codecvt_base::partial
;
2907 *to_nxt
++ = static_cast<uint8_t>(wc
);
2908 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2912 if (to_end
-to_nxt
< 4)
2913 return codecvt_base::partial
;
2914 uint16_t t
= static_cast<uint16_t>(
2916 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2917 | ((wc
& 0x00FC00) >> 10));
2918 *to_nxt
++ = static_cast<uint8_t>(t
);
2919 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2920 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2921 *to_nxt
++ = static_cast<uint8_t>(t
);
2922 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2925 return codecvt_base::ok
;
2929 codecvt_base::result
2930 utf16le_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2931 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2932 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2936 if (mode
& consume_header
)
2938 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2941 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2943 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2944 if ((c1
& 0xFC00) == 0xDC00)
2945 return codecvt_base::error
;
2946 if ((c1
& 0xFC00) != 0xD800)
2949 return codecvt_base::error
;
2950 *to_nxt
= static_cast<uint32_t>(c1
);
2955 if (frm_end
-frm_nxt
< 4)
2956 return codecvt_base::partial
;
2957 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2958 if ((c2
& 0xFC00) != 0xDC00)
2959 return codecvt_base::error
;
2960 uint32_t t
= static_cast<uint32_t>(
2961 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2962 | ((c1
& 0x003F) << 10)
2965 return codecvt_base::error
;
2970 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2975 utf16le_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2976 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2977 codecvt_mode mode
= codecvt_mode(0))
2979 const uint8_t* frm_nxt
= frm
;
2980 if (mode
& consume_header
)
2982 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2985 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2987 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2988 if ((c1
& 0xFC00) == 0xDC00)
2990 if ((c1
& 0xFC00) != 0xD800)
2998 if (frm_end
-frm_nxt
< 4)
3000 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
3001 if ((c2
& 0xFC00) != 0xDC00)
3003 uint32_t t
= static_cast<uint32_t>(
3004 ((((c1
& 0x03C0) >> 6) + 1) << 16)
3005 | ((c1
& 0x003F) << 10)
3012 return static_cast<int>(frm_nxt
- frm
);
3016 codecvt_base::result
3017 ucs2_to_utf16be(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3018 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3019 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3023 if (mode
& generate_header
)
3025 if (to_end
-to_nxt
< 2)
3026 return codecvt_base::partial
;
3027 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3028 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3030 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3032 uint16_t wc
= *frm_nxt
;
3033 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3034 return codecvt_base::error
;
3035 if (to_end
-to_nxt
< 2)
3036 return codecvt_base::partial
;
3037 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3038 *to_nxt
++ = static_cast<uint8_t>(wc
);
3040 return codecvt_base::ok
;
3044 codecvt_base::result
3045 utf16be_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3046 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3047 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3051 if (mode
& consume_header
)
3053 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3056 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3058 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3059 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3060 return codecvt_base::error
;
3064 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3069 utf16be_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3070 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3071 codecvt_mode mode
= codecvt_mode(0))
3073 const uint8_t* frm_nxt
= frm
;
3074 if (mode
& consume_header
)
3076 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3079 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3081 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3082 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3086 return static_cast<int>(frm_nxt
- frm
);
3090 codecvt_base::result
3091 ucs2_to_utf16le(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3092 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3093 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3097 if (mode
& generate_header
)
3099 if (to_end
-to_nxt
< 2)
3100 return codecvt_base::partial
;
3101 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3102 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3104 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3106 uint16_t wc
= *frm_nxt
;
3107 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3108 return codecvt_base::error
;
3109 if (to_end
-to_nxt
< 2)
3110 return codecvt_base::partial
;
3111 *to_nxt
++ = static_cast<uint8_t>(wc
);
3112 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3114 return codecvt_base::ok
;
3118 codecvt_base::result
3119 utf16le_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3120 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3121 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3125 if (mode
& consume_header
)
3127 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3130 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3132 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3133 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3134 return codecvt_base::error
;
3138 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3143 utf16le_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3144 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3145 codecvt_mode mode
= codecvt_mode(0))
3147 const uint8_t* frm_nxt
= frm
;
3149 if (mode
& consume_header
)
3151 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3154 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3156 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3157 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3161 return static_cast<int>(frm_nxt
- frm
);
3164 _LIBCPP_SUPPRESS_DEPRECATED_POP
3166 // template <> class codecvt<char16_t, char, mbstate_t>
3168 constinit
locale::id codecvt
<char16_t
, char, mbstate_t>::id
;
3170 codecvt
<char16_t
, char, mbstate_t>::~codecvt()
3174 codecvt
<char16_t
, char, mbstate_t>::result
3175 codecvt
<char16_t
, char, mbstate_t>::do_out(state_type
&,
3176 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3177 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3179 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3180 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3181 const uint16_t* _frm_nxt
= _frm
;
3182 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3183 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3184 uint8_t* _to_nxt
= _to
;
3185 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3186 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3187 to_nxt
= to
+ (_to_nxt
- _to
);
3191 codecvt
<char16_t
, char, mbstate_t>::result
3192 codecvt
<char16_t
, char, mbstate_t>::do_in(state_type
&,
3193 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3194 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3196 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3197 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3198 const uint8_t* _frm_nxt
= _frm
;
3199 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3200 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3201 uint16_t* _to_nxt
= _to
;
3202 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3203 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3204 to_nxt
= to
+ (_to_nxt
- _to
);
3208 codecvt
<char16_t
, char, mbstate_t>::result
3209 codecvt
<char16_t
, char, mbstate_t>::do_unshift(state_type
&,
3210 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3217 codecvt
<char16_t
, char, mbstate_t>::do_encoding() const noexcept
3223 codecvt
<char16_t
, char, mbstate_t>::do_always_noconv() const noexcept
3229 codecvt
<char16_t
, char, mbstate_t>::do_length(state_type
&,
3230 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3232 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3233 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3234 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3238 codecvt
<char16_t
, char, mbstate_t>::do_max_length() const noexcept
3243 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3245 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3247 constinit
locale::id codecvt
<char16_t
, char8_t
, mbstate_t>::id
;
3249 codecvt
<char16_t
, char8_t
, mbstate_t>::~codecvt()
3253 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3254 codecvt
<char16_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3255 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3256 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3258 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3259 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3260 const uint16_t* _frm_nxt
= _frm
;
3261 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3262 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3263 uint8_t* _to_nxt
= _to
;
3264 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3265 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3266 to_nxt
= to
+ (_to_nxt
- _to
);
3270 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3271 codecvt
<char16_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3272 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3273 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3275 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3276 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3277 const uint8_t* _frm_nxt
= _frm
;
3278 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3279 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3280 uint16_t* _to_nxt
= _to
;
3281 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3282 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3283 to_nxt
= to
+ (_to_nxt
- _to
);
3287 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3288 codecvt
<char16_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3289 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3296 codecvt
<char16_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3302 codecvt
<char16_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3308 codecvt
<char16_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3309 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3311 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3312 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3313 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3317 codecvt
<char16_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3324 // template <> class codecvt<char32_t, char, mbstate_t>
3326 constinit
locale::id codecvt
<char32_t
, char, mbstate_t>::id
;
3328 codecvt
<char32_t
, char, mbstate_t>::~codecvt()
3332 codecvt
<char32_t
, char, mbstate_t>::result
3333 codecvt
<char32_t
, char, mbstate_t>::do_out(state_type
&,
3334 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3335 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3337 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3338 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3339 const uint32_t* _frm_nxt
= _frm
;
3340 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3341 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3342 uint8_t* _to_nxt
= _to
;
3343 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3344 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3345 to_nxt
= to
+ (_to_nxt
- _to
);
3349 codecvt
<char32_t
, char, mbstate_t>::result
3350 codecvt
<char32_t
, char, mbstate_t>::do_in(state_type
&,
3351 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3352 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3354 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3355 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3356 const uint8_t* _frm_nxt
= _frm
;
3357 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3358 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3359 uint32_t* _to_nxt
= _to
;
3360 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3361 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3362 to_nxt
= to
+ (_to_nxt
- _to
);
3366 codecvt
<char32_t
, char, mbstate_t>::result
3367 codecvt
<char32_t
, char, mbstate_t>::do_unshift(state_type
&,
3368 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3375 codecvt
<char32_t
, char, mbstate_t>::do_encoding() const noexcept
3381 codecvt
<char32_t
, char, mbstate_t>::do_always_noconv() const noexcept
3387 codecvt
<char32_t
, char, mbstate_t>::do_length(state_type
&,
3388 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3390 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3391 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3392 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3396 codecvt
<char32_t
, char, mbstate_t>::do_max_length() const noexcept
3401 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3403 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3405 constinit
locale::id codecvt
<char32_t
, char8_t
, mbstate_t>::id
;
3407 codecvt
<char32_t
, char8_t
, mbstate_t>::~codecvt()
3411 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3412 codecvt
<char32_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3413 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3414 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3416 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3417 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3418 const uint32_t* _frm_nxt
= _frm
;
3419 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3420 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3421 uint8_t* _to_nxt
= _to
;
3422 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3423 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3424 to_nxt
= to
+ (_to_nxt
- _to
);
3428 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3429 codecvt
<char32_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3430 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3431 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3433 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3434 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3435 const uint8_t* _frm_nxt
= _frm
;
3436 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3437 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3438 uint32_t* _to_nxt
= _to
;
3439 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3440 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3441 to_nxt
= to
+ (_to_nxt
- _to
);
3445 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3446 codecvt
<char32_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3447 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3454 codecvt
<char32_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3460 codecvt
<char32_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3466 codecvt
<char32_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3467 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3469 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3470 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3471 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3475 codecvt
<char32_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3482 // __codecvt_utf8<wchar_t>
3484 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3485 __codecvt_utf8
<wchar_t>::result
3486 __codecvt_utf8
<wchar_t>::do_out(state_type
&,
3487 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3488 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3490 #if defined(_LIBCPP_SHORT_WCHAR)
3491 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3492 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3493 const uint16_t* _frm_nxt
= _frm
;
3495 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3496 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3497 const uint32_t* _frm_nxt
= _frm
;
3499 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3500 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3501 uint8_t* _to_nxt
= _to
;
3502 #if defined(_LIBCPP_SHORT_WCHAR)
3503 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3504 __maxcode_
, __mode_
);
3506 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3507 __maxcode_
, __mode_
);
3509 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3510 to_nxt
= to
+ (_to_nxt
- _to
);
3514 __codecvt_utf8
<wchar_t>::result
3515 __codecvt_utf8
<wchar_t>::do_in(state_type
&,
3516 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3517 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3519 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3520 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3521 const uint8_t* _frm_nxt
= _frm
;
3522 #if defined(_LIBCPP_SHORT_WCHAR)
3523 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3524 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3525 uint16_t* _to_nxt
= _to
;
3526 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3527 __maxcode_
, __mode_
);
3529 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3530 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3531 uint32_t* _to_nxt
= _to
;
3532 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3533 __maxcode_
, __mode_
);
3535 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3536 to_nxt
= to
+ (_to_nxt
- _to
);
3540 __codecvt_utf8
<wchar_t>::result
3541 __codecvt_utf8
<wchar_t>::do_unshift(state_type
&,
3542 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3549 __codecvt_utf8
<wchar_t>::do_encoding() const noexcept
3555 __codecvt_utf8
<wchar_t>::do_always_noconv() const noexcept
3561 __codecvt_utf8
<wchar_t>::do_length(state_type
&,
3562 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3564 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3565 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3566 #if defined(_LIBCPP_SHORT_WCHAR)
3567 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3569 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3573 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3575 __codecvt_utf8
<wchar_t>::do_max_length() const noexcept
3577 #if defined(_LIBCPP_SHORT_WCHAR)
3578 if (__mode_
& consume_header
)
3582 if (__mode_
& consume_header
)
3587 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3589 // __codecvt_utf8<char16_t>
3591 __codecvt_utf8
<char16_t
>::result
3592 __codecvt_utf8
<char16_t
>::do_out(state_type
&,
3593 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3594 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3596 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3597 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3598 const uint16_t* _frm_nxt
= _frm
;
3599 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3600 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3601 uint8_t* _to_nxt
= _to
;
3602 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3603 __maxcode_
, __mode_
);
3604 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3605 to_nxt
= to
+ (_to_nxt
- _to
);
3609 __codecvt_utf8
<char16_t
>::result
3610 __codecvt_utf8
<char16_t
>::do_in(state_type
&,
3611 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3612 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3614 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3615 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3616 const uint8_t* _frm_nxt
= _frm
;
3617 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3618 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3619 uint16_t* _to_nxt
= _to
;
3620 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3621 __maxcode_
, __mode_
);
3622 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3623 to_nxt
= to
+ (_to_nxt
- _to
);
3627 __codecvt_utf8
<char16_t
>::result
3628 __codecvt_utf8
<char16_t
>::do_unshift(state_type
&,
3629 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3636 __codecvt_utf8
<char16_t
>::do_encoding() const noexcept
3642 __codecvt_utf8
<char16_t
>::do_always_noconv() const noexcept
3648 __codecvt_utf8
<char16_t
>::do_length(state_type
&,
3649 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3651 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3652 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3653 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3656 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3658 __codecvt_utf8
<char16_t
>::do_max_length() const noexcept
3660 if (__mode_
& consume_header
)
3664 _LIBCPP_SUPPRESS_DEPRECATED_POP
3666 // __codecvt_utf8<char32_t>
3668 __codecvt_utf8
<char32_t
>::result
3669 __codecvt_utf8
<char32_t
>::do_out(state_type
&,
3670 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3671 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3673 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3674 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3675 const uint32_t* _frm_nxt
= _frm
;
3676 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3677 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3678 uint8_t* _to_nxt
= _to
;
3679 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3680 __maxcode_
, __mode_
);
3681 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3682 to_nxt
= to
+ (_to_nxt
- _to
);
3686 __codecvt_utf8
<char32_t
>::result
3687 __codecvt_utf8
<char32_t
>::do_in(state_type
&,
3688 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3689 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3691 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3692 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3693 const uint8_t* _frm_nxt
= _frm
;
3694 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3695 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3696 uint32_t* _to_nxt
= _to
;
3697 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3698 __maxcode_
, __mode_
);
3699 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3700 to_nxt
= to
+ (_to_nxt
- _to
);
3704 __codecvt_utf8
<char32_t
>::result
3705 __codecvt_utf8
<char32_t
>::do_unshift(state_type
&,
3706 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3713 __codecvt_utf8
<char32_t
>::do_encoding() const noexcept
3719 __codecvt_utf8
<char32_t
>::do_always_noconv() const noexcept
3725 __codecvt_utf8
<char32_t
>::do_length(state_type
&,
3726 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3728 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3729 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3730 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3733 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3735 __codecvt_utf8
<char32_t
>::do_max_length() const noexcept
3737 if (__mode_
& consume_header
)
3741 _LIBCPP_SUPPRESS_DEPRECATED_POP
3743 // __codecvt_utf16<wchar_t, false>
3745 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3746 __codecvt_utf16
<wchar_t, false>::result
3747 __codecvt_utf16
<wchar_t, false>::do_out(state_type
&,
3748 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3749 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3751 #if defined(_LIBCPP_SHORT_WCHAR)
3752 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3753 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3754 const uint16_t* _frm_nxt
= _frm
;
3756 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3757 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3758 const uint32_t* _frm_nxt
= _frm
;
3760 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3761 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3762 uint8_t* _to_nxt
= _to
;
3763 #if defined(_LIBCPP_SHORT_WCHAR)
3764 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3765 __maxcode_
, __mode_
);
3767 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3768 __maxcode_
, __mode_
);
3770 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3771 to_nxt
= to
+ (_to_nxt
- _to
);
3775 __codecvt_utf16
<wchar_t, false>::result
3776 __codecvt_utf16
<wchar_t, false>::do_in(state_type
&,
3777 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3778 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3780 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3781 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3782 const uint8_t* _frm_nxt
= _frm
;
3783 #if defined(_LIBCPP_SHORT_WCHAR)
3784 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3785 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3786 uint16_t* _to_nxt
= _to
;
3787 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3788 __maxcode_
, __mode_
);
3790 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3791 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3792 uint32_t* _to_nxt
= _to
;
3793 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3794 __maxcode_
, __mode_
);
3796 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3797 to_nxt
= to
+ (_to_nxt
- _to
);
3801 __codecvt_utf16
<wchar_t, false>::result
3802 __codecvt_utf16
<wchar_t, false>::do_unshift(state_type
&,
3803 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3810 __codecvt_utf16
<wchar_t, false>::do_encoding() const noexcept
3816 __codecvt_utf16
<wchar_t, false>::do_always_noconv() const noexcept
3822 __codecvt_utf16
<wchar_t, false>::do_length(state_type
&,
3823 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3825 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3826 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3827 #if defined(_LIBCPP_SHORT_WCHAR)
3828 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3830 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3835 __codecvt_utf16
<wchar_t, false>::do_max_length() const noexcept
3837 #if defined(_LIBCPP_SHORT_WCHAR)
3838 if (__mode_
& consume_header
)
3842 if (__mode_
& consume_header
)
3848 // __codecvt_utf16<wchar_t, true>
3850 __codecvt_utf16
<wchar_t, true>::result
3851 __codecvt_utf16
<wchar_t, true>::do_out(state_type
&,
3852 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3853 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3855 #if defined(_LIBCPP_SHORT_WCHAR)
3856 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3857 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3858 const uint16_t* _frm_nxt
= _frm
;
3860 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3861 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3862 const uint32_t* _frm_nxt
= _frm
;
3864 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3865 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3866 uint8_t* _to_nxt
= _to
;
3867 #if defined(_LIBCPP_SHORT_WCHAR)
3868 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3869 __maxcode_
, __mode_
);
3871 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3872 __maxcode_
, __mode_
);
3874 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3875 to_nxt
= to
+ (_to_nxt
- _to
);
3879 __codecvt_utf16
<wchar_t, true>::result
3880 __codecvt_utf16
<wchar_t, true>::do_in(state_type
&,
3881 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3882 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3884 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3885 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3886 const uint8_t* _frm_nxt
= _frm
;
3887 #if defined(_LIBCPP_SHORT_WCHAR)
3888 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3889 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3890 uint16_t* _to_nxt
= _to
;
3891 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3892 __maxcode_
, __mode_
);
3894 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3895 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3896 uint32_t* _to_nxt
= _to
;
3897 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3898 __maxcode_
, __mode_
);
3900 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3901 to_nxt
= to
+ (_to_nxt
- _to
);
3905 __codecvt_utf16
<wchar_t, true>::result
3906 __codecvt_utf16
<wchar_t, true>::do_unshift(state_type
&,
3907 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3914 __codecvt_utf16
<wchar_t, true>::do_encoding() const noexcept
3920 __codecvt_utf16
<wchar_t, true>::do_always_noconv() const noexcept
3926 __codecvt_utf16
<wchar_t, true>::do_length(state_type
&,
3927 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3929 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3930 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3931 #if defined(_LIBCPP_SHORT_WCHAR)
3932 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3934 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3939 __codecvt_utf16
<wchar_t, true>::do_max_length() const noexcept
3941 #if defined(_LIBCPP_SHORT_WCHAR)
3942 if (__mode_
& consume_header
)
3946 if (__mode_
& consume_header
)
3951 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3953 // __codecvt_utf16<char16_t, false>
3955 __codecvt_utf16
<char16_t
, false>::result
3956 __codecvt_utf16
<char16_t
, false>::do_out(state_type
&,
3957 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3958 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3960 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3961 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3962 const uint16_t* _frm_nxt
= _frm
;
3963 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3964 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3965 uint8_t* _to_nxt
= _to
;
3966 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3967 __maxcode_
, __mode_
);
3968 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3969 to_nxt
= to
+ (_to_nxt
- _to
);
3973 __codecvt_utf16
<char16_t
, false>::result
3974 __codecvt_utf16
<char16_t
, false>::do_in(state_type
&,
3975 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3976 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3978 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3979 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3980 const uint8_t* _frm_nxt
= _frm
;
3981 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3982 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3983 uint16_t* _to_nxt
= _to
;
3984 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3985 __maxcode_
, __mode_
);
3986 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3987 to_nxt
= to
+ (_to_nxt
- _to
);
3991 __codecvt_utf16
<char16_t
, false>::result
3992 __codecvt_utf16
<char16_t
, false>::do_unshift(state_type
&,
3993 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4000 __codecvt_utf16
<char16_t
, false>::do_encoding() const noexcept
4006 __codecvt_utf16
<char16_t
, false>::do_always_noconv() const noexcept
4012 __codecvt_utf16
<char16_t
, false>::do_length(state_type
&,
4013 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4015 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4016 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4017 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4020 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4022 __codecvt_utf16
<char16_t
, false>::do_max_length() const noexcept
4024 if (__mode_
& consume_header
)
4028 _LIBCPP_SUPPRESS_DEPRECATED_POP
4030 // __codecvt_utf16<char16_t, true>
4032 __codecvt_utf16
<char16_t
, true>::result
4033 __codecvt_utf16
<char16_t
, true>::do_out(state_type
&,
4034 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4035 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4037 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4038 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4039 const uint16_t* _frm_nxt
= _frm
;
4040 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4041 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4042 uint8_t* _to_nxt
= _to
;
4043 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4044 __maxcode_
, __mode_
);
4045 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4046 to_nxt
= to
+ (_to_nxt
- _to
);
4050 __codecvt_utf16
<char16_t
, true>::result
4051 __codecvt_utf16
<char16_t
, true>::do_in(state_type
&,
4052 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4053 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4055 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4056 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4057 const uint8_t* _frm_nxt
= _frm
;
4058 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4059 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4060 uint16_t* _to_nxt
= _to
;
4061 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4062 __maxcode_
, __mode_
);
4063 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4064 to_nxt
= to
+ (_to_nxt
- _to
);
4068 __codecvt_utf16
<char16_t
, true>::result
4069 __codecvt_utf16
<char16_t
, true>::do_unshift(state_type
&,
4070 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4077 __codecvt_utf16
<char16_t
, true>::do_encoding() const noexcept
4083 __codecvt_utf16
<char16_t
, true>::do_always_noconv() const noexcept
4089 __codecvt_utf16
<char16_t
, true>::do_length(state_type
&,
4090 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4092 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4093 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4094 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4097 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4099 __codecvt_utf16
<char16_t
, true>::do_max_length() const noexcept
4101 if (__mode_
& consume_header
)
4105 _LIBCPP_SUPPRESS_DEPRECATED_POP
4107 // __codecvt_utf16<char32_t, false>
4109 __codecvt_utf16
<char32_t
, false>::result
4110 __codecvt_utf16
<char32_t
, false>::do_out(state_type
&,
4111 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4112 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4114 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4115 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4116 const uint32_t* _frm_nxt
= _frm
;
4117 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4118 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4119 uint8_t* _to_nxt
= _to
;
4120 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4121 __maxcode_
, __mode_
);
4122 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4123 to_nxt
= to
+ (_to_nxt
- _to
);
4127 __codecvt_utf16
<char32_t
, false>::result
4128 __codecvt_utf16
<char32_t
, false>::do_in(state_type
&,
4129 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4130 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4132 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4133 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4134 const uint8_t* _frm_nxt
= _frm
;
4135 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4136 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4137 uint32_t* _to_nxt
= _to
;
4138 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4139 __maxcode_
, __mode_
);
4140 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4141 to_nxt
= to
+ (_to_nxt
- _to
);
4145 __codecvt_utf16
<char32_t
, false>::result
4146 __codecvt_utf16
<char32_t
, false>::do_unshift(state_type
&,
4147 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4154 __codecvt_utf16
<char32_t
, false>::do_encoding() const noexcept
4160 __codecvt_utf16
<char32_t
, false>::do_always_noconv() const noexcept
4166 __codecvt_utf16
<char32_t
, false>::do_length(state_type
&,
4167 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4169 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4170 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4171 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4174 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4176 __codecvt_utf16
<char32_t
, false>::do_max_length() const noexcept
4178 if (__mode_
& consume_header
)
4182 _LIBCPP_SUPPRESS_DEPRECATED_POP
4184 // __codecvt_utf16<char32_t, true>
4186 __codecvt_utf16
<char32_t
, true>::result
4187 __codecvt_utf16
<char32_t
, true>::do_out(state_type
&,
4188 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4189 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4191 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4192 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4193 const uint32_t* _frm_nxt
= _frm
;
4194 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4195 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4196 uint8_t* _to_nxt
= _to
;
4197 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4198 __maxcode_
, __mode_
);
4199 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4200 to_nxt
= to
+ (_to_nxt
- _to
);
4204 __codecvt_utf16
<char32_t
, true>::result
4205 __codecvt_utf16
<char32_t
, true>::do_in(state_type
&,
4206 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4207 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4209 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4210 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4211 const uint8_t* _frm_nxt
= _frm
;
4212 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4213 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4214 uint32_t* _to_nxt
= _to
;
4215 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4216 __maxcode_
, __mode_
);
4217 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4218 to_nxt
= to
+ (_to_nxt
- _to
);
4222 __codecvt_utf16
<char32_t
, true>::result
4223 __codecvt_utf16
<char32_t
, true>::do_unshift(state_type
&,
4224 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4231 __codecvt_utf16
<char32_t
, true>::do_encoding() const noexcept
4237 __codecvt_utf16
<char32_t
, true>::do_always_noconv() const noexcept
4243 __codecvt_utf16
<char32_t
, true>::do_length(state_type
&,
4244 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4246 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4247 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4248 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4251 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4253 __codecvt_utf16
<char32_t
, true>::do_max_length() const noexcept
4255 if (__mode_
& consume_header
)
4259 _LIBCPP_SUPPRESS_DEPRECATED_POP
4261 // __codecvt_utf8_utf16<wchar_t>
4263 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4264 __codecvt_utf8_utf16
<wchar_t>::result
4265 __codecvt_utf8_utf16
<wchar_t>::do_out(state_type
&,
4266 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4267 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4269 #if defined(_LIBCPP_SHORT_WCHAR)
4270 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4271 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4272 const uint16_t* _frm_nxt
= _frm
;
4274 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4275 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4276 const uint32_t* _frm_nxt
= _frm
;
4278 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4279 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4280 uint8_t* _to_nxt
= _to
;
4281 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4282 __maxcode_
, __mode_
);
4283 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4284 to_nxt
= to
+ (_to_nxt
- _to
);
4288 __codecvt_utf8_utf16
<wchar_t>::result
4289 __codecvt_utf8_utf16
<wchar_t>::do_in(state_type
&,
4290 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4291 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4293 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4294 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4295 const uint8_t* _frm_nxt
= _frm
;
4296 #if defined(_LIBCPP_SHORT_WCHAR)
4297 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4298 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4299 uint16_t* _to_nxt
= _to
;
4301 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4302 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4303 uint32_t* _to_nxt
= _to
;
4305 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4306 __maxcode_
, __mode_
);
4307 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4308 to_nxt
= to
+ (_to_nxt
- _to
);
4312 __codecvt_utf8_utf16
<wchar_t>::result
4313 __codecvt_utf8_utf16
<wchar_t>::do_unshift(state_type
&,
4314 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4321 __codecvt_utf8_utf16
<wchar_t>::do_encoding() const noexcept
4327 __codecvt_utf8_utf16
<wchar_t>::do_always_noconv() const noexcept
4333 __codecvt_utf8_utf16
<wchar_t>::do_length(state_type
&,
4334 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4336 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4337 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4338 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4342 __codecvt_utf8_utf16
<wchar_t>::do_max_length() const noexcept
4344 if (__mode_
& consume_header
)
4348 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4350 // __codecvt_utf8_utf16<char16_t>
4352 __codecvt_utf8_utf16
<char16_t
>::result
4353 __codecvt_utf8_utf16
<char16_t
>::do_out(state_type
&,
4354 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4355 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4357 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4358 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4359 const uint16_t* _frm_nxt
= _frm
;
4360 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4361 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4362 uint8_t* _to_nxt
= _to
;
4363 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4364 __maxcode_
, __mode_
);
4365 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4366 to_nxt
= to
+ (_to_nxt
- _to
);
4370 __codecvt_utf8_utf16
<char16_t
>::result
4371 __codecvt_utf8_utf16
<char16_t
>::do_in(state_type
&,
4372 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4373 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4375 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4376 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4377 const uint8_t* _frm_nxt
= _frm
;
4378 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4379 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4380 uint16_t* _to_nxt
= _to
;
4381 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4382 __maxcode_
, __mode_
);
4383 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4384 to_nxt
= to
+ (_to_nxt
- _to
);
4388 __codecvt_utf8_utf16
<char16_t
>::result
4389 __codecvt_utf8_utf16
<char16_t
>::do_unshift(state_type
&,
4390 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4397 __codecvt_utf8_utf16
<char16_t
>::do_encoding() const noexcept
4403 __codecvt_utf8_utf16
<char16_t
>::do_always_noconv() const noexcept
4409 __codecvt_utf8_utf16
<char16_t
>::do_length(state_type
&,
4410 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4412 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4413 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4414 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4417 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4419 __codecvt_utf8_utf16
<char16_t
>::do_max_length() const noexcept
4421 if (__mode_
& consume_header
)
4425 _LIBCPP_SUPPRESS_DEPRECATED_POP
4427 // __codecvt_utf8_utf16<char32_t>
4429 __codecvt_utf8_utf16
<char32_t
>::result
4430 __codecvt_utf8_utf16
<char32_t
>::do_out(state_type
&,
4431 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4432 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4434 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4435 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4436 const uint32_t* _frm_nxt
= _frm
;
4437 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4438 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4439 uint8_t* _to_nxt
= _to
;
4440 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4441 __maxcode_
, __mode_
);
4442 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4443 to_nxt
= to
+ (_to_nxt
- _to
);
4447 __codecvt_utf8_utf16
<char32_t
>::result
4448 __codecvt_utf8_utf16
<char32_t
>::do_in(state_type
&,
4449 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4450 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4452 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4453 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4454 const uint8_t* _frm_nxt
= _frm
;
4455 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4456 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4457 uint32_t* _to_nxt
= _to
;
4458 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4459 __maxcode_
, __mode_
);
4460 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4461 to_nxt
= to
+ (_to_nxt
- _to
);
4465 __codecvt_utf8_utf16
<char32_t
>::result
4466 __codecvt_utf8_utf16
<char32_t
>::do_unshift(state_type
&,
4467 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4474 __codecvt_utf8_utf16
<char32_t
>::do_encoding() const noexcept
4480 __codecvt_utf8_utf16
<char32_t
>::do_always_noconv() const noexcept
4486 __codecvt_utf8_utf16
<char32_t
>::do_length(state_type
&,
4487 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4489 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4490 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4491 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4494 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4496 __codecvt_utf8_utf16
<char32_t
>::do_max_length() const noexcept
4498 if (__mode_
& consume_header
)
4502 _LIBCPP_SUPPRESS_DEPRECATED_POP
4504 // __narrow_to_utf8<16>
4506 __narrow_to_utf8
<16>::~__narrow_to_utf8()
4510 // __narrow_to_utf8<32>
4512 __narrow_to_utf8
<32>::~__narrow_to_utf8()
4516 // __widen_from_utf8<16>
4518 __widen_from_utf8
<16>::~__widen_from_utf8()
4522 // __widen_from_utf8<32>
4524 __widen_from_utf8
<32>::~__widen_from_utf8()
4528 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4529 static bool checked_string_to_wchar_convert(wchar_t& dest
,
4536 size_t ret
= __libcpp_mbrtowc_l(&out
, ptr
, strlen(ptr
), &mb
, loc
);
4537 if (ret
== static_cast<size_t>(-1) || ret
== static_cast<size_t>(-2)) {
4543 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4545 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4546 static bool is_narrow_non_breaking_space(const char* ptr
) {
4547 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4548 return ptr
[0] == '\xe2' && ptr
[1] == '\x80' && ptr
[2] == '\xaf';
4551 static bool is_non_breaking_space(const char* ptr
) {
4552 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4553 return ptr
[0] == '\xc2' && ptr
[1] == '\xa0';
4555 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4557 static bool checked_string_to_char_convert(char& dest
,
4567 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4568 // First convert the MBS into a wide char then attempt to narrow it using
4571 if (!checked_string_to_wchar_convert(wout
, ptr
, __loc
))
4574 if ((res
= __libcpp_wctob_l(wout
, __loc
)) != char_traits
<char>::eof()) {
4578 // FIXME: Work around specific multibyte sequences that we can reasonably
4579 // translate into a different single byte.
4581 case L
'\u202F': // narrow non-breaking space
4582 case L
'\u00A0': // non-breaking space
4588 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4589 // FIXME: Work around specific multibyte sequences that we can reasonably
4590 // translate into a different single byte.
4591 if (is_narrow_non_breaking_space(ptr
) || is_non_breaking_space(ptr
)) {
4597 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4598 __libcpp_unreachable();
4602 // numpunct<char> && numpunct<wchar_t>
4604 constinit
locale::id numpunct
<char>::id
;
4605 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4606 constinit
locale::id numpunct
<wchar_t>::id
;
4609 numpunct
<char>::numpunct(size_t refs
)
4610 : locale::facet(refs
),
4611 __decimal_point_('.'),
4612 __thousands_sep_(',')
4616 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4617 numpunct
<wchar_t>::numpunct(size_t refs
)
4618 : locale::facet(refs
),
4619 __decimal_point_(L
'.'),
4620 __thousands_sep_(L
',')
4625 numpunct
<char>::~numpunct()
4629 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4630 numpunct
<wchar_t>::~numpunct()
4635 char numpunct
< char >::do_decimal_point() const {return __decimal_point_
;}
4636 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4637 wchar_t numpunct
<wchar_t>::do_decimal_point() const {return __decimal_point_
;}
4640 char numpunct
< char >::do_thousands_sep() const {return __thousands_sep_
;}
4641 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4642 wchar_t numpunct
<wchar_t>::do_thousands_sep() const {return __thousands_sep_
;}
4645 string numpunct
< char >::do_grouping() const {return __grouping_
;}
4646 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4647 string numpunct
<wchar_t>::do_grouping() const {return __grouping_
;}
4650 string numpunct
< char >::do_truename() const {return "true";}
4651 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4652 wstring numpunct
<wchar_t>::do_truename() const {return L
"true";}
4655 string numpunct
< char >::do_falsename() const {return "false";}
4656 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4657 wstring numpunct
<wchar_t>::do_falsename() const {return L
"false";}
4660 // numpunct_byname<char>
4662 numpunct_byname
<char>::numpunct_byname(const char* nm
, size_t refs
)
4663 : numpunct
<char>(refs
)
4668 numpunct_byname
<char>::numpunct_byname(const string
& nm
, size_t refs
)
4669 : numpunct
<char>(refs
)
4674 numpunct_byname
<char>::~numpunct_byname()
4679 numpunct_byname
<char>::__init(const char* nm
)
4681 typedef numpunct
<char> base
;
4682 if (strcmp(nm
, "C") != 0)
4684 __libcpp_unique_locale
loc(nm
);
4686 __throw_runtime_error(("numpunct_byname<char>::numpunct_byname"
4687 " failed to construct for " + string(nm
)).c_str());
4689 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4690 if (!checked_string_to_char_convert(__decimal_point_
, lc
->decimal_point
,
4692 __decimal_point_
= base::do_decimal_point();
4693 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->thousands_sep
,
4695 __thousands_sep_
= base::do_thousands_sep();
4696 __grouping_
= lc
->grouping
;
4697 // localization for truename and falsename is not available
4701 // numpunct_byname<wchar_t>
4703 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4704 numpunct_byname
<wchar_t>::numpunct_byname(const char* nm
, size_t refs
)
4705 : numpunct
<wchar_t>(refs
)
4710 numpunct_byname
<wchar_t>::numpunct_byname(const string
& nm
, size_t refs
)
4711 : numpunct
<wchar_t>(refs
)
4716 numpunct_byname
<wchar_t>::~numpunct_byname()
4721 numpunct_byname
<wchar_t>::__init(const char* nm
)
4723 if (strcmp(nm
, "C") != 0)
4725 __libcpp_unique_locale
loc(nm
);
4727 __throw_runtime_error(("numpunct_byname<wchar_t>::numpunct_byname"
4728 " failed to construct for " + string(nm
)).c_str());
4730 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4731 checked_string_to_wchar_convert(__decimal_point_
, lc
->decimal_point
,
4733 checked_string_to_wchar_convert(__thousands_sep_
, lc
->thousands_sep
,
4735 __grouping_
= lc
->grouping
;
4736 // localization for truename and falsename is not available
4739 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4744 __num_get_base::__get_base(ios_base
& iob
)
4746 ios_base::fmtflags __basefield
= iob
.flags() & ios_base::basefield
;
4747 if (__basefield
== ios_base::oct
)
4749 else if (__basefield
== ios_base::hex
)
4751 else if (__basefield
== 0)
4756 const char __num_get_base::__src
[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4759 __check_grouping(const string
& __grouping
, unsigned* __g
, unsigned* __g_end
,
4760 ios_base::iostate
& __err
)
4762 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4763 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4764 if (__grouping
.size() != 0 && __g_end
- __g
> 1)
4766 reverse(__g
, __g_end
);
4767 const char* __ig
= __grouping
.data();
4768 const char* __eg
= __ig
+ __grouping
.size();
4769 for (unsigned* __r
= __g
; __r
< __g_end
-1; ++__r
)
4771 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4773 if (static_cast<unsigned>(*__ig
) != *__r
)
4775 __err
= ios_base::failbit
;
4779 if (__eg
- __ig
> 1)
4782 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4784 if (static_cast<unsigned>(*__ig
) < __g_end
[-1] || __g_end
[-1] == 0)
4785 __err
= ios_base::failbit
;
4791 __num_put_base::__format_int(char* __fmtp
, const char* __len
, bool __signd
,
4792 ios_base::fmtflags __flags
)
4794 if ((__flags
& ios_base::showpos
) &&
4795 (__flags
& ios_base::basefield
) != ios_base::oct
&&
4796 (__flags
& ios_base::basefield
) != ios_base::hex
&&
4799 if (__flags
& ios_base::showbase
)
4802 *__fmtp
++ = *__len
++;
4803 if ((__flags
& ios_base::basefield
) == ios_base::oct
)
4805 else if ((__flags
& ios_base::basefield
) == ios_base::hex
)
4807 if (__flags
& ios_base::uppercase
)
4819 __num_put_base::__format_float(char* __fmtp
, const char* __len
,
4820 ios_base::fmtflags __flags
)
4822 bool specify_precision
= true;
4823 if (__flags
& ios_base::showpos
)
4825 if (__flags
& ios_base::showpoint
)
4827 ios_base::fmtflags floatfield
= __flags
& ios_base::floatfield
;
4828 bool uppercase
= (__flags
& ios_base::uppercase
) != 0;
4829 if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4830 specify_precision
= false;
4837 *__fmtp
++ = *__len
++;
4838 if (floatfield
== ios_base::fixed
)
4845 else if (floatfield
== ios_base::scientific
)
4852 else if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4866 return specify_precision
;
4870 __num_put_base::__identify_padding(char* __nb
, char* __ne
,
4871 const ios_base
& __iob
)
4873 switch (__iob
.flags() & ios_base::adjustfield
)
4875 case ios_base::internal
:
4876 if (__nb
[0] == '-' || __nb
[0] == '+')
4878 if (__ne
- __nb
>= 2 && __nb
[0] == '0'
4879 && (__nb
[1] == 'x' || __nb
[1] == 'X'))
4882 case ios_base::left
:
4884 case ios_base::right
:
4897 static string weeks
[14];
4898 weeks
[0] = "Sunday";
4899 weeks
[1] = "Monday";
4900 weeks
[2] = "Tuesday";
4901 weeks
[3] = "Wednesday";
4902 weeks
[4] = "Thursday";
4903 weeks
[5] = "Friday";
4904 weeks
[6] = "Saturday";
4915 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4920 static wstring weeks
[14];
4921 weeks
[0] = L
"Sunday";
4922 weeks
[1] = L
"Monday";
4923 weeks
[2] = L
"Tuesday";
4924 weeks
[3] = L
"Wednesday";
4925 weeks
[4] = L
"Thursday";
4926 weeks
[5] = L
"Friday";
4927 weeks
[6] = L
"Saturday";
4941 __time_get_c_storage
<char>::__weeks() const
4943 static const string
* weeks
= init_weeks();
4947 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4950 __time_get_c_storage
<wchar_t>::__weeks() const
4952 static const wstring
* weeks
= init_wweeks();
4961 static string months
[24];
4962 months
[0] = "January";
4963 months
[1] = "February";
4964 months
[2] = "March";
4965 months
[3] = "April";
4969 months
[7] = "August";
4970 months
[8] = "September";
4971 months
[9] = "October";
4972 months
[10] = "November";
4973 months
[11] = "December";
4989 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4994 static wstring months
[24];
4995 months
[0] = L
"January";
4996 months
[1] = L
"February";
4997 months
[2] = L
"March";
4998 months
[3] = L
"April";
5000 months
[5] = L
"June";
5001 months
[6] = L
"July";
5002 months
[7] = L
"August";
5003 months
[8] = L
"September";
5004 months
[9] = L
"October";
5005 months
[10] = L
"November";
5006 months
[11] = L
"December";
5007 months
[12] = L
"Jan";
5008 months
[13] = L
"Feb";
5009 months
[14] = L
"Mar";
5010 months
[15] = L
"Apr";
5011 months
[16] = L
"May";
5012 months
[17] = L
"Jun";
5013 months
[18] = L
"Jul";
5014 months
[19] = L
"Aug";
5015 months
[20] = L
"Sep";
5016 months
[21] = L
"Oct";
5017 months
[22] = L
"Nov";
5018 months
[23] = L
"Dec";
5025 __time_get_c_storage
<char>::__months() const
5027 static const string
* months
= init_months();
5031 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5034 __time_get_c_storage
<wchar_t>::__months() const
5036 static const wstring
* months
= init_wmonths();
5045 static string am_pm
[2];
5051 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5056 static wstring am_pm
[2];
5065 __time_get_c_storage
<char>::__am_pm() const
5067 static const string
* am_pm
= init_am_pm();
5071 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5074 __time_get_c_storage
<wchar_t>::__am_pm() const
5076 static const wstring
* am_pm
= init_wam_pm();
5083 __time_get_c_storage
<char>::__x() const
5085 static string
s("%m/%d/%y");
5089 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5092 __time_get_c_storage
<wchar_t>::__x() const
5094 static wstring
s(L
"%m/%d/%y");
5101 __time_get_c_storage
<char>::__X() const
5103 static string
s("%H:%M:%S");
5107 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5110 __time_get_c_storage
<wchar_t>::__X() const
5112 static wstring
s(L
"%H:%M:%S");
5119 __time_get_c_storage
<char>::__c() const
5121 static string
s("%a %b %d %H:%M:%S %Y");
5125 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5128 __time_get_c_storage
<wchar_t>::__c() const
5130 static wstring
s(L
"%a %b %d %H:%M:%S %Y");
5137 __time_get_c_storage
<char>::__r() const
5139 static string
s("%I:%M:%S %p");
5143 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5146 __time_get_c_storage
<wchar_t>::__r() const
5148 static wstring
s(L
"%I:%M:%S %p");
5155 __time_get::__time_get(const char* nm
)
5156 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5159 __throw_runtime_error(("time_get_byname failed to construct for " + string(nm
)).c_str());
5162 __time_get::__time_get(const string
& nm
)
5163 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5166 __throw_runtime_error(("time_get_byname failed to construct for " + nm
).c_str());
5169 __time_get::~__time_get()
5174 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5178 __time_get_storage
<char>::__analyze(char fmt
, const ctype
<char>& ct
)
5194 size_t n
= strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5200 if (ct
.is(ctype_base::space
, *bb
))
5202 result
.push_back(' ');
5203 for (++bb
; bb
!= be
&& ct
.is(ctype_base::space
, *bb
); ++bb
)
5208 ios_base::iostate err
= ios_base::goodbit
;
5209 ptrdiff_t i
= __scan_keyword(w
, be
, this->__weeks_
, this->__weeks_
+14,
5214 result
.push_back('%');
5216 result
.push_back('A');
5218 result
.push_back('a');
5223 i
= __scan_keyword(w
, be
, this->__months_
, this->__months_
+24,
5228 result
.push_back('%');
5230 result
.push_back('B');
5232 result
.push_back('b');
5233 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5234 result
.back() = 'm';
5238 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5241 i
= __scan_keyword(w
, be
, this->__am_pm_
, this->__am_pm_
+2,
5242 ct
, err
, false) - this->__am_pm_
;
5245 result
.push_back('%');
5246 result
.push_back('p');
5252 if (ct
.is(ctype_base::digit
, *bb
))
5254 switch(__get_up_to_n_digits(bb
, be
, err
, ct
, 4))
5257 result
.push_back('%');
5258 result
.push_back('w');
5261 result
.push_back('%');
5262 result
.push_back('u');
5265 result
.push_back('%');
5266 result
.push_back('I');
5269 result
.push_back('%');
5270 result
.push_back('m');
5273 result
.push_back('%');
5274 result
.push_back('H');
5277 result
.push_back('%');
5278 result
.push_back('d');
5281 result
.push_back('%');
5282 result
.push_back('M');
5285 result
.push_back('%');
5286 result
.push_back('S');
5289 result
.push_back('%');
5290 result
.push_back('y');
5293 result
.push_back('%');
5294 result
.push_back('j');
5297 result
.push_back('%');
5298 result
.push_back('Y');
5301 for (; w
!= bb
; ++w
)
5302 result
.push_back(*w
);
5309 result
.push_back('%');
5310 result
.push_back('%');
5314 result
.push_back(*bb
);
5320 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5322 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5325 __time_get_storage
<wchar_t>::__analyze(char fmt
, const ctype
<wchar_t>& ct
)
5341 strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5343 wchar_t* wbb
= wbuf
;
5345 const char* bb
= buf
;
5346 size_t j
= __libcpp_mbsrtowcs_l( wbb
, &bb
, countof(wbuf
), &mb
, __loc_
);
5347 if (j
== size_t(-1))
5348 __throw_runtime_error("locale not supported");
5349 wchar_t* wbe
= wbb
+ j
;
5353 if (ct
.is(ctype_base::space
, *wbb
))
5355 result
.push_back(L
' ');
5356 for (++wbb
; wbb
!= wbe
&& ct
.is(ctype_base::space
, *wbb
); ++wbb
)
5361 ios_base::iostate err
= ios_base::goodbit
;
5362 ptrdiff_t i
= __scan_keyword(w
, wbe
, this->__weeks_
, this->__weeks_
+14,
5367 result
.push_back(L
'%');
5369 result
.push_back(L
'A');
5371 result
.push_back(L
'a');
5376 i
= __scan_keyword(w
, wbe
, this->__months_
, this->__months_
+24,
5381 result
.push_back(L
'%');
5383 result
.push_back(L
'B');
5385 result
.push_back(L
'b');
5386 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5387 result
.back() = L
'm';
5391 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5394 i
= __scan_keyword(w
, wbe
, this->__am_pm_
, this->__am_pm_
+2,
5395 ct
, err
, false) - this->__am_pm_
;
5398 result
.push_back(L
'%');
5399 result
.push_back(L
'p');
5405 if (ct
.is(ctype_base::digit
, *wbb
))
5407 switch(__get_up_to_n_digits(wbb
, wbe
, err
, ct
, 4))
5410 result
.push_back(L
'%');
5411 result
.push_back(L
'w');
5414 result
.push_back(L
'%');
5415 result
.push_back(L
'u');
5418 result
.push_back(L
'%');
5419 result
.push_back(L
'I');
5422 result
.push_back(L
'%');
5423 result
.push_back(L
'm');
5426 result
.push_back(L
'%');
5427 result
.push_back(L
'H');
5430 result
.push_back(L
'%');
5431 result
.push_back(L
'd');
5434 result
.push_back(L
'%');
5435 result
.push_back(L
'M');
5438 result
.push_back(L
'%');
5439 result
.push_back(L
'S');
5442 result
.push_back(L
'%');
5443 result
.push_back(L
'y');
5446 result
.push_back(L
'%');
5447 result
.push_back(L
'j');
5450 result
.push_back(L
'%');
5451 result
.push_back(L
'Y');
5454 for (; w
!= wbb
; ++w
)
5455 result
.push_back(*w
);
5460 if (ct
.narrow(*wbb
, 0) == '%')
5462 result
.push_back(L
'%');
5463 result
.push_back(L
'%');
5467 result
.push_back(*wbb
);
5472 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5476 __time_get_storage
<char>::init(const ctype
<char>& ct
)
5481 for (int i
= 0; i
< 7; ++i
)
5484 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5486 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5487 __weeks_
[i
+7] = buf
;
5490 for (int i
= 0; i
< 12; ++i
)
5493 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5495 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5496 __months_
[i
+12] = buf
;
5500 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5503 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5505 __c_
= __analyze('c', ct
);
5506 __r_
= __analyze('r', ct
);
5507 __x_
= __analyze('x', ct
);
5508 __X_
= __analyze('X', ct
);
5511 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5514 __time_get_storage
<wchar_t>::init(const ctype
<wchar_t>& ct
)
5522 for (int i
= 0; i
< 7; ++i
)
5525 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5527 const char* bb
= buf
;
5528 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5529 if (j
== size_t(-1) || j
== 0)
5530 __throw_runtime_error("locale not supported");
5532 __weeks_
[i
].assign(wbuf
, wbe
);
5533 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5536 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5537 if (j
== size_t(-1) || j
== 0)
5538 __throw_runtime_error("locale not supported");
5540 __weeks_
[i
+7].assign(wbuf
, wbe
);
5543 for (int i
= 0; i
< 12; ++i
)
5546 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5548 const char* bb
= buf
;
5549 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5550 if (j
== size_t(-1) || j
== 0)
5551 __throw_runtime_error("locale not supported");
5553 __months_
[i
].assign(wbuf
, wbe
);
5554 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5557 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5558 if (j
== size_t(-1) || j
== 0)
5559 __throw_runtime_error("locale not supported");
5561 __months_
[i
+12].assign(wbuf
, wbe
);
5565 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5567 const char* bb
= buf
;
5568 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5569 if (j
== size_t(-1))
5570 __throw_runtime_error("locale not supported");
5572 __am_pm_
[0].assign(wbuf
, wbe
);
5574 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5577 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5578 if (j
== size_t(-1))
5579 __throw_runtime_error("locale not supported");
5581 __am_pm_
[1].assign(wbuf
, wbe
);
5582 __c_
= __analyze('c', ct
);
5583 __r_
= __analyze('r', ct
);
5584 __x_
= __analyze('x', ct
);
5585 __X_
= __analyze('X', ct
);
5587 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5589 template <class CharT
>
5590 struct _LIBCPP_HIDDEN __time_get_temp
5591 : public ctype_byname
<CharT
>
5593 explicit __time_get_temp(const char* nm
)
5594 : ctype_byname
<CharT
>(nm
, 1) {}
5595 explicit __time_get_temp(const string
& nm
)
5596 : ctype_byname
<CharT
>(nm
, 1) {}
5600 __time_get_storage
<char>::__time_get_storage(const char* __nm
)
5603 const __time_get_temp
<char> ct(__nm
);
5608 __time_get_storage
<char>::__time_get_storage(const string
& __nm
)
5611 const __time_get_temp
<char> ct(__nm
);
5615 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5617 __time_get_storage
<wchar_t>::__time_get_storage(const char* __nm
)
5620 const __time_get_temp
<wchar_t> ct(__nm
);
5625 __time_get_storage
<wchar_t>::__time_get_storage(const string
& __nm
)
5628 const __time_get_temp
<wchar_t> ct(__nm
);
5631 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5634 time_base::dateorder
5635 __time_get_storage
<char>::__do_date_order() const
5638 for (i
= 0; i
< __x_
.size(); ++i
)
5646 for (++i
; i
< __x_
.size(); ++i
)
5649 if (i
== __x_
.size())
5655 for (++i
; i
< __x_
.size(); ++i
)
5658 if (i
== __x_
.size())
5662 return time_base::ymd
;
5665 for (++i
; i
< __x_
.size(); ++i
)
5668 if (i
== __x_
.size())
5672 return time_base::ydm
;
5677 for (++i
; i
< __x_
.size(); ++i
)
5680 if (i
== __x_
.size())
5685 for (++i
; i
< __x_
.size(); ++i
)
5688 if (i
== __x_
.size())
5691 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5692 return time_base::mdy
;
5697 for (++i
; i
< __x_
.size(); ++i
)
5700 if (i
== __x_
.size())
5705 for (++i
; i
< __x_
.size(); ++i
)
5708 if (i
== __x_
.size())
5711 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5712 return time_base::dmy
;
5717 return time_base::no_order
;
5720 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5722 time_base::dateorder
5723 __time_get_storage
<wchar_t>::__do_date_order() const
5726 for (i
= 0; i
< __x_
.size(); ++i
)
5727 if (__x_
[i
] == L
'%')
5734 for (++i
; i
< __x_
.size(); ++i
)
5735 if (__x_
[i
] == L
'%')
5737 if (i
== __x_
.size())
5743 for (++i
; i
< __x_
.size(); ++i
)
5744 if (__x_
[i
] == L
'%')
5746 if (i
== __x_
.size())
5749 if (__x_
[i
] == L
'd')
5750 return time_base::ymd
;
5753 for (++i
; i
< __x_
.size(); ++i
)
5754 if (__x_
[i
] == L
'%')
5756 if (i
== __x_
.size())
5759 if (__x_
[i
] == L
'm')
5760 return time_base::ydm
;
5765 for (++i
; i
< __x_
.size(); ++i
)
5766 if (__x_
[i
] == L
'%')
5768 if (i
== __x_
.size())
5771 if (__x_
[i
] == L
'd')
5773 for (++i
; i
< __x_
.size(); ++i
)
5774 if (__x_
[i
] == L
'%')
5776 if (i
== __x_
.size())
5779 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5780 return time_base::mdy
;
5785 for (++i
; i
< __x_
.size(); ++i
)
5786 if (__x_
[i
] == L
'%')
5788 if (i
== __x_
.size())
5791 if (__x_
[i
] == L
'm')
5793 for (++i
; i
< __x_
.size(); ++i
)
5794 if (__x_
[i
] == L
'%')
5796 if (i
== __x_
.size())
5799 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5800 return time_base::dmy
;
5805 return time_base::no_order
;
5807 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5811 __time_put::__time_put(const char* nm
)
5812 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5815 __throw_runtime_error(("time_put_byname failed to construct for " + string(nm
)).c_str());
5818 __time_put::__time_put(const string
& nm
)
5819 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5822 __throw_runtime_error(("time_put_byname failed to construct for " + nm
).c_str());
5825 __time_put::~__time_put()
5827 if (__loc_
!= _LIBCPP_GET_C_LOCALE
)
5832 __time_put::__do_put(char* __nb
, char*& __ne
, const tm
* __tm
,
5833 char __fmt
, char __mod
) const
5835 char fmt
[] = {'%', __fmt
, __mod
, 0};
5837 swap(fmt
[1], fmt
[2]);
5838 size_t n
= strftime_l(__nb
, countof(__nb
, __ne
), fmt
, __tm
, __loc_
);
5842 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5844 __time_put::__do_put(wchar_t* __wb
, wchar_t*& __we
, const tm
* __tm
,
5845 char __fmt
, char __mod
) const
5848 char* __ne
= __nar
+ 100;
5849 __do_put(__nar
, __ne
, __tm
, __fmt
, __mod
);
5851 const char* __nb
= __nar
;
5852 size_t j
= __libcpp_mbsrtowcs_l(__wb
, &__nb
, countof(__wb
, __we
), &mb
, __loc_
);
5853 if (j
== size_t(-1))
5854 __throw_runtime_error("locale not supported");
5857 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5859 // moneypunct_byname
5861 template <class charT
>
5864 __init_pat(money_base::pattern
& pat
, basic_string
<charT
>& __curr_symbol_
,
5865 bool intl
, char cs_precedes
, char sep_by_space
, char sign_posn
,
5868 const char sign
= static_cast<char>(money_base::sign
);
5869 const char space
= static_cast<char>(money_base::space
);
5870 const char none
= static_cast<char>(money_base::none
);
5871 const char symbol
= static_cast<char>(money_base::symbol
);
5872 const char value
= static_cast<char>(money_base::value
);
5873 const bool symbol_contains_sep
= intl
&& __curr_symbol_
.size() == 4;
5875 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5876 // function'. "Space between sign and symbol or value" means that
5877 // if the sign is adjacent to the symbol, there's a space between
5878 // them, and otherwise there's a space between the sign and value.
5880 // C11's localeconv specifies that the fourth character of an
5881 // international curr_symbol is used to separate the sign and
5882 // value when sep_by_space says to do so. C++ can't represent
5883 // that, so we just use a space. When sep_by_space says to
5884 // separate the symbol and value-or-sign with a space, we rearrange the
5885 // curr_symbol to put its spacing character on the correct side of
5888 // We also need to avoid adding an extra space between the sign
5889 // and value when the currency symbol is suppressed (by not
5890 // setting showbase). We match glibc's strfmon by interpreting
5891 // sep_by_space==1 as "omit the space when the currency symbol is
5894 // Users who want to get this right should use ICU instead.
5896 switch (cs_precedes
)
5898 case 0: // value before curr_symbol
5899 if (symbol_contains_sep
) {
5900 // Move the separator to before the symbol, to place it
5901 // between the value and symbol.
5902 rotate(__curr_symbol_
.begin(), __curr_symbol_
.begin() + 3,
5903 __curr_symbol_
.end());
5907 case 0: // Parentheses surround the quantity and currency symbol.
5908 pat
.field
[0] = sign
;
5909 pat
.field
[1] = value
;
5910 pat
.field
[2] = none
; // Any space appears in the symbol.
5911 pat
.field
[3] = symbol
;
5912 switch (sep_by_space
)
5914 case 0: // No space separates the currency symbol and value.
5915 // This case may have changed between C99 and C11;
5916 // assume the currency symbol matches the intention.
5917 case 2: // Space between sign and currency or value.
5918 // The "sign" is two parentheses, so no space here either.
5920 case 1: // Space between currency-and-sign or currency and value.
5921 if (!symbol_contains_sep
) {
5922 // We insert the space into the symbol instead of
5923 // setting pat.field[2]=space so that when
5924 // showbase is not set, the space goes away too.
5925 __curr_symbol_
.insert(0, 1, space_char
);
5932 case 1: // The sign string precedes the quantity and currency symbol.
5933 pat
.field
[0] = sign
;
5934 pat
.field
[3] = symbol
;
5935 switch (sep_by_space
)
5937 case 0: // No space separates the currency symbol and value.
5938 pat
.field
[1] = value
;
5939 pat
.field
[2] = none
;
5941 case 1: // Space between currency-and-sign or currency and value.
5942 pat
.field
[1] = value
;
5943 pat
.field
[2] = none
;
5944 if (!symbol_contains_sep
) {
5945 // We insert the space into the symbol instead of
5946 // setting pat.field[2]=space so that when
5947 // showbase is not set, the space goes away too.
5948 __curr_symbol_
.insert(0, 1, space_char
);
5951 case 2: // Space between sign and currency or value.
5952 pat
.field
[1] = space
;
5953 pat
.field
[2] = value
;
5954 if (symbol_contains_sep
) {
5955 // Remove the separator from the symbol, since it
5956 // has already appeared after the sign.
5957 __curr_symbol_
.erase(__curr_symbol_
.begin());
5964 case 2: // The sign string succeeds the quantity and currency symbol.
5965 pat
.field
[0] = value
;
5966 pat
.field
[3] = sign
;
5967 switch (sep_by_space
)
5969 case 0: // No space separates the currency symbol and value.
5970 pat
.field
[1] = none
;
5971 pat
.field
[2] = symbol
;
5973 case 1: // Space between currency-and-sign or currency and value.
5974 if (!symbol_contains_sep
) {
5975 // We insert the space into the symbol instead of
5976 // setting pat.field[1]=space so that when
5977 // showbase is not set, the space goes away too.
5978 __curr_symbol_
.insert(0, 1, space_char
);
5980 pat
.field
[1] = none
;
5981 pat
.field
[2] = symbol
;
5983 case 2: // Space between sign and currency or value.
5984 pat
.field
[1] = symbol
;
5985 pat
.field
[2] = space
;
5986 if (symbol_contains_sep
) {
5987 // Remove the separator from the symbol, since it
5988 // should not be removed if showbase is absent.
5989 __curr_symbol_
.erase(__curr_symbol_
.begin());
5996 case 3: // The sign string immediately precedes the currency symbol.
5997 pat
.field
[0] = value
;
5998 pat
.field
[3] = symbol
;
5999 switch (sep_by_space
)
6001 case 0: // No space separates the currency symbol and value.
6002 pat
.field
[1] = none
;
6003 pat
.field
[2] = sign
;
6005 case 1: // Space between currency-and-sign or currency and value.
6006 pat
.field
[1] = space
;
6007 pat
.field
[2] = sign
;
6008 if (symbol_contains_sep
) {
6009 // Remove the separator from the symbol, since it
6010 // has already appeared before the sign.
6011 __curr_symbol_
.erase(__curr_symbol_
.begin());
6014 case 2: // Space between sign and currency or value.
6015 pat
.field
[1] = sign
;
6016 pat
.field
[2] = none
;
6017 if (!symbol_contains_sep
) {
6018 // We insert the space into the symbol instead of
6019 // setting pat.field[2]=space so that when
6020 // showbase is not set, the space goes away too.
6021 __curr_symbol_
.insert(0, 1, space_char
);
6028 case 4: // The sign string immediately succeeds the currency symbol.
6029 pat
.field
[0] = value
;
6030 pat
.field
[3] = sign
;
6031 switch (sep_by_space
)
6033 case 0: // No space separates the currency symbol and value.
6034 pat
.field
[1] = none
;
6035 pat
.field
[2] = symbol
;
6037 case 1: // Space between currency-and-sign or currency and value.
6038 pat
.field
[1] = none
;
6039 pat
.field
[2] = symbol
;
6040 if (!symbol_contains_sep
) {
6041 // We insert the space into the symbol instead of
6042 // setting pat.field[1]=space so that when
6043 // showbase is not set, the space goes away too.
6044 __curr_symbol_
.insert(0, 1, space_char
);
6047 case 2: // Space between sign and currency or value.
6048 pat
.field
[1] = symbol
;
6049 pat
.field
[2] = space
;
6050 if (symbol_contains_sep
) {
6051 // Remove the separator from the symbol, since it
6052 // should not disappear when showbase is absent.
6053 __curr_symbol_
.erase(__curr_symbol_
.begin());
6064 case 1: // curr_symbol before value
6067 case 0: // Parentheses surround the quantity and currency symbol.
6068 pat
.field
[0] = sign
;
6069 pat
.field
[1] = symbol
;
6070 pat
.field
[2] = none
; // Any space appears in the symbol.
6071 pat
.field
[3] = value
;
6072 switch (sep_by_space
)
6074 case 0: // No space separates the currency symbol and value.
6075 // This case may have changed between C99 and C11;
6076 // assume the currency symbol matches the intention.
6077 case 2: // Space between sign and currency or value.
6078 // The "sign" is two parentheses, so no space here either.
6080 case 1: // Space between currency-and-sign or currency and value.
6081 if (!symbol_contains_sep
) {
6082 // We insert the space into the symbol instead of
6083 // setting pat.field[2]=space so that when
6084 // showbase is not set, the space goes away too.
6085 __curr_symbol_
.insert(0, 1, space_char
);
6092 case 1: // The sign string precedes the quantity and currency symbol.
6093 pat
.field
[0] = sign
;
6094 pat
.field
[3] = value
;
6095 switch (sep_by_space
)
6097 case 0: // No space separates the currency symbol and value.
6098 pat
.field
[1] = symbol
;
6099 pat
.field
[2] = none
;
6101 case 1: // Space between currency-and-sign or currency and value.
6102 pat
.field
[1] = symbol
;
6103 pat
.field
[2] = none
;
6104 if (!symbol_contains_sep
) {
6105 // We insert the space into the symbol instead of
6106 // setting pat.field[2]=space so that when
6107 // showbase is not set, the space goes away too.
6108 __curr_symbol_
.push_back(space_char
);
6111 case 2: // Space between sign and currency or value.
6112 pat
.field
[1] = space
;
6113 pat
.field
[2] = symbol
;
6114 if (symbol_contains_sep
) {
6115 // Remove the separator from the symbol, since it
6116 // has already appeared after the sign.
6117 __curr_symbol_
.pop_back();
6124 case 2: // The sign string succeeds the quantity and currency symbol.
6125 pat
.field
[0] = symbol
;
6126 pat
.field
[3] = sign
;
6127 switch (sep_by_space
)
6129 case 0: // No space separates the currency symbol and value.
6130 pat
.field
[1] = none
;
6131 pat
.field
[2] = value
;
6133 case 1: // Space between currency-and-sign or currency and value.
6134 pat
.field
[1] = none
;
6135 pat
.field
[2] = value
;
6136 if (!symbol_contains_sep
) {
6137 // We insert the space into the symbol instead of
6138 // setting pat.field[1]=space so that when
6139 // showbase is not set, the space goes away too.
6140 __curr_symbol_
.push_back(space_char
);
6143 case 2: // Space between sign and currency or value.
6144 pat
.field
[1] = value
;
6145 pat
.field
[2] = space
;
6146 if (symbol_contains_sep
) {
6147 // Remove the separator from the symbol, since it
6148 // will appear before the sign.
6149 __curr_symbol_
.pop_back();
6156 case 3: // The sign string immediately precedes the currency symbol.
6157 pat
.field
[0] = sign
;
6158 pat
.field
[3] = value
;
6159 switch (sep_by_space
)
6161 case 0: // No space separates the currency symbol and value.
6162 pat
.field
[1] = symbol
;
6163 pat
.field
[2] = none
;
6165 case 1: // Space between currency-and-sign or currency and value.
6166 pat
.field
[1] = symbol
;
6167 pat
.field
[2] = none
;
6168 if (!symbol_contains_sep
) {
6169 // We insert the space into the symbol instead of
6170 // setting pat.field[2]=space so that when
6171 // showbase is not set, the space goes away too.
6172 __curr_symbol_
.push_back(space_char
);
6175 case 2: // Space between sign and currency or value.
6176 pat
.field
[1] = space
;
6177 pat
.field
[2] = symbol
;
6178 if (symbol_contains_sep
) {
6179 // Remove the separator from the symbol, since it
6180 // has already appeared after the sign.
6181 __curr_symbol_
.pop_back();
6188 case 4: // The sign string immediately succeeds the currency symbol.
6189 pat
.field
[0] = symbol
;
6190 pat
.field
[3] = value
;
6191 switch (sep_by_space
)
6193 case 0: // No space separates the currency symbol and value.
6194 pat
.field
[1] = sign
;
6195 pat
.field
[2] = none
;
6197 case 1: // Space between currency-and-sign or currency and value.
6198 pat
.field
[1] = sign
;
6199 pat
.field
[2] = space
;
6200 if (symbol_contains_sep
) {
6201 // Remove the separator from the symbol, since it
6202 // should not disappear when showbase is absent.
6203 __curr_symbol_
.pop_back();
6206 case 2: // Space between sign and currency or value.
6207 pat
.field
[1] = none
;
6208 pat
.field
[2] = sign
;
6209 if (!symbol_contains_sep
) {
6210 // We insert the space into the symbol instead of
6211 // setting pat.field[1]=space so that when
6212 // showbase is not set, the space goes away too.
6213 __curr_symbol_
.push_back(space_char
);
6227 pat
.field
[0] = symbol
;
6228 pat
.field
[1] = sign
;
6229 pat
.field
[2] = none
;
6230 pat
.field
[3] = value
;
6235 moneypunct_byname
<char, false>::init(const char* nm
)
6237 typedef moneypunct
<char, false> base
;
6238 __libcpp_unique_locale
loc(nm
);
6240 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6242 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6243 if (!checked_string_to_char_convert(__decimal_point_
,
6244 lc
->mon_decimal_point
,
6246 __decimal_point_
= base::do_decimal_point();
6247 if (!checked_string_to_char_convert(__thousands_sep_
,
6248 lc
->mon_thousands_sep
,
6250 __thousands_sep_
= base::do_thousands_sep();
6252 __grouping_
= lc
->mon_grouping
;
6253 __curr_symbol_
= lc
->currency_symbol
;
6254 if (lc
->frac_digits
!= CHAR_MAX
)
6255 __frac_digits_
= lc
->frac_digits
;
6257 __frac_digits_
= base::do_frac_digits();
6258 if (lc
->p_sign_posn
== 0)
6259 __positive_sign_
= "()";
6261 __positive_sign_
= lc
->positive_sign
;
6262 if (lc
->n_sign_posn
== 0)
6263 __negative_sign_
= "()";
6265 __negative_sign_
= lc
->negative_sign
;
6266 // Assume the positive and negative formats will want spaces in
6267 // the same places in curr_symbol since there's no way to
6268 // represent anything else.
6269 string_type __dummy_curr_symbol
= __curr_symbol_
;
6270 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6271 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6272 __init_pat(__neg_format_
, __curr_symbol_
, false,
6273 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6278 moneypunct_byname
<char, true>::init(const char* nm
)
6280 typedef moneypunct
<char, true> base
;
6281 __libcpp_unique_locale
loc(nm
);
6283 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6285 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6286 if (!checked_string_to_char_convert(__decimal_point_
,
6287 lc
->mon_decimal_point
,
6289 __decimal_point_
= base::do_decimal_point();
6290 if (!checked_string_to_char_convert(__thousands_sep_
,
6291 lc
->mon_thousands_sep
,
6293 __thousands_sep_
= base::do_thousands_sep();
6294 __grouping_
= lc
->mon_grouping
;
6295 __curr_symbol_
= lc
->int_curr_symbol
;
6296 if (lc
->int_frac_digits
!= CHAR_MAX
)
6297 __frac_digits_
= lc
->int_frac_digits
;
6299 __frac_digits_
= base::do_frac_digits();
6300 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6301 if (lc
->p_sign_posn
== 0)
6302 #else // _LIBCPP_MSVCRT
6303 if (lc
->int_p_sign_posn
== 0)
6304 #endif // !_LIBCPP_MSVCRT
6305 __positive_sign_
= "()";
6307 __positive_sign_
= lc
->positive_sign
;
6308 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6309 if(lc
->n_sign_posn
== 0)
6310 #else // _LIBCPP_MSVCRT
6311 if (lc
->int_n_sign_posn
== 0)
6312 #endif // !_LIBCPP_MSVCRT
6313 __negative_sign_
= "()";
6315 __negative_sign_
= lc
->negative_sign
;
6316 // Assume the positive and negative formats will want spaces in
6317 // the same places in curr_symbol since there's no way to
6318 // represent anything else.
6319 string_type __dummy_curr_symbol
= __curr_symbol_
;
6320 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6321 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6322 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6323 __init_pat(__neg_format_
, __curr_symbol_
, true,
6324 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6325 #else // _LIBCPP_MSVCRT
6326 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6327 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6328 lc
->int_p_sign_posn
, ' ');
6329 __init_pat(__neg_format_
, __curr_symbol_
, true,
6330 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6331 lc
->int_n_sign_posn
, ' ');
6332 #endif // !_LIBCPP_MSVCRT
6335 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6338 moneypunct_byname
<wchar_t, false>::init(const char* nm
)
6340 typedef moneypunct
<wchar_t, false> base
;
6341 __libcpp_unique_locale
loc(nm
);
6343 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6344 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6345 if (!checked_string_to_wchar_convert(__decimal_point_
,
6346 lc
->mon_decimal_point
,
6348 __decimal_point_
= base::do_decimal_point();
6349 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6350 lc
->mon_thousands_sep
,
6352 __thousands_sep_
= base::do_thousands_sep();
6353 __grouping_
= lc
->mon_grouping
;
6356 const char* bb
= lc
->currency_symbol
;
6357 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6358 if (j
== size_t(-1))
6359 __throw_runtime_error("locale not supported");
6360 wchar_t* wbe
= wbuf
+ j
;
6361 __curr_symbol_
.assign(wbuf
, wbe
);
6362 if (lc
->frac_digits
!= CHAR_MAX
)
6363 __frac_digits_
= lc
->frac_digits
;
6365 __frac_digits_
= base::do_frac_digits();
6366 if (lc
->p_sign_posn
== 0)
6367 __positive_sign_
= L
"()";
6371 bb
= lc
->positive_sign
;
6372 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6373 if (j
== size_t(-1))
6374 __throw_runtime_error("locale not supported");
6376 __positive_sign_
.assign(wbuf
, wbe
);
6378 if (lc
->n_sign_posn
== 0)
6379 __negative_sign_
= L
"()";
6383 bb
= lc
->negative_sign
;
6384 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6385 if (j
== size_t(-1))
6386 __throw_runtime_error("locale not supported");
6388 __negative_sign_
.assign(wbuf
, wbe
);
6390 // Assume the positive and negative formats will want spaces in
6391 // the same places in curr_symbol since there's no way to
6392 // represent anything else.
6393 string_type __dummy_curr_symbol
= __curr_symbol_
;
6394 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6395 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6396 __init_pat(__neg_format_
, __curr_symbol_
, false,
6397 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6402 moneypunct_byname
<wchar_t, true>::init(const char* nm
)
6404 typedef moneypunct
<wchar_t, true> base
;
6405 __libcpp_unique_locale
loc(nm
);
6407 __throw_runtime_error(("moneypunct_byname failed to construct for " + string(nm
)).c_str());
6409 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6410 if (!checked_string_to_wchar_convert(__decimal_point_
,
6411 lc
->mon_decimal_point
,
6413 __decimal_point_
= base::do_decimal_point();
6414 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6415 lc
->mon_thousands_sep
,
6417 __thousands_sep_
= base::do_thousands_sep();
6418 __grouping_
= lc
->mon_grouping
;
6421 const char* bb
= lc
->int_curr_symbol
;
6422 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6423 if (j
== size_t(-1))
6424 __throw_runtime_error("locale not supported");
6425 wchar_t* wbe
= wbuf
+ j
;
6426 __curr_symbol_
.assign(wbuf
, wbe
);
6427 if (lc
->int_frac_digits
!= CHAR_MAX
)
6428 __frac_digits_
= lc
->int_frac_digits
;
6430 __frac_digits_
= base::do_frac_digits();
6431 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6432 if (lc
->p_sign_posn
== 0)
6433 #else // _LIBCPP_MSVCRT
6434 if (lc
->int_p_sign_posn
== 0)
6435 #endif // !_LIBCPP_MSVCRT
6436 __positive_sign_
= L
"()";
6440 bb
= lc
->positive_sign
;
6441 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6442 if (j
== size_t(-1))
6443 __throw_runtime_error("locale not supported");
6445 __positive_sign_
.assign(wbuf
, wbe
);
6447 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6448 if (lc
->n_sign_posn
== 0)
6449 #else // _LIBCPP_MSVCRT
6450 if (lc
->int_n_sign_posn
== 0)
6451 #endif // !_LIBCPP_MSVCRT
6452 __negative_sign_
= L
"()";
6456 bb
= lc
->negative_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 __negative_sign_
.assign(wbuf
, wbe
);
6463 // Assume the positive and negative formats will want spaces in
6464 // the same places in curr_symbol since there's no way to
6465 // represent anything else.
6466 string_type __dummy_curr_symbol
= __curr_symbol_
;
6467 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6468 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6469 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6470 __init_pat(__neg_format_
, __curr_symbol_
, true,
6471 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6472 #else // _LIBCPP_MSVCRT
6473 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6474 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6475 lc
->int_p_sign_posn
, L
' ');
6476 __init_pat(__neg_format_
, __curr_symbol_
, true,
6477 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6478 lc
->int_n_sign_posn
, L
' ');
6479 #endif // !_LIBCPP_MSVCRT
6481 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6483 void __do_nothing(void*) {}
6485 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<char>;
6486 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<wchar_t>;)
6488 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<char>;
6489 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<wchar_t>;)
6491 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<char>;
6492 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<wchar_t>;)
6494 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<char>;
6495 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<wchar_t>;)
6497 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<char>;
6498 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<wchar_t>;)
6500 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<char>;
6501 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<wchar_t>;)
6503 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<char>;
6504 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<wchar_t>;)
6506 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<char>;
6507 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<wchar_t>;)
6509 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<char>;
6510 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<wchar_t>;)
6512 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, false>;
6513 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, true>;
6514 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, false>;)
6515 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, true>;)
6517 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, false>;
6518 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, true>;
6519 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, false>;)
6520 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, true>;)
6522 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<char>;
6523 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<wchar_t>;)
6525 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<char>;
6526 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<wchar_t>;)
6528 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<char>;
6529 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<wchar_t>;)
6531 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<char>;
6532 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<wchar_t>;)
6534 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<char>;
6535 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<wchar_t>;)
6537 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<char>;
6538 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<wchar_t>;)
6540 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char, char, mbstate_t>;
6541 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<wchar_t, char, mbstate_t>;)
6542 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char, mbstate_t>;
6543 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char, mbstate_t>;
6544 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6545 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char8_t
, mbstate_t>;
6546 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char8_t
, mbstate_t>;
6549 _LIBCPP_END_NAMESPACE_STD