1 //===------------------------- locale.cpp ---------------------------------===//
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 // On Solaris, we need to define something to make the C99 parts of localeconv
21 #ifndef _LIBCPP_NO_EXCEPTIONS
22 # include "type_traits"
26 #if defined(_LIBCPP_MSVCRT)
27 #define _CTYPE_DISABLE_MACROS
30 #include "__sso_allocator"
31 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
32 #include "support/win32/locale_win32.h"
33 #elif !defined(__BIONIC__) && !defined(__NuttX__)
38 #include "include/atomic_support.h"
39 #include "__undef_macros"
41 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
42 // lots of noise in the build log, but no bugs that I know of.
43 #if defined(__clang__)
44 #pragma clang diagnostic ignored "-Wsign-conversion"
47 _LIBCPP_BEGIN_NAMESPACE_STD
49 struct __libcpp_unique_locale
{
50 __libcpp_unique_locale(const char* nm
) : __loc_(newlocale(LC_ALL_MASK
, nm
, 0)) {}
52 ~__libcpp_unique_locale() {
57 explicit operator bool() const { return __loc_
; }
59 locale_t
& get() { return __loc_
; }
63 __libcpp_unique_locale(__libcpp_unique_locale
const&);
64 __libcpp_unique_locale
& operator=(__libcpp_unique_locale
const&);
69 // In theory this could create a race condition. In practice
70 // the race condition is non-fatal since it will just create
71 // a little resource leak. Better approach would be appreciated.
72 static locale_t result
= newlocale(LC_ALL_MASK
, "C", 0);
75 #endif // __cloc_defined
81 void operator()(locale::facet
* p
) {p
->__release_shared();}
84 template <class T
, class A0
>
89 static typename aligned_storage
<sizeof(T
)>::type buf
;
90 auto *obj
= ::new (&buf
) T(a0
);
94 template <class T
, class A0
, class A1
>
99 static typename aligned_storage
<sizeof(T
)>::type buf
;
100 ::new (&buf
) T(a0
, a1
);
101 return *reinterpret_cast<T
*>(&buf
);
104 template <class T
, class A0
, class A1
, class A2
>
107 make(A0 a0
, A1 a1
, A2 a2
)
109 static typename aligned_storage
<sizeof(T
)>::type buf
;
110 auto *obj
= ::new (&buf
) T(a0
, a1
, a2
);
114 template <typename T
, size_t N
>
118 countof(const T (&)[N
])
123 template <typename T
>
127 countof(const T
* const begin
, const T
* const end
)
129 return static_cast<size_t>(end
- begin
);
132 _LIBCPP_NORETURN
static void __throw_runtime_error(const string
&msg
)
134 #ifndef _LIBCPP_NO_EXCEPTIONS
135 throw runtime_error(msg
);
145 // Set priority to INT_MIN + 256 + 150
146 # pragma priority ( -2147483242 )
149 const locale::category
locale::none
;
150 const locale::category
locale::collate
;
151 const locale::category
locale::ctype
;
152 const locale::category
locale::monetary
;
153 const locale::category
locale::numeric
;
154 const locale::category
locale::time
;
155 const locale::category
locale::messages
;
156 const locale::category
locale::all
;
158 class _LIBCPP_HIDDEN
locale::__imp
162 #if defined(_LIBCPP_COMPILER_MSVC)
163 // FIXME: MSVC doesn't support aligned parameters by value.
164 // I can't get the __sso_allocator to work here
165 // for MSVC I think for this reason.
166 vector
<facet
*> facets_
;
168 vector
<facet
*, __sso_allocator
<facet
*, N
> > facets_
;
172 explicit __imp(size_t refs
= 0);
173 explicit __imp(const string
& name
, size_t refs
= 0);
175 __imp(const __imp
&, const string
&, locale::category c
);
176 __imp(const __imp
& other
, const __imp
& one
, locale::category c
);
177 __imp(const __imp
&, facet
* f
, long id
);
180 const string
& name() const {return name_
;}
181 bool has_facet(long id
) const
182 {return static_cast<size_t>(id
) < facets_
.size() && facets_
[static_cast<size_t>(id
)];}
183 const locale::facet
* use_facet(long id
) const;
185 static const locale
& make_classic();
186 static locale
& make_global();
188 void install(facet
* f
, long id
);
189 template <class F
> void install(F
* f
) {install(f
, f
->id
.__get());}
190 template <class F
> void install_from(const __imp
& other
);
193 locale::__imp::__imp(size_t refs
)
199 install(&make
<_VSTD::collate
<char> >(1u));
200 install(&make
<_VSTD::collate
<wchar_t> >(1u));
201 install(&make
<_VSTD::ctype
<char> >(nullptr, false, 1u));
202 install(&make
<_VSTD::ctype
<wchar_t> >(1u));
203 install(&make
<codecvt
<char, char, mbstate_t> >(1u));
204 install(&make
<codecvt
<wchar_t, char, mbstate_t> >(1u));
205 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
206 install(&make
<codecvt
<char16_t
, char, mbstate_t> >(1u));
207 install(&make
<codecvt
<char32_t
, char, mbstate_t> >(1u));
208 _LIBCPP_SUPPRESS_DEPRECATED_POP
209 #ifndef _LIBCPP_NO_HAS_CHAR8_T
210 install(&make
<codecvt
<char16_t
, char8_t
, mbstate_t> >(1u));
211 install(&make
<codecvt
<char32_t
, char8_t
, mbstate_t> >(1u));
213 install(&make
<numpunct
<char> >(1u));
214 install(&make
<numpunct
<wchar_t> >(1u));
215 install(&make
<num_get
<char> >(1u));
216 install(&make
<num_get
<wchar_t> >(1u));
217 install(&make
<num_put
<char> >(1u));
218 install(&make
<num_put
<wchar_t> >(1u));
219 install(&make
<moneypunct
<char, false> >(1u));
220 install(&make
<moneypunct
<char, true> >(1u));
221 install(&make
<moneypunct
<wchar_t, false> >(1u));
222 install(&make
<moneypunct
<wchar_t, true> >(1u));
223 install(&make
<money_get
<char> >(1u));
224 install(&make
<money_get
<wchar_t> >(1u));
225 install(&make
<money_put
<char> >(1u));
226 install(&make
<money_put
<wchar_t> >(1u));
227 install(&make
<time_get
<char> >(1u));
228 install(&make
<time_get
<wchar_t> >(1u));
229 install(&make
<time_put
<char> >(1u));
230 install(&make
<time_put
<wchar_t> >(1u));
231 install(&make
<_VSTD::messages
<char> >(1u));
232 install(&make
<_VSTD::messages
<wchar_t> >(1u));
235 locale::__imp::__imp(const string
& name
, size_t refs
)
240 #ifndef _LIBCPP_NO_EXCEPTIONS
243 #endif // _LIBCPP_NO_EXCEPTIONS
244 facets_
= locale::classic().__locale_
->facets_
;
245 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
247 facets_
[i
]->__add_shared();
248 install(new collate_byname
<char>(name_
));
249 install(new collate_byname
<wchar_t>(name_
));
250 install(new ctype_byname
<char>(name_
));
251 install(new ctype_byname
<wchar_t>(name_
));
252 install(new codecvt_byname
<char, char, mbstate_t>(name_
));
253 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name_
));
254 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
255 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name_
));
256 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name_
));
257 _LIBCPP_SUPPRESS_DEPRECATED_POP
258 #ifndef _LIBCPP_NO_HAS_CHAR8_T
259 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name_
));
260 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name_
));
262 install(new numpunct_byname
<char>(name_
));
263 install(new numpunct_byname
<wchar_t>(name_
));
264 install(new moneypunct_byname
<char, false>(name_
));
265 install(new moneypunct_byname
<char, true>(name_
));
266 install(new moneypunct_byname
<wchar_t, false>(name_
));
267 install(new moneypunct_byname
<wchar_t, true>(name_
));
268 install(new time_get_byname
<char>(name_
));
269 install(new time_get_byname
<wchar_t>(name_
));
270 install(new time_put_byname
<char>(name_
));
271 install(new time_put_byname
<wchar_t>(name_
));
272 install(new messages_byname
<char>(name_
));
273 install(new messages_byname
<wchar_t>(name_
));
274 #ifndef _LIBCPP_NO_EXCEPTIONS
278 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
280 facets_
[i
]->__release_shared();
283 #endif // _LIBCPP_NO_EXCEPTIONS
286 // NOTE avoid the `base class should be explicitly initialized in the
287 // copy constructor` warning emitted by GCC
288 #if defined(__clang__) || _GNUC_VER >= 406
289 #pragma GCC diagnostic push
290 #pragma GCC diagnostic ignored "-Wextra"
293 locale::__imp::__imp(const __imp
& other
)
294 : facets_(max
<size_t>(N
, other
.facets_
.size())),
297 facets_
= other
.facets_
;
298 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
300 facets_
[i
]->__add_shared();
303 #if defined(__clang__) || _GNUC_VER >= 406
304 #pragma GCC diagnostic pop
307 locale::__imp::__imp(const __imp
& other
, const string
& name
, locale::category c
)
311 facets_
= other
.facets_
;
312 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
314 facets_
[i
]->__add_shared();
315 #ifndef _LIBCPP_NO_EXCEPTIONS
318 #endif // _LIBCPP_NO_EXCEPTIONS
319 if (c
& locale::collate
)
321 install(new collate_byname
<char>(name
));
322 install(new collate_byname
<wchar_t>(name
));
324 if (c
& locale::ctype
)
326 install(new ctype_byname
<char>(name
));
327 install(new ctype_byname
<wchar_t>(name
));
328 install(new codecvt_byname
<char, char, mbstate_t>(name
));
329 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name
));
330 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
331 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name
));
332 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name
));
333 _LIBCPP_SUPPRESS_DEPRECATED_POP
334 #ifndef _LIBCPP_NO_HAS_CHAR8_T
335 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name
));
336 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name
));
339 if (c
& locale::monetary
)
341 install(new moneypunct_byname
<char, false>(name
));
342 install(new moneypunct_byname
<char, true>(name
));
343 install(new moneypunct_byname
<wchar_t, false>(name
));
344 install(new moneypunct_byname
<wchar_t, true>(name
));
346 if (c
& locale::numeric
)
348 install(new numpunct_byname
<char>(name
));
349 install(new numpunct_byname
<wchar_t>(name
));
351 if (c
& locale::time
)
353 install(new time_get_byname
<char>(name
));
354 install(new time_get_byname
<wchar_t>(name
));
355 install(new time_put_byname
<char>(name
));
356 install(new time_put_byname
<wchar_t>(name
));
358 if (c
& locale::messages
)
360 install(new messages_byname
<char>(name
));
361 install(new messages_byname
<wchar_t>(name
));
363 #ifndef _LIBCPP_NO_EXCEPTIONS
367 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
369 facets_
[i
]->__release_shared();
372 #endif // _LIBCPP_NO_EXCEPTIONS
378 locale::__imp::install_from(const locale::__imp
& one
)
380 long id
= F::id
.__get();
381 install(const_cast<F
*>(static_cast<const F
*>(one
.use_facet(id
))), id
);
384 locale::__imp::__imp(const __imp
& other
, const __imp
& one
, locale::category c
)
388 facets_
= other
.facets_
;
389 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
391 facets_
[i
]->__add_shared();
392 #ifndef _LIBCPP_NO_EXCEPTIONS
395 #endif // _LIBCPP_NO_EXCEPTIONS
396 if (c
& locale::collate
)
398 install_from
<_VSTD::collate
<char> >(one
);
399 install_from
<_VSTD::collate
<wchar_t> >(one
);
401 if (c
& locale::ctype
)
403 install_from
<_VSTD::ctype
<char> >(one
);
404 install_from
<_VSTD::ctype
<wchar_t> >(one
);
405 install_from
<_VSTD::codecvt
<char, char, mbstate_t> >(one
);
406 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
407 install_from
<_VSTD::codecvt
<char16_t
, char, mbstate_t> >(one
);
408 install_from
<_VSTD::codecvt
<char32_t
, char, mbstate_t> >(one
);
409 _LIBCPP_SUPPRESS_DEPRECATED_POP
410 #ifndef _LIBCPP_NO_HAS_CHAR8_T
411 install_from
<_VSTD::codecvt
<char16_t
, char8_t
, mbstate_t> >(one
);
412 install_from
<_VSTD::codecvt
<char32_t
, char8_t
, mbstate_t> >(one
);
414 install_from
<_VSTD::codecvt
<wchar_t, char, mbstate_t> >(one
);
416 if (c
& locale::monetary
)
418 install_from
<moneypunct
<char, false> >(one
);
419 install_from
<moneypunct
<char, true> >(one
);
420 install_from
<moneypunct
<wchar_t, false> >(one
);
421 install_from
<moneypunct
<wchar_t, true> >(one
);
422 install_from
<money_get
<char> >(one
);
423 install_from
<money_get
<wchar_t> >(one
);
424 install_from
<money_put
<char> >(one
);
425 install_from
<money_put
<wchar_t> >(one
);
427 if (c
& locale::numeric
)
429 install_from
<numpunct
<char> >(one
);
430 install_from
<numpunct
<wchar_t> >(one
);
431 install_from
<num_get
<char> >(one
);
432 install_from
<num_get
<wchar_t> >(one
);
433 install_from
<num_put
<char> >(one
);
434 install_from
<num_put
<wchar_t> >(one
);
436 if (c
& locale::time
)
438 install_from
<time_get
<char> >(one
);
439 install_from
<time_get
<wchar_t> >(one
);
440 install_from
<time_put
<char> >(one
);
441 install_from
<time_put
<wchar_t> >(one
);
443 if (c
& locale::messages
)
445 install_from
<_VSTD::messages
<char> >(one
);
446 install_from
<_VSTD::messages
<wchar_t> >(one
);
448 #ifndef _LIBCPP_NO_EXCEPTIONS
452 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
454 facets_
[i
]->__release_shared();
457 #endif // _LIBCPP_NO_EXCEPTIONS
460 locale::__imp::__imp(const __imp
& other
, facet
* f
, long id
)
461 : facets_(max
<size_t>(N
, other
.facets_
.size()+1)),
465 unique_ptr
<facet
, release
> hold(f
);
466 facets_
= other
.facets_
;
467 for (unsigned i
= 0; i
< other
.facets_
.size(); ++i
)
469 facets_
[i
]->__add_shared();
470 install(hold
.get(), id
);
473 locale::__imp::~__imp()
475 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
477 facets_
[i
]->__release_shared();
481 locale::__imp::install(facet
* f
, long id
)
484 unique_ptr
<facet
, release
> hold(f
);
485 if (static_cast<size_t>(id
) >= facets_
.size())
486 facets_
.resize(static_cast<size_t>(id
+1));
487 if (facets_
[static_cast<size_t>(id
)])
488 facets_
[static_cast<size_t>(id
)]->__release_shared();
489 facets_
[static_cast<size_t>(id
)] = hold
.release();
493 locale::__imp::use_facet(long id
) const
497 return facets_
[static_cast<size_t>(id
)];
503 locale::__imp::make_classic()
505 // only one thread can get in here and it only gets in once
506 static aligned_storage
<sizeof(locale
)>::type buf
;
507 locale
* c
= reinterpret_cast<locale
*>(&buf
);
508 c
->__locale_
= &make
<__imp
>(1u);
515 static const locale
& c
= __imp::make_classic();
520 locale::__imp::make_global()
522 // only one thread can get in here and it only gets in once
523 static aligned_storage
<sizeof(locale
)>::type buf
;
524 auto *obj
= ::new (&buf
) locale(locale::classic());
531 static locale
& g
= __imp::make_global();
535 locale::locale() _NOEXCEPT
536 : __locale_(__global().__locale_
)
538 __locale_
->__add_shared();
541 locale::locale(const locale
& l
) _NOEXCEPT
542 : __locale_(l
.__locale_
)
544 __locale_
->__add_shared();
549 __locale_
->__release_shared();
553 locale::operator=(const locale
& other
) _NOEXCEPT
555 other
.__locale_
->__add_shared();
556 __locale_
->__release_shared();
557 __locale_
= other
.__locale_
;
561 locale::locale(const char* name
)
562 : __locale_(name
? new __imp(name
)
563 : (__throw_runtime_error("locale constructed with null"), nullptr))
565 __locale_
->__add_shared();
568 locale::locale(const string
& name
)
569 : __locale_(new __imp(name
))
571 __locale_
->__add_shared();
574 locale::locale(const locale
& other
, const char* name
, category c
)
575 : __locale_(name
? new __imp(*other
.__locale_
, name
, c
)
576 : (__throw_runtime_error("locale constructed with null"), nullptr))
578 __locale_
->__add_shared();
581 locale::locale(const locale
& other
, const string
& name
, category c
)
582 : __locale_(new __imp(*other
.__locale_
, name
, c
))
584 __locale_
->__add_shared();
587 locale::locale(const locale
& other
, const locale
& one
, category c
)
588 : __locale_(new __imp(*other
.__locale_
, *one
.__locale_
, c
))
590 __locale_
->__add_shared();
596 return __locale_
->name();
600 locale::__install_ctor(const locale
& other
, facet
* f
, long id
)
603 __locale_
= new __imp(*other
.__locale_
, f
, id
);
605 __locale_
= other
.__locale_
;
606 __locale_
->__add_shared();
610 locale::global(const locale
& loc
)
612 locale
& g
= __global();
616 setlocale(LC_ALL
, g
.name().c_str());
621 locale::has_facet(id
& x
) const
623 return __locale_
->has_facet(x
.__get());
627 locale::use_facet(id
& x
) const
629 return __locale_
->use_facet(x
.__get());
633 locale::operator==(const locale
& y
) const
635 return (__locale_
== y
.__locale_
)
636 || (__locale_
->name() != "*" && __locale_
->name() == y
.__locale_
->name());
641 locale::facet::~facet()
646 locale::facet::__on_zero_shared() _NOEXCEPT
653 int32_t locale::id::__next_id
= 0;
661 void (locale::id::* pmf_
)();
663 __fake_bind(void (locale::id::* pmf
)(), locale::id
* id
)
664 : id_(id
), pmf_(pmf
) {}
666 void operator()() const
677 call_once(__flag_
, __fake_bind(&locale::id::__init
, this));
684 __id_
= __libcpp_atomic_add(&__next_id
, 1);
687 // template <> class collate_byname<char>
689 collate_byname
<char>::collate_byname(const char* n
, size_t refs
)
690 : collate
<char>(refs
),
691 __l(newlocale(LC_ALL_MASK
, n
, 0))
694 __throw_runtime_error("collate_byname<char>::collate_byname"
695 " failed to construct for " + string(n
));
698 collate_byname
<char>::collate_byname(const string
& name
, size_t refs
)
699 : collate
<char>(refs
),
700 __l(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
703 __throw_runtime_error("collate_byname<char>::collate_byname"
704 " failed to construct for " + name
);
707 collate_byname
<char>::~collate_byname()
713 collate_byname
<char>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
714 const char_type
* __lo2
, const char_type
* __hi2
) const
716 string_type
lhs(__lo1
, __hi1
);
717 string_type
rhs(__lo2
, __hi2
);
718 int r
= strcoll_l(lhs
.c_str(), rhs
.c_str(), __l
);
726 collate_byname
<char>::string_type
727 collate_byname
<char>::do_transform(const char_type
* lo
, const char_type
* hi
) const
729 const string_type
in(lo
, hi
);
730 string_type
out(strxfrm_l(0, in
.c_str(), 0, __l
), char());
731 strxfrm_l(const_cast<char*>(out
.c_str()), in
.c_str(), out
.size()+1, __l
);
735 // template <> class collate_byname<wchar_t>
737 collate_byname
<wchar_t>::collate_byname(const char* n
, size_t refs
)
738 : collate
<wchar_t>(refs
),
739 __l(newlocale(LC_ALL_MASK
, n
, 0))
742 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
743 " failed to construct for " + string(n
));
746 collate_byname
<wchar_t>::collate_byname(const string
& name
, size_t refs
)
747 : collate
<wchar_t>(refs
),
748 __l(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
751 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
752 " failed to construct for " + name
);
755 collate_byname
<wchar_t>::~collate_byname()
761 collate_byname
<wchar_t>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
762 const char_type
* __lo2
, const char_type
* __hi2
) const
764 string_type
lhs(__lo1
, __hi1
);
765 string_type
rhs(__lo2
, __hi2
);
766 int r
= wcscoll_l(lhs
.c_str(), rhs
.c_str(), __l
);
774 collate_byname
<wchar_t>::string_type
775 collate_byname
<wchar_t>::do_transform(const char_type
* lo
, const char_type
* hi
) const
777 const string_type
in(lo
, hi
);
778 string_type
out(wcsxfrm_l(0, in
.c_str(), 0, __l
), wchar_t());
779 wcsxfrm_l(const_cast<wchar_t*>(out
.c_str()), in
.c_str(), out
.size()+1, __l
);
783 // template <> class ctype<wchar_t>;
785 const ctype_base::mask
ctype_base::space
;
786 const ctype_base::mask
ctype_base::print
;
787 const ctype_base::mask
ctype_base::cntrl
;
788 const ctype_base::mask
ctype_base::upper
;
789 const ctype_base::mask
ctype_base::lower
;
790 const ctype_base::mask
ctype_base::alpha
;
791 const ctype_base::mask
ctype_base::digit
;
792 const ctype_base::mask
ctype_base::punct
;
793 const ctype_base::mask
ctype_base::xdigit
;
794 const ctype_base::mask
ctype_base::blank
;
795 const ctype_base::mask
ctype_base::alnum
;
796 const ctype_base::mask
ctype_base::graph
;
798 locale::id ctype
<wchar_t>::id
;
800 ctype
<wchar_t>::~ctype()
805 ctype
<wchar_t>::do_is(mask m
, char_type c
) const
807 return isascii(c
) ? (ctype
<char>::classic_table()[c
] & m
) != 0 : false;
811 ctype
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
813 for (; low
!= high
; ++low
, ++vec
)
814 *vec
= static_cast<mask
>(isascii(*low
) ?
815 ctype
<char>::classic_table()[*low
] : 0);
820 ctype
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
822 for (; low
!= high
; ++low
)
823 if (isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
))
829 ctype
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
831 for (; low
!= high
; ++low
)
832 if (!(isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
)))
838 ctype
<wchar_t>::do_toupper(char_type c
) const
840 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
841 return isascii(c
) ? _DefaultRuneLocale
.__mapupper
[c
] : c
;
842 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
844 return isascii(c
) ? ctype
<char>::__classic_upper_table()[c
] : c
;
846 return (isascii(c
) && iswlower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'a'+L
'A' : c
;
851 ctype
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
853 for (; low
!= high
; ++low
)
854 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
855 *low
= isascii(*low
) ? _DefaultRuneLocale
.__mapupper
[*low
] : *low
;
856 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
858 *low
= isascii(*low
) ? ctype
<char>::__classic_upper_table()[*low
]
861 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? (*low
-L
'a'+L
'A') : *low
;
867 ctype
<wchar_t>::do_tolower(char_type c
) const
869 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
870 return isascii(c
) ? _DefaultRuneLocale
.__maplower
[c
] : c
;
871 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
873 return isascii(c
) ? ctype
<char>::__classic_lower_table()[c
] : c
;
875 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'A'+'a' : c
;
880 ctype
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
882 for (; low
!= high
; ++low
)
883 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
884 *low
= isascii(*low
) ? _DefaultRuneLocale
.__maplower
[*low
] : *low
;
885 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
887 *low
= isascii(*low
) ? ctype
<char>::__classic_lower_table()[*low
]
890 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-L
'A'+L
'a' : *low
;
896 ctype
<wchar_t>::do_widen(char c
) const
902 ctype
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
904 for (; low
!= high
; ++low
, ++dest
)
910 ctype
<wchar_t>::do_narrow(char_type c
, char dfault
) const
913 return static_cast<char>(c
);
918 ctype
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
920 for (; low
!= high
; ++low
, ++dest
)
922 *dest
= static_cast<char>(*low
);
928 // template <> class ctype<char>;
930 locale::id ctype
<char>::id
;
932 ctype
<char>::ctype(const mask
* tab
, bool del
, size_t refs
)
933 : locale::facet(refs
),
938 __tab_
= classic_table();
941 ctype
<char>::~ctype()
943 if (__tab_
&& __del_
)
948 ctype
<char>::do_toupper(char_type c
) const
950 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
952 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(c
)]) : c
;
953 #elif defined(__NetBSD__)
954 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]);
955 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
957 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]) : c
;
959 return (isascii(c
) && islower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'a'+'A' : c
;
964 ctype
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
966 for (; low
!= high
; ++low
)
967 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
968 *low
= isascii(*low
) ?
969 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(*low
)]) : *low
;
970 #elif defined(__NetBSD__)
971 *low
= static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low
)]);
972 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
973 *low
= isascii(*low
) ?
974 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low
)]) : *low
;
976 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'a'+'A' : *low
;
982 ctype
<char>::do_tolower(char_type c
) const
984 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
986 static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(c
)]) : c
;
987 #elif defined(__NetBSD__)
988 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c
)]);
989 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
991 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c
)]) : c
;
993 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'A'+'a' : c
;
998 ctype
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1000 for (; low
!= high
; ++low
)
1001 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1002 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(*low
)]) : *low
;
1003 #elif defined(__NetBSD__)
1004 *low
= static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low
)]);
1005 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
1006 *low
= isascii(*low
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low
)]) : *low
;
1008 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'A'+'a' : *low
;
1014 ctype
<char>::do_widen(char c
) const
1020 ctype
<char>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1022 for (; low
!= high
; ++low
, ++dest
)
1028 ctype
<char>::do_narrow(char_type c
, char dfault
) const
1031 return static_cast<char>(c
);
1036 ctype
<char>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1038 for (; low
!= high
; ++low
, ++dest
)
1046 #if defined(__EMSCRIPTEN__)
1047 extern "C" const unsigned short ** __ctype_b_loc();
1048 extern "C" const int ** __ctype_tolower_loc();
1049 extern "C" const int ** __ctype_toupper_loc();
1052 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1053 const ctype
<char>::mask
*
1054 ctype
<char>::classic_table() _NOEXCEPT
1056 static _LIBCPP_CONSTEXPR
const ctype
<char>::mask builtin_table
[table_size
] = {
1061 cntrl
, cntrl
| space
| blank
,
1062 cntrl
| space
, cntrl
| space
,
1063 cntrl
| space
, cntrl
| space
,
1073 space
| blank
| print
, punct
| print
,
1074 punct
| print
, punct
| print
,
1075 punct
| print
, punct
| print
,
1076 punct
| print
, punct
| print
,
1077 punct
| print
, punct
| print
,
1078 punct
| print
, punct
| print
,
1079 punct
| print
, punct
| print
,
1080 punct
| print
, punct
| print
,
1081 digit
| print
| xdigit
, digit
| print
| xdigit
,
1082 digit
| print
| xdigit
, digit
| print
| xdigit
,
1083 digit
| print
| xdigit
, digit
| print
| xdigit
,
1084 digit
| print
| xdigit
, digit
| print
| xdigit
,
1085 digit
| print
| xdigit
, digit
| print
| xdigit
,
1086 punct
| print
, punct
| print
,
1087 punct
| print
, punct
| print
,
1088 punct
| print
, punct
| print
,
1089 punct
| print
, upper
| xdigit
| print
| alpha
,
1090 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1091 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1092 upper
| xdigit
| print
| alpha
, upper
| print
| alpha
,
1093 upper
| print
| alpha
, upper
| print
| alpha
,
1094 upper
| print
| alpha
, upper
| print
| alpha
,
1095 upper
| print
| alpha
, upper
| print
| alpha
,
1096 upper
| print
| alpha
, upper
| print
| alpha
,
1097 upper
| print
| alpha
, upper
| print
| alpha
,
1098 upper
| print
| alpha
, upper
| print
| alpha
,
1099 upper
| print
| alpha
, upper
| print
| alpha
,
1100 upper
| print
| alpha
, upper
| print
| alpha
,
1101 upper
| print
| alpha
, upper
| print
| alpha
,
1102 upper
| print
| alpha
, punct
| print
,
1103 punct
| print
, punct
| print
,
1104 punct
| print
, punct
| print
,
1105 punct
| print
, lower
| xdigit
| print
| alpha
,
1106 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1107 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1108 lower
| xdigit
| print
| alpha
, lower
| print
| alpha
,
1109 lower
| print
| alpha
, lower
| print
| alpha
,
1110 lower
| print
| alpha
, lower
| print
| alpha
,
1111 lower
| print
| alpha
, lower
| print
| alpha
,
1112 lower
| print
| alpha
, lower
| print
| alpha
,
1113 lower
| print
| alpha
, lower
| print
| alpha
,
1114 lower
| print
| alpha
, lower
| print
| alpha
,
1115 lower
| print
| alpha
, lower
| print
| alpha
,
1116 lower
| print
| alpha
, lower
| print
| alpha
,
1117 lower
| print
| alpha
, lower
| print
| alpha
,
1118 lower
| print
| alpha
, punct
| print
,
1119 punct
| print
, punct
| print
,
1120 punct
| print
, cntrl
,
1121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1130 return builtin_table
;
1133 const ctype
<char>::mask
*
1134 ctype
<char>::classic_table() _NOEXCEPT
1136 #if defined(__APPLE__) || defined(__FreeBSD__)
1137 return _DefaultRuneLocale
.__runetype
;
1138 #elif defined(__NetBSD__)
1139 return _C_ctype_tab_
+ 1;
1140 #elif defined(__GLIBC__)
1141 return _LIBCPP_GET_C_LOCALE
->__ctype_b
;
1143 return __ctype_mask
;
1144 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1145 return __pctype_func();
1146 #elif defined(__EMSCRIPTEN__)
1147 return *__ctype_b_loc();
1148 #elif defined(_NEWLIB_VERSION)
1149 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1152 return (const unsigned int *)__lc_ctype_ptr
->obj
->mask
;
1154 // Platform not supported: abort so the person doing the port knows what to
1156 # warning ctype<char>::classic_table() is not implemented
1157 printf("ctype<char>::classic_table() is not implemented\n");
1164 #if defined(__GLIBC__)
1166 ctype
<char>::__classic_lower_table() _NOEXCEPT
1168 return _LIBCPP_GET_C_LOCALE
->__ctype_tolower
;
1172 ctype
<char>::__classic_upper_table() _NOEXCEPT
1174 return _LIBCPP_GET_C_LOCALE
->__ctype_toupper
;
1176 #elif defined(__NetBSD__)
1178 ctype
<char>::__classic_lower_table() _NOEXCEPT
1180 return _C_tolower_tab_
+ 1;
1184 ctype
<char>::__classic_upper_table() _NOEXCEPT
1186 return _C_toupper_tab_
+ 1;
1189 #elif defined(__EMSCRIPTEN__)
1191 ctype
<char>::__classic_lower_table() _NOEXCEPT
1193 return *__ctype_tolower_loc();
1197 ctype
<char>::__classic_upper_table() _NOEXCEPT
1199 return *__ctype_toupper_loc();
1201 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
1203 // template <> class ctype_byname<char>
1205 ctype_byname
<char>::ctype_byname(const char* name
, size_t refs
)
1206 : ctype
<char>(0, false, refs
),
1207 __l(newlocale(LC_ALL_MASK
, name
, 0))
1210 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1211 " failed to construct for " + string(name
));
1214 ctype_byname
<char>::ctype_byname(const string
& name
, size_t refs
)
1215 : ctype
<char>(0, false, refs
),
1216 __l(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1219 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1220 " failed to construct for " + name
);
1223 ctype_byname
<char>::~ctype_byname()
1229 ctype_byname
<char>::do_toupper(char_type c
) const
1231 return static_cast<char>(toupper_l(static_cast<unsigned char>(c
), __l
));
1235 ctype_byname
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
1237 for (; low
!= high
; ++low
)
1238 *low
= static_cast<char>(toupper_l(static_cast<unsigned char>(*low
), __l
));
1243 ctype_byname
<char>::do_tolower(char_type c
) const
1245 return static_cast<char>(tolower_l(static_cast<unsigned char>(c
), __l
));
1249 ctype_byname
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1251 for (; low
!= high
; ++low
)
1252 *low
= static_cast<char>(tolower_l(static_cast<unsigned char>(*low
), __l
));
1256 // template <> class ctype_byname<wchar_t>
1258 ctype_byname
<wchar_t>::ctype_byname(const char* name
, size_t refs
)
1259 : ctype
<wchar_t>(refs
),
1260 __l(newlocale(LC_ALL_MASK
, name
, 0))
1263 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1264 " failed to construct for " + string(name
));
1267 ctype_byname
<wchar_t>::ctype_byname(const string
& name
, size_t refs
)
1268 : ctype
<wchar_t>(refs
),
1269 __l(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1272 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1273 " failed to construct for " + name
);
1276 ctype_byname
<wchar_t>::~ctype_byname()
1282 ctype_byname
<wchar_t>::do_is(mask m
, char_type c
) const
1284 #ifdef _LIBCPP_WCTYPE_IS_MASK
1285 return static_cast<bool>(iswctype_l(c
, m
, __l
));
1287 bool result
= false;
1288 wint_t ch
= static_cast<wint_t>(c
);
1289 if ((m
& space
) == space
) result
|= (iswspace_l(ch
, __l
) != 0);
1290 if ((m
& print
) == print
) result
|= (iswprint_l(ch
, __l
) != 0);
1291 if ((m
& cntrl
) == cntrl
) result
|= (iswcntrl_l(ch
, __l
) != 0);
1292 if ((m
& upper
) == upper
) result
|= (iswupper_l(ch
, __l
) != 0);
1293 if ((m
& lower
) == lower
) result
|= (iswlower_l(ch
, __l
) != 0);
1294 if ((m
& alpha
) == alpha
) result
|= (iswalpha_l(ch
, __l
) != 0);
1295 if ((m
& digit
) == digit
) result
|= (iswdigit_l(ch
, __l
) != 0);
1296 if ((m
& punct
) == punct
) result
|= (iswpunct_l(ch
, __l
) != 0);
1297 if ((m
& xdigit
) == xdigit
) result
|= (iswxdigit_l(ch
, __l
) != 0);
1298 if ((m
& blank
) == blank
) result
|= (iswblank_l(ch
, __l
) != 0);
1304 ctype_byname
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
1306 for (; low
!= high
; ++low
, ++vec
)
1309 *vec
= static_cast<mask
>(ctype
<char>::classic_table()[*low
]);
1313 wint_t ch
= static_cast<wint_t>(*low
);
1314 if (iswspace_l(ch
, __l
))
1316 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1317 if (iswprint_l(ch
, __l
))
1320 if (iswcntrl_l(ch
, __l
))
1322 if (iswupper_l(ch
, __l
))
1324 if (iswlower_l(ch
, __l
))
1326 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1327 if (iswalpha_l(ch
, __l
))
1330 if (iswdigit_l(ch
, __l
))
1332 if (iswpunct_l(ch
, __l
))
1334 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1335 if (iswxdigit_l(ch
, __l
))
1338 #if !defined(__sun__)
1339 if (iswblank_l(ch
, __l
))
1348 ctype_byname
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
1350 for (; low
!= high
; ++low
)
1352 #ifdef _LIBCPP_WCTYPE_IS_MASK
1353 if (iswctype_l(*low
, m
, __l
))
1356 wint_t ch
= static_cast<wint_t>(*low
);
1357 if ((m
& space
) == space
&& iswspace_l(ch
, __l
)) break;
1358 if ((m
& print
) == print
&& iswprint_l(ch
, __l
)) break;
1359 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l
)) break;
1360 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l
)) break;
1361 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l
)) break;
1362 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l
)) break;
1363 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l
)) break;
1364 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l
)) break;
1365 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l
)) break;
1366 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l
)) break;
1373 ctype_byname
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
1375 for (; low
!= high
; ++low
)
1377 #ifdef _LIBCPP_WCTYPE_IS_MASK
1378 if (!iswctype_l(*low
, m
, __l
))
1381 wint_t ch
= static_cast<wint_t>(*low
);
1382 if ((m
& space
) == space
&& iswspace_l(ch
, __l
)) continue;
1383 if ((m
& print
) == print
&& iswprint_l(ch
, __l
)) continue;
1384 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l
)) continue;
1385 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l
)) continue;
1386 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l
)) continue;
1387 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l
)) continue;
1388 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l
)) continue;
1389 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l
)) continue;
1390 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l
)) continue;
1391 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l
)) continue;
1399 ctype_byname
<wchar_t>::do_toupper(char_type c
) const
1401 return towupper_l(c
, __l
);
1405 ctype_byname
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
1407 for (; low
!= high
; ++low
)
1408 *low
= towupper_l(*low
, __l
);
1413 ctype_byname
<wchar_t>::do_tolower(char_type c
) const
1415 return towlower_l(c
, __l
);
1419 ctype_byname
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
1421 for (; low
!= high
; ++low
)
1422 *low
= towlower_l(*low
, __l
);
1427 ctype_byname
<wchar_t>::do_widen(char c
) const
1429 return __libcpp_btowc_l(c
, __l
);
1433 ctype_byname
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1435 for (; low
!= high
; ++low
, ++dest
)
1436 *dest
= __libcpp_btowc_l(*low
, __l
);
1441 ctype_byname
<wchar_t>::do_narrow(char_type c
, char dfault
) const
1443 int r
= __libcpp_wctob_l(c
, __l
);
1444 return r
!= static_cast<int>(WEOF
) ? static_cast<char>(r
) : dfault
;
1448 ctype_byname
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1450 for (; low
!= high
; ++low
, ++dest
)
1452 int r
= __libcpp_wctob_l(*low
, __l
);
1453 *dest
= r
!= static_cast<int>(WEOF
) ? static_cast<char>(r
) : dfault
;
1458 // template <> class codecvt<char, char, mbstate_t>
1460 locale::id codecvt
<char, char, mbstate_t>::id
;
1462 codecvt
<char, char, mbstate_t>::~codecvt()
1466 codecvt
<char, char, mbstate_t>::result
1467 codecvt
<char, char, mbstate_t>::do_out(state_type
&,
1468 const intern_type
* frm
, const intern_type
*, const intern_type
*& frm_nxt
,
1469 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1476 codecvt
<char, char, mbstate_t>::result
1477 codecvt
<char, char, mbstate_t>::do_in(state_type
&,
1478 const extern_type
* frm
, const extern_type
*, const extern_type
*& frm_nxt
,
1479 intern_type
* to
, intern_type
*, intern_type
*& to_nxt
) const
1486 codecvt
<char, char, mbstate_t>::result
1487 codecvt
<char, char, mbstate_t>::do_unshift(state_type
&,
1488 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1495 codecvt
<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1501 codecvt
<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1507 codecvt
<char, char, mbstate_t>::do_length(state_type
&,
1508 const extern_type
* frm
, const extern_type
* end
, size_t mx
) const
1510 return static_cast<int>(min
<size_t>(mx
, static_cast<size_t>(end
-frm
)));
1514 codecvt
<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1519 // template <> class codecvt<wchar_t, char, mbstate_t>
1521 locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
1523 codecvt
<wchar_t, char, mbstate_t>::codecvt(size_t refs
)
1524 : locale::facet(refs
),
1525 __l(_LIBCPP_GET_C_LOCALE
)
1529 codecvt
<wchar_t, char, mbstate_t>::codecvt(const char* nm
, size_t refs
)
1530 : locale::facet(refs
),
1531 __l(newlocale(LC_ALL_MASK
, nm
, 0))
1534 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1535 " failed to construct for " + string(nm
));
1538 codecvt
<wchar_t, char, mbstate_t>::~codecvt()
1540 if (__l
!= _LIBCPP_GET_C_LOCALE
)
1544 codecvt
<wchar_t, char, mbstate_t>::result
1545 codecvt
<wchar_t, char, mbstate_t>::do_out(state_type
& st
,
1546 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
1547 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1549 // look for first internal null in frm
1550 const intern_type
* fend
= frm
;
1551 for (; fend
!= frm_end
; ++fend
)
1554 // loop over all null-terminated sequences in frm
1556 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1558 // save state in case it is needed to recover to_nxt on error
1559 mbstate_t save_state
= st
;
1560 size_t n
= __libcpp_wcsnrtombs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1561 static_cast<size_t>(to_end
-to
), &st
, __l
);
1562 if (n
== size_t(-1))
1564 // need to recover to_nxt
1565 for (to_nxt
= to
; frm
!= frm_nxt
; ++frm
)
1567 n
= __libcpp_wcrtomb_l(to_nxt
, *frm
, &save_state
, __l
);
1568 if (n
== size_t(-1))
1578 if (to_nxt
== to_end
)
1580 if (fend
!= frm_end
) // set up next null terminated sequence
1582 // Try to write the terminating null
1583 extern_type tmp
[MB_LEN_MAX
];
1584 n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l
);
1585 if (n
== size_t(-1)) // on error
1587 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1589 for (extern_type
* p
= tmp
; n
; --n
) // write it
1592 // look for next null in frm
1593 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1598 return frm_nxt
== frm_end
? ok
: partial
;
1601 codecvt
<wchar_t, char, mbstate_t>::result
1602 codecvt
<wchar_t, char, mbstate_t>::do_in(state_type
& st
,
1603 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
1604 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
1606 // look for first internal null in frm
1607 const extern_type
* fend
= frm
;
1608 for (; fend
!= frm_end
; ++fend
)
1611 // loop over all null-terminated sequences in frm
1613 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1615 // save state in case it is needed to recover to_nxt on error
1616 mbstate_t save_state
= st
;
1617 size_t n
= __libcpp_mbsnrtowcs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1618 static_cast<size_t>(to_end
-to
), &st
, __l
);
1619 if (n
== size_t(-1))
1621 // need to recover to_nxt
1622 for (to_nxt
= to
; frm
!= frm_nxt
; ++to_nxt
)
1624 n
= __libcpp_mbrtowc_l(to_nxt
, frm
, static_cast<size_t>(fend
-frm
),
1643 return frm_nxt
== frm_end
? ok
: partial
;
1645 if (n
== size_t(-1))
1648 if (to_nxt
== to_end
)
1650 if (fend
!= frm_end
) // set up next null terminated sequence
1652 // Try to write the terminating null
1653 n
= __libcpp_mbrtowc_l(to_nxt
, frm_nxt
, 1, &st
, __l
);
1654 if (n
!= 0) // on error
1658 // look for next null in frm
1659 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1664 return frm_nxt
== frm_end
? ok
: partial
;
1667 codecvt
<wchar_t, char, mbstate_t>::result
1668 codecvt
<wchar_t, char, mbstate_t>::do_unshift(state_type
& st
,
1669 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1672 extern_type tmp
[MB_LEN_MAX
];
1673 size_t n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l
);
1674 if (n
== size_t(-1) || n
== 0) // on error
1677 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1679 for (extern_type
* p
= tmp
; n
; --n
) // write it
1685 codecvt
<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1687 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX
, __l
) != 0)
1690 // stateless encoding
1691 if (__l
== 0 || __libcpp_mb_cur_max_l(__l
) == 1) // there are no known constant length encodings
1692 return 1; // which take more than 1 char to form a wchar_t
1697 codecvt
<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1703 codecvt
<wchar_t, char, mbstate_t>::do_length(state_type
& st
,
1704 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
1707 for (size_t nwchar_t
= 0; nwchar_t
< mx
&& frm
!= frm_end
; ++nwchar_t
)
1709 size_t n
= __libcpp_mbrlen_l(frm
, static_cast<size_t>(frm_end
-frm
), &st
, __l
);
1729 codecvt
<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1731 return __l
== 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l
));
1735 // UTF-32 UTF-16 UTF-8 # of code points
1736 // first second first second third fourth
1737 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1738 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1739 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1740 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1741 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1742 // 00D800 - 00DFFF invalid
1743 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1744 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1745 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1746 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1749 codecvt_base::result
1750 utf16_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
1751 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1752 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1756 if (mode
& generate_header
)
1758 if (to_end
-to_nxt
< 3)
1759 return codecvt_base::partial
;
1760 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1761 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1762 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1764 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1766 uint16_t wc1
= *frm_nxt
;
1768 return codecvt_base::error
;
1771 if (to_end
-to_nxt
< 1)
1772 return codecvt_base::partial
;
1773 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1775 else if (wc1
< 0x0800)
1777 if (to_end
-to_nxt
< 2)
1778 return codecvt_base::partial
;
1779 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1780 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1782 else if (wc1
< 0xD800)
1784 if (to_end
-to_nxt
< 3)
1785 return codecvt_base::partial
;
1786 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1787 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1788 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1790 else if (wc1
< 0xDC00)
1792 if (frm_end
-frm_nxt
< 2)
1793 return codecvt_base::partial
;
1794 uint16_t wc2
= frm_nxt
[1];
1795 if ((wc2
& 0xFC00) != 0xDC00)
1796 return codecvt_base::error
;
1797 if (to_end
-to_nxt
< 4)
1798 return codecvt_base::partial
;
1799 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1800 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1801 return codecvt_base::error
;
1803 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1804 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1805 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1806 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1807 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1809 else if (wc1
< 0xE000)
1811 return codecvt_base::error
;
1815 if (to_end
-to_nxt
< 3)
1816 return codecvt_base::partial
;
1817 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1818 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1819 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1822 return codecvt_base::ok
;
1826 codecvt_base::result
1827 utf16_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
1828 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1829 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1833 if (mode
& generate_header
)
1835 if (to_end
-to_nxt
< 3)
1836 return codecvt_base::partial
;
1837 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1838 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1839 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1841 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1843 uint16_t wc1
= static_cast<uint16_t>(*frm_nxt
);
1845 return codecvt_base::error
;
1848 if (to_end
-to_nxt
< 1)
1849 return codecvt_base::partial
;
1850 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1852 else if (wc1
< 0x0800)
1854 if (to_end
-to_nxt
< 2)
1855 return codecvt_base::partial
;
1856 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1857 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1859 else if (wc1
< 0xD800)
1861 if (to_end
-to_nxt
< 3)
1862 return codecvt_base::partial
;
1863 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1864 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1865 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1867 else if (wc1
< 0xDC00)
1869 if (frm_end
-frm_nxt
< 2)
1870 return codecvt_base::partial
;
1871 uint16_t wc2
= static_cast<uint16_t>(frm_nxt
[1]);
1872 if ((wc2
& 0xFC00) != 0xDC00)
1873 return codecvt_base::error
;
1874 if (to_end
-to_nxt
< 4)
1875 return codecvt_base::partial
;
1876 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1877 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1878 return codecvt_base::error
;
1880 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1881 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1882 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1883 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1884 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1886 else if (wc1
< 0xE000)
1888 return codecvt_base::error
;
1892 if (to_end
-to_nxt
< 3)
1893 return codecvt_base::partial
;
1894 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1895 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1896 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1899 return codecvt_base::ok
;
1903 codecvt_base::result
1904 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
1905 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
1906 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1910 if (mode
& consume_header
)
1912 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
1916 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
1918 uint8_t c1
= *frm_nxt
;
1920 return codecvt_base::error
;
1923 *to_nxt
= static_cast<uint16_t>(c1
);
1928 return codecvt_base::error
;
1932 if (frm_end
-frm_nxt
< 2)
1933 return codecvt_base::partial
;
1934 uint8_t c2
= frm_nxt
[1];
1935 if ((c2
& 0xC0) != 0x80)
1936 return codecvt_base::error
;
1937 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
1939 return codecvt_base::error
;
1945 if (frm_end
-frm_nxt
< 3)
1946 return codecvt_base::partial
;
1947 uint8_t c2
= frm_nxt
[1];
1948 uint8_t c3
= frm_nxt
[2];
1952 if ((c2
& 0xE0) != 0xA0)
1953 return codecvt_base::error
;
1956 if ((c2
& 0xE0) != 0x80)
1957 return codecvt_base::error
;
1960 if ((c2
& 0xC0) != 0x80)
1961 return codecvt_base::error
;
1964 if ((c3
& 0xC0) != 0x80)
1965 return codecvt_base::error
;
1966 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
1967 | ((c2
& 0x3F) << 6)
1970 return codecvt_base::error
;
1976 if (frm_end
-frm_nxt
< 4)
1977 return codecvt_base::partial
;
1978 uint8_t c2
= frm_nxt
[1];
1979 uint8_t c3
= frm_nxt
[2];
1980 uint8_t c4
= frm_nxt
[3];
1984 if (!(0x90 <= c2
&& c2
<= 0xBF))
1985 return codecvt_base::error
;
1988 if ((c2
& 0xF0) != 0x80)
1989 return codecvt_base::error
;
1992 if ((c2
& 0xC0) != 0x80)
1993 return codecvt_base::error
;
1996 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
1997 return codecvt_base::error
;
1998 if (to_end
-to_nxt
< 2)
1999 return codecvt_base::partial
;
2000 if ((((c1
& 7UL) << 18) +
2001 ((c2
& 0x3FUL
) << 12) +
2002 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2003 return codecvt_base::error
;
2004 *to_nxt
= static_cast<uint16_t>(
2006 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2007 | ((c2
& 0x0F) << 2)
2008 | ((c3
& 0x30) >> 4));
2009 *++to_nxt
= static_cast<uint16_t>(
2011 | ((c3
& 0x0F) << 6)
2017 return codecvt_base::error
;
2020 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2024 codecvt_base::result
2025 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2026 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2027 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2031 if (mode
& consume_header
)
2033 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2037 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2039 uint8_t c1
= *frm_nxt
;
2041 return codecvt_base::error
;
2044 *to_nxt
= static_cast<uint32_t>(c1
);
2049 return codecvt_base::error
;
2053 if (frm_end
-frm_nxt
< 2)
2054 return codecvt_base::partial
;
2055 uint8_t c2
= frm_nxt
[1];
2056 if ((c2
& 0xC0) != 0x80)
2057 return codecvt_base::error
;
2058 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2060 return codecvt_base::error
;
2061 *to_nxt
= static_cast<uint32_t>(t
);
2066 if (frm_end
-frm_nxt
< 3)
2067 return codecvt_base::partial
;
2068 uint8_t c2
= frm_nxt
[1];
2069 uint8_t c3
= frm_nxt
[2];
2073 if ((c2
& 0xE0) != 0xA0)
2074 return codecvt_base::error
;
2077 if ((c2
& 0xE0) != 0x80)
2078 return codecvt_base::error
;
2081 if ((c2
& 0xC0) != 0x80)
2082 return codecvt_base::error
;
2085 if ((c3
& 0xC0) != 0x80)
2086 return codecvt_base::error
;
2087 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2088 | ((c2
& 0x3F) << 6)
2091 return codecvt_base::error
;
2092 *to_nxt
= static_cast<uint32_t>(t
);
2097 if (frm_end
-frm_nxt
< 4)
2098 return codecvt_base::partial
;
2099 uint8_t c2
= frm_nxt
[1];
2100 uint8_t c3
= frm_nxt
[2];
2101 uint8_t c4
= frm_nxt
[3];
2105 if (!(0x90 <= c2
&& c2
<= 0xBF))
2106 return codecvt_base::error
;
2109 if ((c2
& 0xF0) != 0x80)
2110 return codecvt_base::error
;
2113 if ((c2
& 0xC0) != 0x80)
2114 return codecvt_base::error
;
2117 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2118 return codecvt_base::error
;
2119 if (to_end
-to_nxt
< 2)
2120 return codecvt_base::partial
;
2121 if ((((c1
& 7UL) << 18) +
2122 ((c2
& 0x3FUL
) << 12) +
2123 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2124 return codecvt_base::error
;
2125 *to_nxt
= static_cast<uint32_t>(
2127 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2128 | ((c2
& 0x0F) << 2)
2129 | ((c3
& 0x30) >> 4));
2130 *++to_nxt
= static_cast<uint32_t>(
2132 | ((c3
& 0x0F) << 6)
2138 return codecvt_base::error
;
2141 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2146 utf8_to_utf16_length(const uint8_t* frm
, const uint8_t* frm_end
,
2147 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2148 codecvt_mode mode
= codecvt_mode(0))
2150 const uint8_t* frm_nxt
= frm
;
2151 if (mode
& consume_header
)
2153 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2157 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
&& nchar16_t
< mx
; ++nchar16_t
)
2159 uint8_t c1
= *frm_nxt
;
2172 if ((frm_end
-frm_nxt
< 2) || (frm_nxt
[1] & 0xC0) != 0x80)
2174 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (frm_nxt
[1] & 0x3F));
2181 if (frm_end
-frm_nxt
< 3)
2183 uint8_t c2
= frm_nxt
[1];
2184 uint8_t c3
= frm_nxt
[2];
2188 if ((c2
& 0xE0) != 0xA0)
2189 return static_cast<int>(frm_nxt
- frm
);
2192 if ((c2
& 0xE0) != 0x80)
2193 return static_cast<int>(frm_nxt
- frm
);
2196 if ((c2
& 0xC0) != 0x80)
2197 return static_cast<int>(frm_nxt
- frm
);
2200 if ((c3
& 0xC0) != 0x80)
2202 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2208 if (frm_end
-frm_nxt
< 4 || mx
-nchar16_t
< 2)
2210 uint8_t c2
= frm_nxt
[1];
2211 uint8_t c3
= frm_nxt
[2];
2212 uint8_t c4
= frm_nxt
[3];
2216 if (!(0x90 <= c2
&& c2
<= 0xBF))
2217 return static_cast<int>(frm_nxt
- frm
);
2220 if ((c2
& 0xF0) != 0x80)
2221 return static_cast<int>(frm_nxt
- frm
);
2224 if ((c2
& 0xC0) != 0x80)
2225 return static_cast<int>(frm_nxt
- frm
);
2228 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2230 if ((((c1
& 7UL) << 18) +
2231 ((c2
& 0x3FUL
) << 12) +
2232 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2242 return static_cast<int>(frm_nxt
- frm
);
2246 codecvt_base::result
2247 ucs4_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2248 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2249 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2253 if (mode
& generate_header
)
2255 if (to_end
-to_nxt
< 3)
2256 return codecvt_base::partial
;
2257 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2258 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2259 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2261 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2263 uint32_t wc
= *frm_nxt
;
2264 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2265 return codecvt_base::error
;
2268 if (to_end
-to_nxt
< 1)
2269 return codecvt_base::partial
;
2270 *to_nxt
++ = static_cast<uint8_t>(wc
);
2272 else if (wc
< 0x000800)
2274 if (to_end
-to_nxt
< 2)
2275 return codecvt_base::partial
;
2276 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2277 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2279 else if (wc
< 0x010000)
2281 if (to_end
-to_nxt
< 3)
2282 return codecvt_base::partial
;
2283 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2284 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2285 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2287 else // if (wc < 0x110000)
2289 if (to_end
-to_nxt
< 4)
2290 return codecvt_base::partial
;
2291 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (wc
>> 18));
2292 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x03F000) >> 12));
2293 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x000FC0) >> 6));
2294 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x00003F));
2297 return codecvt_base::ok
;
2301 codecvt_base::result
2302 utf8_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2303 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2304 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2308 if (mode
& consume_header
)
2310 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2314 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2316 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2320 return codecvt_base::error
;
2321 *to_nxt
= static_cast<uint32_t>(c1
);
2326 return codecvt_base::error
;
2330 if (frm_end
-frm_nxt
< 2)
2331 return codecvt_base::partial
;
2332 uint8_t c2
= frm_nxt
[1];
2333 if ((c2
& 0xC0) != 0x80)
2334 return codecvt_base::error
;
2335 uint32_t t
= static_cast<uint32_t>(((c1
& 0x1F) << 6)
2338 return codecvt_base::error
;
2344 if (frm_end
-frm_nxt
< 3)
2345 return codecvt_base::partial
;
2346 uint8_t c2
= frm_nxt
[1];
2347 uint8_t c3
= frm_nxt
[2];
2351 if ((c2
& 0xE0) != 0xA0)
2352 return codecvt_base::error
;
2355 if ((c2
& 0xE0) != 0x80)
2356 return codecvt_base::error
;
2359 if ((c2
& 0xC0) != 0x80)
2360 return codecvt_base::error
;
2363 if ((c3
& 0xC0) != 0x80)
2364 return codecvt_base::error
;
2365 uint32_t t
= static_cast<uint32_t>(((c1
& 0x0F) << 12)
2366 | ((c2
& 0x3F) << 6)
2369 return codecvt_base::error
;
2375 if (frm_end
-frm_nxt
< 4)
2376 return codecvt_base::partial
;
2377 uint8_t c2
= frm_nxt
[1];
2378 uint8_t c3
= frm_nxt
[2];
2379 uint8_t c4
= frm_nxt
[3];
2383 if (!(0x90 <= c2
&& c2
<= 0xBF))
2384 return codecvt_base::error
;
2387 if ((c2
& 0xF0) != 0x80)
2388 return codecvt_base::error
;
2391 if ((c2
& 0xC0) != 0x80)
2392 return codecvt_base::error
;
2395 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2396 return codecvt_base::error
;
2397 uint32_t t
= static_cast<uint32_t>(((c1
& 0x07) << 18)
2398 | ((c2
& 0x3F) << 12)
2399 | ((c3
& 0x3F) << 6)
2402 return codecvt_base::error
;
2408 return codecvt_base::error
;
2411 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2416 utf8_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2417 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2418 codecvt_mode mode
= codecvt_mode(0))
2420 const uint8_t* frm_nxt
= frm
;
2421 if (mode
& consume_header
)
2423 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2427 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2429 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2442 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2444 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2450 if (frm_end
-frm_nxt
< 3)
2452 uint8_t c2
= frm_nxt
[1];
2453 uint8_t c3
= frm_nxt
[2];
2457 if ((c2
& 0xE0) != 0xA0)
2458 return static_cast<int>(frm_nxt
- frm
);
2461 if ((c2
& 0xE0) != 0x80)
2462 return static_cast<int>(frm_nxt
- frm
);
2465 if ((c2
& 0xC0) != 0x80)
2466 return static_cast<int>(frm_nxt
- frm
);
2469 if ((c3
& 0xC0) != 0x80)
2471 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2477 if (frm_end
-frm_nxt
< 4)
2479 uint8_t c2
= frm_nxt
[1];
2480 uint8_t c3
= frm_nxt
[2];
2481 uint8_t c4
= frm_nxt
[3];
2485 if (!(0x90 <= c2
&& c2
<= 0xBF))
2486 return static_cast<int>(frm_nxt
- frm
);
2489 if ((c2
& 0xF0) != 0x80)
2490 return static_cast<int>(frm_nxt
- frm
);
2493 if ((c2
& 0xC0) != 0x80)
2494 return static_cast<int>(frm_nxt
- frm
);
2497 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2499 if ((((c1
& 0x07u
) << 18) | ((c2
& 0x3Fu
) << 12) |
2500 ((c3
& 0x3Fu
) << 6) | (c4
& 0x3Fu
)) > Maxcode
)
2509 return static_cast<int>(frm_nxt
- frm
);
2513 codecvt_base::result
2514 ucs2_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
2515 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2516 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2520 if (mode
& generate_header
)
2522 if (to_end
-to_nxt
< 3)
2523 return codecvt_base::partial
;
2524 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2525 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2526 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2528 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2530 uint16_t wc
= *frm_nxt
;
2531 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2532 return codecvt_base::error
;
2535 if (to_end
-to_nxt
< 1)
2536 return codecvt_base::partial
;
2537 *to_nxt
++ = static_cast<uint8_t>(wc
);
2539 else if (wc
< 0x0800)
2541 if (to_end
-to_nxt
< 2)
2542 return codecvt_base::partial
;
2543 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2544 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2546 else // if (wc <= 0xFFFF)
2548 if (to_end
-to_nxt
< 3)
2549 return codecvt_base::partial
;
2550 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2551 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2552 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2555 return codecvt_base::ok
;
2559 codecvt_base::result
2560 utf8_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2561 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
2562 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2566 if (mode
& consume_header
)
2568 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2572 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2574 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2578 return codecvt_base::error
;
2579 *to_nxt
= static_cast<uint16_t>(c1
);
2584 return codecvt_base::error
;
2588 if (frm_end
-frm_nxt
< 2)
2589 return codecvt_base::partial
;
2590 uint8_t c2
= frm_nxt
[1];
2591 if ((c2
& 0xC0) != 0x80)
2592 return codecvt_base::error
;
2593 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6)
2596 return codecvt_base::error
;
2602 if (frm_end
-frm_nxt
< 3)
2603 return codecvt_base::partial
;
2604 uint8_t c2
= frm_nxt
[1];
2605 uint8_t c3
= frm_nxt
[2];
2609 if ((c2
& 0xE0) != 0xA0)
2610 return codecvt_base::error
;
2613 if ((c2
& 0xE0) != 0x80)
2614 return codecvt_base::error
;
2617 if ((c2
& 0xC0) != 0x80)
2618 return codecvt_base::error
;
2621 if ((c3
& 0xC0) != 0x80)
2622 return codecvt_base::error
;
2623 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2624 | ((c2
& 0x3F) << 6)
2627 return codecvt_base::error
;
2633 return codecvt_base::error
;
2636 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2641 utf8_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
2642 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2643 codecvt_mode mode
= codecvt_mode(0))
2645 const uint8_t* frm_nxt
= frm
;
2646 if (mode
& consume_header
)
2648 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2652 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2654 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2667 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2669 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2675 if (frm_end
-frm_nxt
< 3)
2677 uint8_t c2
= frm_nxt
[1];
2678 uint8_t c3
= frm_nxt
[2];
2682 if ((c2
& 0xE0) != 0xA0)
2683 return static_cast<int>(frm_nxt
- frm
);
2686 if ((c2
& 0xE0) != 0x80)
2687 return static_cast<int>(frm_nxt
- frm
);
2690 if ((c2
& 0xC0) != 0x80)
2691 return static_cast<int>(frm_nxt
- frm
);
2694 if ((c3
& 0xC0) != 0x80)
2696 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2705 return static_cast<int>(frm_nxt
- frm
);
2709 codecvt_base::result
2710 ucs4_to_utf16be(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2711 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2712 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2716 if (mode
& generate_header
)
2718 if (to_end
-to_nxt
< 2)
2719 return codecvt_base::partial
;
2720 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2721 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2723 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2725 uint32_t wc
= *frm_nxt
;
2726 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2727 return codecvt_base::error
;
2730 if (to_end
-to_nxt
< 2)
2731 return codecvt_base::partial
;
2732 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2733 *to_nxt
++ = static_cast<uint8_t>(wc
);
2737 if (to_end
-to_nxt
< 4)
2738 return codecvt_base::partial
;
2739 uint16_t t
= static_cast<uint16_t>(
2741 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2742 | ((wc
& 0x00FC00) >> 10));
2743 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2744 *to_nxt
++ = static_cast<uint8_t>(t
);
2745 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2746 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2747 *to_nxt
++ = static_cast<uint8_t>(t
);
2750 return codecvt_base::ok
;
2754 codecvt_base::result
2755 utf16be_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2756 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2757 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2761 if (mode
& consume_header
)
2763 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2766 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2768 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2769 if ((c1
& 0xFC00) == 0xDC00)
2770 return codecvt_base::error
;
2771 if ((c1
& 0xFC00) != 0xD800)
2774 return codecvt_base::error
;
2775 *to_nxt
= static_cast<uint32_t>(c1
);
2780 if (frm_end
-frm_nxt
< 4)
2781 return codecvt_base::partial
;
2782 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2783 if ((c2
& 0xFC00) != 0xDC00)
2784 return codecvt_base::error
;
2785 uint32_t t
= static_cast<uint32_t>(
2786 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2787 | ((c1
& 0x003F) << 10)
2790 return codecvt_base::error
;
2795 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2800 utf16be_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2801 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2802 codecvt_mode mode
= codecvt_mode(0))
2804 const uint8_t* frm_nxt
= frm
;
2805 if (mode
& consume_header
)
2807 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2810 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2812 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2813 if ((c1
& 0xFC00) == 0xDC00)
2815 if ((c1
& 0xFC00) != 0xD800)
2823 if (frm_end
-frm_nxt
< 4)
2825 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2826 if ((c2
& 0xFC00) != 0xDC00)
2828 uint32_t t
= static_cast<uint32_t>(
2829 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2830 | ((c1
& 0x003F) << 10)
2837 return static_cast<int>(frm_nxt
- frm
);
2841 codecvt_base::result
2842 ucs4_to_utf16le(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2843 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2844 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2848 if (mode
& generate_header
)
2850 if (to_end
- to_nxt
< 2)
2851 return codecvt_base::partial
;
2852 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2853 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2855 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2857 uint32_t wc
= *frm_nxt
;
2858 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2859 return codecvt_base::error
;
2862 if (to_end
-to_nxt
< 2)
2863 return codecvt_base::partial
;
2864 *to_nxt
++ = static_cast<uint8_t>(wc
);
2865 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2869 if (to_end
-to_nxt
< 4)
2870 return codecvt_base::partial
;
2871 uint16_t t
= static_cast<uint16_t>(
2873 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2874 | ((wc
& 0x00FC00) >> 10));
2875 *to_nxt
++ = static_cast<uint8_t>(t
);
2876 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2877 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2878 *to_nxt
++ = static_cast<uint8_t>(t
);
2879 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2882 return codecvt_base::ok
;
2886 codecvt_base::result
2887 utf16le_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2888 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2889 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2893 if (mode
& consume_header
)
2895 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2898 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2900 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2901 if ((c1
& 0xFC00) == 0xDC00)
2902 return codecvt_base::error
;
2903 if ((c1
& 0xFC00) != 0xD800)
2906 return codecvt_base::error
;
2907 *to_nxt
= static_cast<uint32_t>(c1
);
2912 if (frm_end
-frm_nxt
< 4)
2913 return codecvt_base::partial
;
2914 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2915 if ((c2
& 0xFC00) != 0xDC00)
2916 return codecvt_base::error
;
2917 uint32_t t
= static_cast<uint32_t>(
2918 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2919 | ((c1
& 0x003F) << 10)
2922 return codecvt_base::error
;
2927 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2932 utf16le_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2933 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2934 codecvt_mode mode
= codecvt_mode(0))
2936 const uint8_t* frm_nxt
= frm
;
2937 if (mode
& consume_header
)
2939 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2942 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2944 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2945 if ((c1
& 0xFC00) == 0xDC00)
2947 if ((c1
& 0xFC00) != 0xD800)
2955 if (frm_end
-frm_nxt
< 4)
2957 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2958 if ((c2
& 0xFC00) != 0xDC00)
2960 uint32_t t
= static_cast<uint32_t>(
2961 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2962 | ((c1
& 0x003F) << 10)
2969 return static_cast<int>(frm_nxt
- frm
);
2973 codecvt_base::result
2974 ucs2_to_utf16be(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
2975 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2976 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2980 if (mode
& generate_header
)
2982 if (to_end
-to_nxt
< 2)
2983 return codecvt_base::partial
;
2984 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2985 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2987 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2989 uint16_t wc
= *frm_nxt
;
2990 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2991 return codecvt_base::error
;
2992 if (to_end
-to_nxt
< 2)
2993 return codecvt_base::partial
;
2994 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2995 *to_nxt
++ = static_cast<uint8_t>(wc
);
2997 return codecvt_base::ok
;
3001 codecvt_base::result
3002 utf16be_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3003 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3004 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3008 if (mode
& consume_header
)
3010 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3013 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3015 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3016 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3017 return codecvt_base::error
;
3021 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3026 utf16be_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3027 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3028 codecvt_mode mode
= codecvt_mode(0))
3030 const uint8_t* frm_nxt
= frm
;
3031 if (mode
& consume_header
)
3033 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3036 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3038 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3039 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3043 return static_cast<int>(frm_nxt
- frm
);
3047 codecvt_base::result
3048 ucs2_to_utf16le(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3049 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3050 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3054 if (mode
& generate_header
)
3056 if (to_end
-to_nxt
< 2)
3057 return codecvt_base::partial
;
3058 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3059 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3061 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3063 uint16_t wc
= *frm_nxt
;
3064 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3065 return codecvt_base::error
;
3066 if (to_end
-to_nxt
< 2)
3067 return codecvt_base::partial
;
3068 *to_nxt
++ = static_cast<uint8_t>(wc
);
3069 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3071 return codecvt_base::ok
;
3075 codecvt_base::result
3076 utf16le_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3077 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3078 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3082 if (mode
& consume_header
)
3084 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3087 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3089 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3090 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3091 return codecvt_base::error
;
3095 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3100 utf16le_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3101 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3102 codecvt_mode mode
= codecvt_mode(0))
3104 const uint8_t* frm_nxt
= frm
;
3106 if (mode
& consume_header
)
3108 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3111 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3113 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3114 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3118 return static_cast<int>(frm_nxt
- frm
);
3121 // template <> class codecvt<char16_t, char, mbstate_t>
3123 locale::id codecvt
<char16_t
, char, mbstate_t>::id
;
3125 codecvt
<char16_t
, char, mbstate_t>::~codecvt()
3129 codecvt
<char16_t
, char, mbstate_t>::result
3130 codecvt
<char16_t
, char, mbstate_t>::do_out(state_type
&,
3131 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3132 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3134 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3135 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3136 const uint16_t* _frm_nxt
= _frm
;
3137 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3138 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3139 uint8_t* _to_nxt
= _to
;
3140 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3141 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3142 to_nxt
= to
+ (_to_nxt
- _to
);
3146 codecvt
<char16_t
, char, mbstate_t>::result
3147 codecvt
<char16_t
, char, mbstate_t>::do_in(state_type
&,
3148 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3149 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3151 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3152 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3153 const uint8_t* _frm_nxt
= _frm
;
3154 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3155 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3156 uint16_t* _to_nxt
= _to
;
3157 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3158 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3159 to_nxt
= to
+ (_to_nxt
- _to
);
3163 codecvt
<char16_t
, char, mbstate_t>::result
3164 codecvt
<char16_t
, char, mbstate_t>::do_unshift(state_type
&,
3165 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3172 codecvt
<char16_t
, char, mbstate_t>::do_encoding() const _NOEXCEPT
3178 codecvt
<char16_t
, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3184 codecvt
<char16_t
, char, mbstate_t>::do_length(state_type
&,
3185 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3187 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3188 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3189 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3193 codecvt
<char16_t
, char, mbstate_t>::do_max_length() const _NOEXCEPT
3198 #ifndef _LIBCPP_NO_HAS_CHAR8_T
3200 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3202 locale::id codecvt
<char16_t
, char8_t
, mbstate_t>::id
;
3204 codecvt
<char16_t
, char8_t
, mbstate_t>::~codecvt()
3208 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3209 codecvt
<char16_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3210 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3211 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3213 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3214 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3215 const uint16_t* _frm_nxt
= _frm
;
3216 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3217 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3218 uint8_t* _to_nxt
= _to
;
3219 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3220 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3221 to_nxt
= to
+ (_to_nxt
- _to
);
3225 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3226 codecvt
<char16_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3227 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3228 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3230 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3231 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3232 const uint8_t* _frm_nxt
= _frm
;
3233 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3234 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3235 uint16_t* _to_nxt
= _to
;
3236 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3237 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3238 to_nxt
= to
+ (_to_nxt
- _to
);
3242 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3243 codecvt
<char16_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3244 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3251 codecvt
<char16_t
, char8_t
, mbstate_t>::do_encoding() const _NOEXCEPT
3257 codecvt
<char16_t
, char8_t
, mbstate_t>::do_always_noconv() const _NOEXCEPT
3263 codecvt
<char16_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3264 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3266 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3267 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3268 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3272 codecvt
<char16_t
, char8_t
, mbstate_t>::do_max_length() const _NOEXCEPT
3279 // template <> class codecvt<char32_t, char, mbstate_t>
3281 locale::id codecvt
<char32_t
, char, mbstate_t>::id
;
3283 codecvt
<char32_t
, char, mbstate_t>::~codecvt()
3287 codecvt
<char32_t
, char, mbstate_t>::result
3288 codecvt
<char32_t
, char, mbstate_t>::do_out(state_type
&,
3289 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3290 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3292 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3293 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3294 const uint32_t* _frm_nxt
= _frm
;
3295 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3296 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3297 uint8_t* _to_nxt
= _to
;
3298 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3299 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3300 to_nxt
= to
+ (_to_nxt
- _to
);
3304 codecvt
<char32_t
, char, mbstate_t>::result
3305 codecvt
<char32_t
, char, mbstate_t>::do_in(state_type
&,
3306 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3307 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3309 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3310 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3311 const uint8_t* _frm_nxt
= _frm
;
3312 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3313 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3314 uint32_t* _to_nxt
= _to
;
3315 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3316 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3317 to_nxt
= to
+ (_to_nxt
- _to
);
3321 codecvt
<char32_t
, char, mbstate_t>::result
3322 codecvt
<char32_t
, char, mbstate_t>::do_unshift(state_type
&,
3323 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3330 codecvt
<char32_t
, char, mbstate_t>::do_encoding() const _NOEXCEPT
3336 codecvt
<char32_t
, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3342 codecvt
<char32_t
, char, mbstate_t>::do_length(state_type
&,
3343 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3345 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3346 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3347 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3351 codecvt
<char32_t
, char, mbstate_t>::do_max_length() const _NOEXCEPT
3356 #ifndef _LIBCPP_NO_HAS_CHAR8_T
3358 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3360 locale::id codecvt
<char32_t
, char8_t
, mbstate_t>::id
;
3362 codecvt
<char32_t
, char8_t
, mbstate_t>::~codecvt()
3366 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3367 codecvt
<char32_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3368 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3369 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3371 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3372 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3373 const uint32_t* _frm_nxt
= _frm
;
3374 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3375 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3376 uint8_t* _to_nxt
= _to
;
3377 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3378 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3379 to_nxt
= to
+ (_to_nxt
- _to
);
3383 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3384 codecvt
<char32_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3385 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3386 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3388 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3389 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3390 const uint8_t* _frm_nxt
= _frm
;
3391 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3392 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3393 uint32_t* _to_nxt
= _to
;
3394 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3395 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3396 to_nxt
= to
+ (_to_nxt
- _to
);
3400 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3401 codecvt
<char32_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3402 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3409 codecvt
<char32_t
, char8_t
, mbstate_t>::do_encoding() const _NOEXCEPT
3415 codecvt
<char32_t
, char8_t
, mbstate_t>::do_always_noconv() const _NOEXCEPT
3421 codecvt
<char32_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3422 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3424 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3425 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3426 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3430 codecvt
<char32_t
, char8_t
, mbstate_t>::do_max_length() const _NOEXCEPT
3437 // __codecvt_utf8<wchar_t>
3439 __codecvt_utf8
<wchar_t>::result
3440 __codecvt_utf8
<wchar_t>::do_out(state_type
&,
3441 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3442 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3444 #if defined(_LIBCPP_SHORT_WCHAR)
3445 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3446 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3447 const uint16_t* _frm_nxt
= _frm
;
3449 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3450 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3451 const uint32_t* _frm_nxt
= _frm
;
3453 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3454 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3455 uint8_t* _to_nxt
= _to
;
3456 #if defined(_LIBCPP_SHORT_WCHAR)
3457 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3460 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3463 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3464 to_nxt
= to
+ (_to_nxt
- _to
);
3468 __codecvt_utf8
<wchar_t>::result
3469 __codecvt_utf8
<wchar_t>::do_in(state_type
&,
3470 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3471 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3473 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3474 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3475 const uint8_t* _frm_nxt
= _frm
;
3476 #if defined(_LIBCPP_SHORT_WCHAR)
3477 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3478 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3479 uint16_t* _to_nxt
= _to
;
3480 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3483 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3484 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3485 uint32_t* _to_nxt
= _to
;
3486 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3489 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3490 to_nxt
= to
+ (_to_nxt
- _to
);
3494 __codecvt_utf8
<wchar_t>::result
3495 __codecvt_utf8
<wchar_t>::do_unshift(state_type
&,
3496 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3503 __codecvt_utf8
<wchar_t>::do_encoding() const _NOEXCEPT
3509 __codecvt_utf8
<wchar_t>::do_always_noconv() const _NOEXCEPT
3515 __codecvt_utf8
<wchar_t>::do_length(state_type
&,
3516 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3518 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3519 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3520 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3524 __codecvt_utf8
<wchar_t>::do_max_length() const _NOEXCEPT
3526 if (_Mode_
& consume_header
)
3531 // __codecvt_utf8<char16_t>
3533 __codecvt_utf8
<char16_t
>::result
3534 __codecvt_utf8
<char16_t
>::do_out(state_type
&,
3535 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3536 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3538 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3539 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3540 const uint16_t* _frm_nxt
= _frm
;
3541 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3542 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3543 uint8_t* _to_nxt
= _to
;
3544 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3546 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3547 to_nxt
= to
+ (_to_nxt
- _to
);
3551 __codecvt_utf8
<char16_t
>::result
3552 __codecvt_utf8
<char16_t
>::do_in(state_type
&,
3553 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3554 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3556 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3557 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3558 const uint8_t* _frm_nxt
= _frm
;
3559 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3560 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3561 uint16_t* _to_nxt
= _to
;
3562 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3564 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3565 to_nxt
= to
+ (_to_nxt
- _to
);
3569 __codecvt_utf8
<char16_t
>::result
3570 __codecvt_utf8
<char16_t
>::do_unshift(state_type
&,
3571 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3578 __codecvt_utf8
<char16_t
>::do_encoding() const _NOEXCEPT
3584 __codecvt_utf8
<char16_t
>::do_always_noconv() const _NOEXCEPT
3590 __codecvt_utf8
<char16_t
>::do_length(state_type
&,
3591 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3593 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3594 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3595 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3599 __codecvt_utf8
<char16_t
>::do_max_length() const _NOEXCEPT
3601 if (_Mode_
& consume_header
)
3606 // __codecvt_utf8<char32_t>
3608 __codecvt_utf8
<char32_t
>::result
3609 __codecvt_utf8
<char32_t
>::do_out(state_type
&,
3610 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3611 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3613 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3614 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3615 const uint32_t* _frm_nxt
= _frm
;
3616 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3617 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3618 uint8_t* _to_nxt
= _to
;
3619 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3621 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3622 to_nxt
= to
+ (_to_nxt
- _to
);
3626 __codecvt_utf8
<char32_t
>::result
3627 __codecvt_utf8
<char32_t
>::do_in(state_type
&,
3628 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3629 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3631 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3632 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3633 const uint8_t* _frm_nxt
= _frm
;
3634 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3635 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3636 uint32_t* _to_nxt
= _to
;
3637 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3639 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3640 to_nxt
= to
+ (_to_nxt
- _to
);
3644 __codecvt_utf8
<char32_t
>::result
3645 __codecvt_utf8
<char32_t
>::do_unshift(state_type
&,
3646 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3653 __codecvt_utf8
<char32_t
>::do_encoding() const _NOEXCEPT
3659 __codecvt_utf8
<char32_t
>::do_always_noconv() const _NOEXCEPT
3665 __codecvt_utf8
<char32_t
>::do_length(state_type
&,
3666 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3668 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3669 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3670 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3674 __codecvt_utf8
<char32_t
>::do_max_length() const _NOEXCEPT
3676 if (_Mode_
& consume_header
)
3681 // __codecvt_utf16<wchar_t, false>
3683 __codecvt_utf16
<wchar_t, false>::result
3684 __codecvt_utf16
<wchar_t, false>::do_out(state_type
&,
3685 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3686 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3688 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3689 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3690 const uint32_t* _frm_nxt
= _frm
;
3691 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3692 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3693 uint8_t* _to_nxt
= _to
;
3694 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3696 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3697 to_nxt
= to
+ (_to_nxt
- _to
);
3701 __codecvt_utf16
<wchar_t, false>::result
3702 __codecvt_utf16
<wchar_t, false>::do_in(state_type
&,
3703 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3704 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3706 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3707 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3708 const uint8_t* _frm_nxt
= _frm
;
3709 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3710 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3711 uint32_t* _to_nxt
= _to
;
3712 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3714 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3715 to_nxt
= to
+ (_to_nxt
- _to
);
3719 __codecvt_utf16
<wchar_t, false>::result
3720 __codecvt_utf16
<wchar_t, false>::do_unshift(state_type
&,
3721 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3728 __codecvt_utf16
<wchar_t, false>::do_encoding() const _NOEXCEPT
3734 __codecvt_utf16
<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3740 __codecvt_utf16
<wchar_t, false>::do_length(state_type
&,
3741 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3743 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3744 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3745 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3749 __codecvt_utf16
<wchar_t, false>::do_max_length() const _NOEXCEPT
3751 if (_Mode_
& consume_header
)
3756 // __codecvt_utf16<wchar_t, true>
3758 __codecvt_utf16
<wchar_t, true>::result
3759 __codecvt_utf16
<wchar_t, true>::do_out(state_type
&,
3760 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3761 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3763 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3764 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3765 const uint32_t* _frm_nxt
= _frm
;
3766 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3767 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3768 uint8_t* _to_nxt
= _to
;
3769 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3771 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3772 to_nxt
= to
+ (_to_nxt
- _to
);
3776 __codecvt_utf16
<wchar_t, true>::result
3777 __codecvt_utf16
<wchar_t, true>::do_in(state_type
&,
3778 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3779 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3781 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3782 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3783 const uint8_t* _frm_nxt
= _frm
;
3784 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3785 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3786 uint32_t* _to_nxt
= _to
;
3787 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3789 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3790 to_nxt
= to
+ (_to_nxt
- _to
);
3794 __codecvt_utf16
<wchar_t, true>::result
3795 __codecvt_utf16
<wchar_t, true>::do_unshift(state_type
&,
3796 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3803 __codecvt_utf16
<wchar_t, true>::do_encoding() const _NOEXCEPT
3809 __codecvt_utf16
<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3815 __codecvt_utf16
<wchar_t, true>::do_length(state_type
&,
3816 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3818 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3819 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3820 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3824 __codecvt_utf16
<wchar_t, true>::do_max_length() const _NOEXCEPT
3826 if (_Mode_
& consume_header
)
3831 // __codecvt_utf16<char16_t, false>
3833 __codecvt_utf16
<char16_t
, false>::result
3834 __codecvt_utf16
<char16_t
, false>::do_out(state_type
&,
3835 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3836 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3838 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3839 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3840 const uint16_t* _frm_nxt
= _frm
;
3841 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3842 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3843 uint8_t* _to_nxt
= _to
;
3844 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3846 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3847 to_nxt
= to
+ (_to_nxt
- _to
);
3851 __codecvt_utf16
<char16_t
, false>::result
3852 __codecvt_utf16
<char16_t
, false>::do_in(state_type
&,
3853 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3854 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3856 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3857 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3858 const uint8_t* _frm_nxt
= _frm
;
3859 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3860 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3861 uint16_t* _to_nxt
= _to
;
3862 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3864 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3865 to_nxt
= to
+ (_to_nxt
- _to
);
3869 __codecvt_utf16
<char16_t
, false>::result
3870 __codecvt_utf16
<char16_t
, false>::do_unshift(state_type
&,
3871 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3878 __codecvt_utf16
<char16_t
, false>::do_encoding() const _NOEXCEPT
3884 __codecvt_utf16
<char16_t
, false>::do_always_noconv() const _NOEXCEPT
3890 __codecvt_utf16
<char16_t
, false>::do_length(state_type
&,
3891 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3893 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3894 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3895 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3899 __codecvt_utf16
<char16_t
, false>::do_max_length() const _NOEXCEPT
3901 if (_Mode_
& consume_header
)
3906 // __codecvt_utf16<char16_t, true>
3908 __codecvt_utf16
<char16_t
, true>::result
3909 __codecvt_utf16
<char16_t
, true>::do_out(state_type
&,
3910 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3911 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3913 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3914 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3915 const uint16_t* _frm_nxt
= _frm
;
3916 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3917 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3918 uint8_t* _to_nxt
= _to
;
3919 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3921 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3922 to_nxt
= to
+ (_to_nxt
- _to
);
3926 __codecvt_utf16
<char16_t
, true>::result
3927 __codecvt_utf16
<char16_t
, true>::do_in(state_type
&,
3928 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3929 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3931 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3932 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3933 const uint8_t* _frm_nxt
= _frm
;
3934 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3935 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3936 uint16_t* _to_nxt
= _to
;
3937 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3939 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3940 to_nxt
= to
+ (_to_nxt
- _to
);
3944 __codecvt_utf16
<char16_t
, true>::result
3945 __codecvt_utf16
<char16_t
, true>::do_unshift(state_type
&,
3946 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3953 __codecvt_utf16
<char16_t
, true>::do_encoding() const _NOEXCEPT
3959 __codecvt_utf16
<char16_t
, true>::do_always_noconv() const _NOEXCEPT
3965 __codecvt_utf16
<char16_t
, true>::do_length(state_type
&,
3966 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3968 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3969 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3970 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
3974 __codecvt_utf16
<char16_t
, true>::do_max_length() const _NOEXCEPT
3976 if (_Mode_
& consume_header
)
3981 // __codecvt_utf16<char32_t, false>
3983 __codecvt_utf16
<char32_t
, false>::result
3984 __codecvt_utf16
<char32_t
, false>::do_out(state_type
&,
3985 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3986 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3988 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3989 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3990 const uint32_t* _frm_nxt
= _frm
;
3991 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3992 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3993 uint8_t* _to_nxt
= _to
;
3994 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3996 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3997 to_nxt
= to
+ (_to_nxt
- _to
);
4001 __codecvt_utf16
<char32_t
, false>::result
4002 __codecvt_utf16
<char32_t
, false>::do_in(state_type
&,
4003 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4004 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4006 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4007 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4008 const uint8_t* _frm_nxt
= _frm
;
4009 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4010 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4011 uint32_t* _to_nxt
= _to
;
4012 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4014 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4015 to_nxt
= to
+ (_to_nxt
- _to
);
4019 __codecvt_utf16
<char32_t
, false>::result
4020 __codecvt_utf16
<char32_t
, false>::do_unshift(state_type
&,
4021 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4028 __codecvt_utf16
<char32_t
, false>::do_encoding() const _NOEXCEPT
4034 __codecvt_utf16
<char32_t
, false>::do_always_noconv() const _NOEXCEPT
4040 __codecvt_utf16
<char32_t
, false>::do_length(state_type
&,
4041 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4043 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4044 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4045 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
4049 __codecvt_utf16
<char32_t
, false>::do_max_length() const _NOEXCEPT
4051 if (_Mode_
& consume_header
)
4056 // __codecvt_utf16<char32_t, true>
4058 __codecvt_utf16
<char32_t
, true>::result
4059 __codecvt_utf16
<char32_t
, true>::do_out(state_type
&,
4060 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4061 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4063 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4064 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4065 const uint32_t* _frm_nxt
= _frm
;
4066 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4067 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4068 uint8_t* _to_nxt
= _to
;
4069 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4071 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4072 to_nxt
= to
+ (_to_nxt
- _to
);
4076 __codecvt_utf16
<char32_t
, true>::result
4077 __codecvt_utf16
<char32_t
, true>::do_in(state_type
&,
4078 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4079 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4081 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4082 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4083 const uint8_t* _frm_nxt
= _frm
;
4084 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4085 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4086 uint32_t* _to_nxt
= _to
;
4087 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4089 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4090 to_nxt
= to
+ (_to_nxt
- _to
);
4094 __codecvt_utf16
<char32_t
, true>::result
4095 __codecvt_utf16
<char32_t
, true>::do_unshift(state_type
&,
4096 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4103 __codecvt_utf16
<char32_t
, true>::do_encoding() const _NOEXCEPT
4109 __codecvt_utf16
<char32_t
, true>::do_always_noconv() const _NOEXCEPT
4115 __codecvt_utf16
<char32_t
, true>::do_length(state_type
&,
4116 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4118 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4119 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4120 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
4124 __codecvt_utf16
<char32_t
, true>::do_max_length() const _NOEXCEPT
4126 if (_Mode_
& consume_header
)
4131 // __codecvt_utf8_utf16<wchar_t>
4133 __codecvt_utf8_utf16
<wchar_t>::result
4134 __codecvt_utf8_utf16
<wchar_t>::do_out(state_type
&,
4135 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4136 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4138 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4139 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4140 const uint32_t* _frm_nxt
= _frm
;
4141 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4142 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4143 uint8_t* _to_nxt
= _to
;
4144 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4146 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4147 to_nxt
= to
+ (_to_nxt
- _to
);
4151 __codecvt_utf8_utf16
<wchar_t>::result
4152 __codecvt_utf8_utf16
<wchar_t>::do_in(state_type
&,
4153 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4154 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4156 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4157 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4158 const uint8_t* _frm_nxt
= _frm
;
4159 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4160 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4161 uint32_t* _to_nxt
= _to
;
4162 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4164 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4165 to_nxt
= to
+ (_to_nxt
- _to
);
4169 __codecvt_utf8_utf16
<wchar_t>::result
4170 __codecvt_utf8_utf16
<wchar_t>::do_unshift(state_type
&,
4171 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4178 __codecvt_utf8_utf16
<wchar_t>::do_encoding() const _NOEXCEPT
4184 __codecvt_utf8_utf16
<wchar_t>::do_always_noconv() const _NOEXCEPT
4190 __codecvt_utf8_utf16
<wchar_t>::do_length(state_type
&,
4191 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4193 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4194 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4195 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
4199 __codecvt_utf8_utf16
<wchar_t>::do_max_length() const _NOEXCEPT
4201 if (_Mode_
& consume_header
)
4206 // __codecvt_utf8_utf16<char16_t>
4208 __codecvt_utf8_utf16
<char16_t
>::result
4209 __codecvt_utf8_utf16
<char16_t
>::do_out(state_type
&,
4210 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4211 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4213 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4214 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4215 const uint16_t* _frm_nxt
= _frm
;
4216 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4217 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4218 uint8_t* _to_nxt
= _to
;
4219 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4221 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4222 to_nxt
= to
+ (_to_nxt
- _to
);
4226 __codecvt_utf8_utf16
<char16_t
>::result
4227 __codecvt_utf8_utf16
<char16_t
>::do_in(state_type
&,
4228 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4229 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4231 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4232 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4233 const uint8_t* _frm_nxt
= _frm
;
4234 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4235 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4236 uint16_t* _to_nxt
= _to
;
4237 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4239 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4240 to_nxt
= to
+ (_to_nxt
- _to
);
4244 __codecvt_utf8_utf16
<char16_t
>::result
4245 __codecvt_utf8_utf16
<char16_t
>::do_unshift(state_type
&,
4246 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4253 __codecvt_utf8_utf16
<char16_t
>::do_encoding() const _NOEXCEPT
4259 __codecvt_utf8_utf16
<char16_t
>::do_always_noconv() const _NOEXCEPT
4265 __codecvt_utf8_utf16
<char16_t
>::do_length(state_type
&,
4266 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4268 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4269 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4270 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
4274 __codecvt_utf8_utf16
<char16_t
>::do_max_length() const _NOEXCEPT
4276 if (_Mode_
& consume_header
)
4281 // __codecvt_utf8_utf16<char32_t>
4283 __codecvt_utf8_utf16
<char32_t
>::result
4284 __codecvt_utf8_utf16
<char32_t
>::do_out(state_type
&,
4285 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4286 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4288 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4289 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4290 const uint32_t* _frm_nxt
= _frm
;
4291 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4292 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4293 uint8_t* _to_nxt
= _to
;
4294 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4296 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4297 to_nxt
= to
+ (_to_nxt
- _to
);
4301 __codecvt_utf8_utf16
<char32_t
>::result
4302 __codecvt_utf8_utf16
<char32_t
>::do_in(state_type
&,
4303 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4304 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4306 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4307 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4308 const uint8_t* _frm_nxt
= _frm
;
4309 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4310 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4311 uint32_t* _to_nxt
= _to
;
4312 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4314 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4315 to_nxt
= to
+ (_to_nxt
- _to
);
4319 __codecvt_utf8_utf16
<char32_t
>::result
4320 __codecvt_utf8_utf16
<char32_t
>::do_unshift(state_type
&,
4321 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4328 __codecvt_utf8_utf16
<char32_t
>::do_encoding() const _NOEXCEPT
4334 __codecvt_utf8_utf16
<char32_t
>::do_always_noconv() const _NOEXCEPT
4340 __codecvt_utf8_utf16
<char32_t
>::do_length(state_type
&,
4341 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4343 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4344 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4345 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, _Maxcode_
, _Mode_
);
4349 __codecvt_utf8_utf16
<char32_t
>::do_max_length() const _NOEXCEPT
4351 if (_Mode_
& consume_header
)
4356 // __narrow_to_utf8<16>
4358 __narrow_to_utf8
<16>::~__narrow_to_utf8()
4362 // __narrow_to_utf8<32>
4364 __narrow_to_utf8
<32>::~__narrow_to_utf8()
4368 // __widen_from_utf8<16>
4370 __widen_from_utf8
<16>::~__widen_from_utf8()
4374 // __widen_from_utf8<32>
4376 __widen_from_utf8
<32>::~__widen_from_utf8()
4381 static bool checked_string_to_wchar_convert(wchar_t& dest
,
4388 size_t ret
= __libcpp_mbrtowc_l(&out
, ptr
, strlen(ptr
), &mb
, loc
);
4389 if (ret
== static_cast<size_t>(-1) || ret
== static_cast<size_t>(-2)) {
4396 static bool checked_string_to_char_convert(char& dest
,
4405 // First convert the MBS into a wide char then attempt to narrow it using
4408 if (!checked_string_to_wchar_convert(wout
, ptr
, __loc
))
4411 if ((res
= __libcpp_wctob_l(wout
, __loc
)) != char_traits
<char>::eof()) {
4415 // FIXME: Work around specific multibyte sequences that we can reasonable
4416 // translate into a different single byte.
4418 case L
'\u202F': // narrow non-breaking space
4419 case L
'\u00A0': // non-breaking space
4425 _LIBCPP_UNREACHABLE();
4429 // numpunct<char> && numpunct<wchar_t>
4431 locale::id numpunct
< char >::id
;
4432 locale::id numpunct
<wchar_t>::id
;
4434 numpunct
<char>::numpunct(size_t refs
)
4435 : locale::facet(refs
),
4436 __decimal_point_('.'),
4437 __thousands_sep_(',')
4441 numpunct
<wchar_t>::numpunct(size_t refs
)
4442 : locale::facet(refs
),
4443 __decimal_point_(L
'.'),
4444 __thousands_sep_(L
',')
4448 numpunct
<char>::~numpunct()
4452 numpunct
<wchar_t>::~numpunct()
4456 char numpunct
< char >::do_decimal_point() const {return __decimal_point_
;}
4457 wchar_t numpunct
<wchar_t>::do_decimal_point() const {return __decimal_point_
;}
4459 char numpunct
< char >::do_thousands_sep() const {return __thousands_sep_
;}
4460 wchar_t numpunct
<wchar_t>::do_thousands_sep() const {return __thousands_sep_
;}
4462 string numpunct
< char >::do_grouping() const {return __grouping_
;}
4463 string numpunct
<wchar_t>::do_grouping() const {return __grouping_
;}
4465 string numpunct
< char >::do_truename() const {return "true";}
4466 wstring numpunct
<wchar_t>::do_truename() const {return L
"true";}
4468 string numpunct
< char >::do_falsename() const {return "false";}
4469 wstring numpunct
<wchar_t>::do_falsename() const {return L
"false";}
4471 // numpunct_byname<char>
4473 numpunct_byname
<char>::numpunct_byname(const char* nm
, size_t refs
)
4474 : numpunct
<char>(refs
)
4479 numpunct_byname
<char>::numpunct_byname(const string
& nm
, size_t refs
)
4480 : numpunct
<char>(refs
)
4485 numpunct_byname
<char>::~numpunct_byname()
4490 numpunct_byname
<char>::__init(const char* nm
)
4492 if (strcmp(nm
, "C") != 0)
4494 __libcpp_unique_locale
loc(nm
);
4496 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4497 " failed to construct for " + string(nm
));
4499 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4500 checked_string_to_char_convert(__decimal_point_
, lc
->decimal_point
,
4502 checked_string_to_char_convert(__thousands_sep_
, lc
->thousands_sep
,
4504 __grouping_
= lc
->grouping
;
4505 // localization for truename and falsename is not available
4509 // numpunct_byname<wchar_t>
4511 numpunct_byname
<wchar_t>::numpunct_byname(const char* nm
, size_t refs
)
4512 : numpunct
<wchar_t>(refs
)
4517 numpunct_byname
<wchar_t>::numpunct_byname(const string
& nm
, size_t refs
)
4518 : numpunct
<wchar_t>(refs
)
4523 numpunct_byname
<wchar_t>::~numpunct_byname()
4528 numpunct_byname
<wchar_t>::__init(const char* nm
)
4530 if (strcmp(nm
, "C") != 0)
4532 __libcpp_unique_locale
loc(nm
);
4534 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4535 " failed to construct for " + string(nm
));
4537 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4538 checked_string_to_wchar_convert(__decimal_point_
, lc
->decimal_point
,
4540 checked_string_to_wchar_convert(__thousands_sep_
, lc
->thousands_sep
,
4542 __grouping_
= lc
->grouping
;
4543 // localization for truename and falsename is not available
4550 __num_get_base::__get_base(ios_base
& iob
)
4552 ios_base::fmtflags __basefield
= iob
.flags() & ios_base::basefield
;
4553 if (__basefield
== ios_base::oct
)
4555 else if (__basefield
== ios_base::hex
)
4557 else if (__basefield
== 0)
4562 const char __num_get_base::__src
[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4565 __check_grouping(const string
& __grouping
, unsigned* __g
, unsigned* __g_end
,
4566 ios_base::iostate
& __err
)
4568 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4569 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4570 if (__grouping
.size() != 0 && __g_end
- __g
> 1)
4572 reverse(__g
, __g_end
);
4573 const char* __ig
= __grouping
.data();
4574 const char* __eg
= __ig
+ __grouping
.size();
4575 for (unsigned* __r
= __g
; __r
< __g_end
-1; ++__r
)
4577 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4579 if (static_cast<unsigned>(*__ig
) != *__r
)
4581 __err
= ios_base::failbit
;
4585 if (__eg
- __ig
> 1)
4588 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4590 if (static_cast<unsigned>(*__ig
) < __g_end
[-1] || __g_end
[-1] == 0)
4591 __err
= ios_base::failbit
;
4597 __num_put_base::__format_int(char* __fmtp
, const char* __len
, bool __signd
,
4598 ios_base::fmtflags __flags
)
4600 if (__flags
& ios_base::showpos
)
4602 if (__flags
& ios_base::showbase
)
4605 *__fmtp
++ = *__len
++;
4606 if ((__flags
& ios_base::basefield
) == ios_base::oct
)
4608 else if ((__flags
& ios_base::basefield
) == ios_base::hex
)
4610 if (__flags
& ios_base::uppercase
)
4622 __num_put_base::__format_float(char* __fmtp
, const char* __len
,
4623 ios_base::fmtflags __flags
)
4625 bool specify_precision
= true;
4626 if (__flags
& ios_base::showpos
)
4628 if (__flags
& ios_base::showpoint
)
4630 ios_base::fmtflags floatfield
= __flags
& ios_base::floatfield
;
4631 bool uppercase
= (__flags
& ios_base::uppercase
) != 0;
4632 if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4633 specify_precision
= false;
4640 *__fmtp
++ = *__len
++;
4641 if (floatfield
== ios_base::fixed
)
4648 else if (floatfield
== ios_base::scientific
)
4655 else if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4669 return specify_precision
;
4673 __num_put_base::__identify_padding(char* __nb
, char* __ne
,
4674 const ios_base
& __iob
)
4676 switch (__iob
.flags() & ios_base::adjustfield
)
4678 case ios_base::internal
:
4679 if (__nb
[0] == '-' || __nb
[0] == '+')
4681 if (__ne
- __nb
>= 2 && __nb
[0] == '0'
4682 && (__nb
[1] == 'x' || __nb
[1] == 'X'))
4685 case ios_base::left
:
4687 case ios_base::right
:
4700 static string weeks
[14];
4701 weeks
[0] = "Sunday";
4702 weeks
[1] = "Monday";
4703 weeks
[2] = "Tuesday";
4704 weeks
[3] = "Wednesday";
4705 weeks
[4] = "Thursday";
4706 weeks
[5] = "Friday";
4707 weeks
[6] = "Saturday";
4722 static wstring weeks
[14];
4723 weeks
[0] = L
"Sunday";
4724 weeks
[1] = L
"Monday";
4725 weeks
[2] = L
"Tuesday";
4726 weeks
[3] = L
"Wednesday";
4727 weeks
[4] = L
"Thursday";
4728 weeks
[5] = L
"Friday";
4729 weeks
[6] = L
"Saturday";
4742 __time_get_c_storage
<char>::__weeks() const
4744 static const string
* weeks
= init_weeks();
4750 __time_get_c_storage
<wchar_t>::__weeks() const
4752 static const wstring
* weeks
= init_wweeks();
4760 static string months
[24];
4761 months
[0] = "January";
4762 months
[1] = "February";
4763 months
[2] = "March";
4764 months
[3] = "April";
4768 months
[7] = "August";
4769 months
[8] = "September";
4770 months
[9] = "October";
4771 months
[10] = "November";
4772 months
[11] = "December";
4792 static wstring months
[24];
4793 months
[0] = L
"January";
4794 months
[1] = L
"February";
4795 months
[2] = L
"March";
4796 months
[3] = L
"April";
4798 months
[5] = L
"June";
4799 months
[6] = L
"July";
4800 months
[7] = L
"August";
4801 months
[8] = L
"September";
4802 months
[9] = L
"October";
4803 months
[10] = L
"November";
4804 months
[11] = L
"December";
4805 months
[12] = L
"Jan";
4806 months
[13] = L
"Feb";
4807 months
[14] = L
"Mar";
4808 months
[15] = L
"Apr";
4809 months
[16] = L
"May";
4810 months
[17] = L
"Jun";
4811 months
[18] = L
"Jul";
4812 months
[19] = L
"Aug";
4813 months
[20] = L
"Sep";
4814 months
[21] = L
"Oct";
4815 months
[22] = L
"Nov";
4816 months
[23] = L
"Dec";
4822 __time_get_c_storage
<char>::__months() const
4824 static const string
* months
= init_months();
4830 __time_get_c_storage
<wchar_t>::__months() const
4832 static const wstring
* months
= init_wmonths();
4840 static string am_pm
[2];
4850 static wstring am_pm
[2];
4858 __time_get_c_storage
<char>::__am_pm() const
4860 static const string
* am_pm
= init_am_pm();
4866 __time_get_c_storage
<wchar_t>::__am_pm() const
4868 static const wstring
* am_pm
= init_wam_pm();
4874 __time_get_c_storage
<char>::__x() const
4876 static string
s("%m/%d/%y");
4882 __time_get_c_storage
<wchar_t>::__x() const
4884 static wstring
s(L
"%m/%d/%y");
4890 __time_get_c_storage
<char>::__X() const
4892 static string
s("%H:%M:%S");
4898 __time_get_c_storage
<wchar_t>::__X() const
4900 static wstring
s(L
"%H:%M:%S");
4906 __time_get_c_storage
<char>::__c() const
4908 static string
s("%a %b %d %H:%M:%S %Y");
4914 __time_get_c_storage
<wchar_t>::__c() const
4916 static wstring
s(L
"%a %b %d %H:%M:%S %Y");
4922 __time_get_c_storage
<char>::__r() const
4924 static string
s("%I:%M:%S %p");
4930 __time_get_c_storage
<wchar_t>::__r() const
4932 static wstring
s(L
"%I:%M:%S %p");
4938 __time_get::__time_get(const char* nm
)
4939 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
4942 __throw_runtime_error("time_get_byname"
4943 " failed to construct for " + string(nm
));
4946 __time_get::__time_get(const string
& nm
)
4947 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
4950 __throw_runtime_error("time_get_byname"
4951 " failed to construct for " + nm
);
4954 __time_get::~__time_get()
4958 #if defined(__clang__)
4959 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4961 #if defined(__GNUG__)
4962 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4967 __time_get_storage
<char>::__analyze(char fmt
, const ctype
<char>& ct
)
4983 size_t n
= strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
4989 if (ct
.is(ctype_base::space
, *bb
))
4991 result
.push_back(' ');
4992 for (++bb
; bb
!= be
&& ct
.is(ctype_base::space
, *bb
); ++bb
)
4997 ios_base::iostate err
= ios_base::goodbit
;
4998 ptrdiff_t i
= __scan_keyword(w
, be
, this->__weeks_
, this->__weeks_
+14,
5003 result
.push_back('%');
5005 result
.push_back('A');
5007 result
.push_back('a');
5012 i
= __scan_keyword(w
, be
, this->__months_
, this->__months_
+24,
5017 result
.push_back('%');
5019 result
.push_back('B');
5021 result
.push_back('b');
5022 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5023 result
.back() = 'm';
5027 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5030 i
= __scan_keyword(w
, be
, this->__am_pm_
, this->__am_pm_
+2,
5031 ct
, err
, false) - this->__am_pm_
;
5034 result
.push_back('%');
5035 result
.push_back('p');
5041 if (ct
.is(ctype_base::digit
, *bb
))
5043 switch(__get_up_to_n_digits(bb
, be
, err
, ct
, 4))
5046 result
.push_back('%');
5047 result
.push_back('w');
5050 result
.push_back('%');
5051 result
.push_back('u');
5054 result
.push_back('%');
5055 result
.push_back('I');
5058 result
.push_back('%');
5059 result
.push_back('m');
5062 result
.push_back('%');
5063 result
.push_back('H');
5066 result
.push_back('%');
5067 result
.push_back('d');
5070 result
.push_back('%');
5071 result
.push_back('M');
5074 result
.push_back('%');
5075 result
.push_back('S');
5078 result
.push_back('%');
5079 result
.push_back('y');
5082 result
.push_back('%');
5083 result
.push_back('j');
5086 result
.push_back('%');
5087 result
.push_back('Y');
5090 for (; w
!= bb
; ++w
)
5091 result
.push_back(*w
);
5098 result
.push_back('%');
5099 result
.push_back('%');
5103 result
.push_back(*bb
);
5109 #if defined(__clang__)
5110 #pragma clang diagnostic ignored "-Wmissing-braces"
5115 __time_get_storage
<wchar_t>::__analyze(char fmt
, const ctype
<wchar_t>& ct
)
5131 strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5133 wchar_t* wbb
= wbuf
;
5135 const char* bb
= buf
;
5136 size_t j
= __libcpp_mbsrtowcs_l( wbb
, &bb
, countof(wbuf
), &mb
, __loc_
);
5137 if (j
== size_t(-1))
5138 __throw_runtime_error("locale not supported");
5139 wchar_t* wbe
= wbb
+ j
;
5143 if (ct
.is(ctype_base::space
, *wbb
))
5145 result
.push_back(L
' ');
5146 for (++wbb
; wbb
!= wbe
&& ct
.is(ctype_base::space
, *wbb
); ++wbb
)
5151 ios_base::iostate err
= ios_base::goodbit
;
5152 ptrdiff_t i
= __scan_keyword(w
, wbe
, this->__weeks_
, this->__weeks_
+14,
5157 result
.push_back(L
'%');
5159 result
.push_back(L
'A');
5161 result
.push_back(L
'a');
5166 i
= __scan_keyword(w
, wbe
, this->__months_
, this->__months_
+24,
5171 result
.push_back(L
'%');
5173 result
.push_back(L
'B');
5175 result
.push_back(L
'b');
5176 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5177 result
.back() = L
'm';
5181 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5184 i
= __scan_keyword(w
, wbe
, this->__am_pm_
, this->__am_pm_
+2,
5185 ct
, err
, false) - this->__am_pm_
;
5188 result
.push_back(L
'%');
5189 result
.push_back(L
'p');
5195 if (ct
.is(ctype_base::digit
, *wbb
))
5197 switch(__get_up_to_n_digits(wbb
, wbe
, err
, ct
, 4))
5200 result
.push_back(L
'%');
5201 result
.push_back(L
'w');
5204 result
.push_back(L
'%');
5205 result
.push_back(L
'u');
5208 result
.push_back(L
'%');
5209 result
.push_back(L
'I');
5212 result
.push_back(L
'%');
5213 result
.push_back(L
'm');
5216 result
.push_back(L
'%');
5217 result
.push_back(L
'H');
5220 result
.push_back(L
'%');
5221 result
.push_back(L
'd');
5224 result
.push_back(L
'%');
5225 result
.push_back(L
'M');
5228 result
.push_back(L
'%');
5229 result
.push_back(L
'S');
5232 result
.push_back(L
'%');
5233 result
.push_back(L
'y');
5236 result
.push_back(L
'%');
5237 result
.push_back(L
'j');
5240 result
.push_back(L
'%');
5241 result
.push_back(L
'Y');
5244 for (; w
!= wbb
; ++w
)
5245 result
.push_back(*w
);
5250 if (ct
.narrow(*wbb
, 0) == '%')
5252 result
.push_back(L
'%');
5253 result
.push_back(L
'%');
5257 result
.push_back(*wbb
);
5265 __time_get_storage
<char>::init(const ctype
<char>& ct
)
5270 for (int i
= 0; i
< 7; ++i
)
5273 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5275 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5276 __weeks_
[i
+7] = buf
;
5279 for (int i
= 0; i
< 12; ++i
)
5282 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5284 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5285 __months_
[i
+12] = buf
;
5289 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5292 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5294 __c_
= __analyze('c', ct
);
5295 __r_
= __analyze('r', ct
);
5296 __x_
= __analyze('x', ct
);
5297 __X_
= __analyze('X', ct
);
5302 __time_get_storage
<wchar_t>::init(const ctype
<wchar_t>& ct
)
5310 for (int i
= 0; i
< 7; ++i
)
5313 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5315 const char* bb
= buf
;
5316 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5317 if (j
== size_t(-1) || j
== 0)
5318 __throw_runtime_error("locale not supported");
5320 __weeks_
[i
].assign(wbuf
, wbe
);
5321 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5324 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5325 if (j
== size_t(-1) || j
== 0)
5326 __throw_runtime_error("locale not supported");
5328 __weeks_
[i
+7].assign(wbuf
, wbe
);
5331 for (int i
= 0; i
< 12; ++i
)
5334 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5336 const char* bb
= buf
;
5337 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5338 if (j
== size_t(-1) || j
== 0)
5339 __throw_runtime_error("locale not supported");
5341 __months_
[i
].assign(wbuf
, wbe
);
5342 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5345 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5346 if (j
== size_t(-1) || j
== 0)
5347 __throw_runtime_error("locale not supported");
5349 __months_
[i
+12].assign(wbuf
, wbe
);
5353 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5355 const char* bb
= buf
;
5356 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5357 if (j
== size_t(-1))
5358 __throw_runtime_error("locale not supported");
5360 __am_pm_
[0].assign(wbuf
, wbe
);
5362 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5365 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5366 if (j
== size_t(-1))
5367 __throw_runtime_error("locale not supported");
5369 __am_pm_
[1].assign(wbuf
, wbe
);
5370 __c_
= __analyze('c', ct
);
5371 __r_
= __analyze('r', ct
);
5372 __x_
= __analyze('x', ct
);
5373 __X_
= __analyze('X', ct
);
5376 template <class CharT
>
5377 struct _LIBCPP_HIDDEN __time_get_temp
5378 : public ctype_byname
<CharT
>
5380 explicit __time_get_temp(const char* nm
)
5381 : ctype_byname
<CharT
>(nm
, 1) {}
5382 explicit __time_get_temp(const string
& nm
)
5383 : ctype_byname
<CharT
>(nm
, 1) {}
5387 __time_get_storage
<char>::__time_get_storage(const char* __nm
)
5390 const __time_get_temp
<char> ct(__nm
);
5395 __time_get_storage
<char>::__time_get_storage(const string
& __nm
)
5398 const __time_get_temp
<char> ct(__nm
);
5403 __time_get_storage
<wchar_t>::__time_get_storage(const char* __nm
)
5406 const __time_get_temp
<wchar_t> ct(__nm
);
5411 __time_get_storage
<wchar_t>::__time_get_storage(const string
& __nm
)
5414 const __time_get_temp
<wchar_t> ct(__nm
);
5419 time_base::dateorder
5420 __time_get_storage
<char>::__do_date_order() const
5423 for (i
= 0; i
< __x_
.size(); ++i
)
5431 for (++i
; i
< __x_
.size(); ++i
)
5434 if (i
== __x_
.size())
5440 for (++i
; i
< __x_
.size(); ++i
)
5443 if (i
== __x_
.size())
5447 return time_base::ymd
;
5450 for (++i
; i
< __x_
.size(); ++i
)
5453 if (i
== __x_
.size())
5457 return time_base::ydm
;
5462 for (++i
; i
< __x_
.size(); ++i
)
5465 if (i
== __x_
.size())
5470 for (++i
; i
< __x_
.size(); ++i
)
5473 if (i
== __x_
.size())
5476 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5477 return time_base::mdy
;
5482 for (++i
; i
< __x_
.size(); ++i
)
5485 if (i
== __x_
.size())
5490 for (++i
; i
< __x_
.size(); ++i
)
5493 if (i
== __x_
.size())
5496 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5497 return time_base::dmy
;
5502 return time_base::no_order
;
5506 time_base::dateorder
5507 __time_get_storage
<wchar_t>::__do_date_order() const
5510 for (i
= 0; i
< __x_
.size(); ++i
)
5511 if (__x_
[i
] == L
'%')
5518 for (++i
; i
< __x_
.size(); ++i
)
5519 if (__x_
[i
] == L
'%')
5521 if (i
== __x_
.size())
5527 for (++i
; i
< __x_
.size(); ++i
)
5528 if (__x_
[i
] == L
'%')
5530 if (i
== __x_
.size())
5533 if (__x_
[i
] == L
'd')
5534 return time_base::ymd
;
5537 for (++i
; i
< __x_
.size(); ++i
)
5538 if (__x_
[i
] == L
'%')
5540 if (i
== __x_
.size())
5543 if (__x_
[i
] == L
'm')
5544 return time_base::ydm
;
5549 for (++i
; i
< __x_
.size(); ++i
)
5550 if (__x_
[i
] == L
'%')
5552 if (i
== __x_
.size())
5555 if (__x_
[i
] == L
'd')
5557 for (++i
; i
< __x_
.size(); ++i
)
5558 if (__x_
[i
] == L
'%')
5560 if (i
== __x_
.size())
5563 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5564 return time_base::mdy
;
5569 for (++i
; i
< __x_
.size(); ++i
)
5570 if (__x_
[i
] == L
'%')
5572 if (i
== __x_
.size())
5575 if (__x_
[i
] == L
'm')
5577 for (++i
; i
< __x_
.size(); ++i
)
5578 if (__x_
[i
] == L
'%')
5580 if (i
== __x_
.size())
5583 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5584 return time_base::dmy
;
5589 return time_base::no_order
;
5594 __time_put::__time_put(const char* nm
)
5595 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5598 __throw_runtime_error("time_put_byname"
5599 " failed to construct for " + string(nm
));
5602 __time_put::__time_put(const string
& nm
)
5603 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5606 __throw_runtime_error("time_put_byname"
5607 " failed to construct for " + nm
);
5610 __time_put::~__time_put()
5612 if (__loc_
!= _LIBCPP_GET_C_LOCALE
)
5617 __time_put::__do_put(char* __nb
, char*& __ne
, const tm
* __tm
,
5618 char __fmt
, char __mod
) const
5620 char fmt
[] = {'%', __fmt
, __mod
, 0};
5622 swap(fmt
[1], fmt
[2]);
5623 size_t n
= strftime_l(__nb
, countof(__nb
, __ne
), fmt
, __tm
, __loc_
);
5628 __time_put::__do_put(wchar_t* __wb
, wchar_t*& __we
, const tm
* __tm
,
5629 char __fmt
, char __mod
) const
5632 char* __ne
= __nar
+ 100;
5633 __do_put(__nar
, __ne
, __tm
, __fmt
, __mod
);
5635 const char* __nb
= __nar
;
5636 size_t j
= __libcpp_mbsrtowcs_l(__wb
, &__nb
, countof(__wb
, __we
), &mb
, __loc_
);
5637 if (j
== size_t(-1))
5638 __throw_runtime_error("locale not supported");
5642 // moneypunct_byname
5644 template <class charT
>
5647 __init_pat(money_base::pattern
& pat
, basic_string
<charT
>& __curr_symbol_
,
5648 bool intl
, char cs_precedes
, char sep_by_space
, char sign_posn
,
5651 const char sign
= static_cast<char>(money_base::sign
);
5652 const char space
= static_cast<char>(money_base::space
);
5653 const char none
= static_cast<char>(money_base::none
);
5654 const char symbol
= static_cast<char>(money_base::symbol
);
5655 const char value
= static_cast<char>(money_base::value
);
5656 const bool symbol_contains_sep
= intl
&& __curr_symbol_
.size() == 4;
5658 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5659 // function'. "Space between sign and symbol or value" means that
5660 // if the sign is adjacent to the symbol, there's a space between
5661 // them, and otherwise there's a space between the sign and value.
5663 // C11's localeconv specifies that the fourth character of an
5664 // international curr_symbol is used to separate the sign and
5665 // value when sep_by_space says to do so. C++ can't represent
5666 // that, so we just use a space. When sep_by_space says to
5667 // separate the symbol and value-or-sign with a space, we rearrange the
5668 // curr_symbol to put its spacing character on the correct side of
5671 // We also need to avoid adding an extra space between the sign
5672 // and value when the currency symbol is suppressed (by not
5673 // setting showbase). We match glibc's strfmon by interpreting
5674 // sep_by_space==1 as "omit the space when the currency symbol is
5677 // Users who want to get this right should use ICU instead.
5679 switch (cs_precedes
)
5681 case 0: // value before curr_symbol
5682 if (symbol_contains_sep
) {
5683 // Move the separator to before the symbol, to place it
5684 // between the value and symbol.
5685 rotate(__curr_symbol_
.begin(), __curr_symbol_
.begin() + 3,
5686 __curr_symbol_
.end());
5690 case 0: // Parentheses surround the quantity and currency symbol.
5691 pat
.field
[0] = sign
;
5692 pat
.field
[1] = value
;
5693 pat
.field
[2] = none
; // Any space appears in the symbol.
5694 pat
.field
[3] = symbol
;
5695 switch (sep_by_space
)
5697 case 0: // No space separates the currency symbol and value.
5698 // This case may have changed between C99 and C11;
5699 // assume the currency symbol matches the intention.
5700 case 2: // Space between sign and currency or value.
5701 // The "sign" is two parentheses, so no space here either.
5703 case 1: // Space between currency-and-sign or currency and value.
5704 if (!symbol_contains_sep
) {
5705 // We insert the space into the symbol instead of
5706 // setting pat.field[2]=space so that when
5707 // showbase is not set, the space goes away too.
5708 __curr_symbol_
.insert(0, 1, space_char
);
5715 case 1: // The sign string precedes the quantity and currency symbol.
5716 pat
.field
[0] = sign
;
5717 pat
.field
[3] = symbol
;
5718 switch (sep_by_space
)
5720 case 0: // No space separates the currency symbol and value.
5721 pat
.field
[1] = value
;
5722 pat
.field
[2] = none
;
5724 case 1: // Space between currency-and-sign or currency and value.
5725 pat
.field
[1] = value
;
5726 pat
.field
[2] = none
;
5727 if (!symbol_contains_sep
) {
5728 // We insert the space into the symbol instead of
5729 // setting pat.field[2]=space so that when
5730 // showbase is not set, the space goes away too.
5731 __curr_symbol_
.insert(0, 1, space_char
);
5734 case 2: // Space between sign and currency or value.
5735 pat
.field
[1] = space
;
5736 pat
.field
[2] = value
;
5737 if (symbol_contains_sep
) {
5738 // Remove the separator from the symbol, since it
5739 // has already appeared after the sign.
5740 __curr_symbol_
.erase(__curr_symbol_
.begin());
5747 case 2: // The sign string succeeds the quantity and currency symbol.
5748 pat
.field
[0] = value
;
5749 pat
.field
[3] = sign
;
5750 switch (sep_by_space
)
5752 case 0: // No space separates the currency symbol and value.
5753 pat
.field
[1] = none
;
5754 pat
.field
[2] = symbol
;
5756 case 1: // Space between currency-and-sign or currency and value.
5757 if (!symbol_contains_sep
) {
5758 // We insert the space into the symbol instead of
5759 // setting pat.field[1]=space so that when
5760 // showbase is not set, the space goes away too.
5761 __curr_symbol_
.insert(0, 1, space_char
);
5763 pat
.field
[1] = none
;
5764 pat
.field
[2] = symbol
;
5766 case 2: // Space between sign and currency or value.
5767 pat
.field
[1] = symbol
;
5768 pat
.field
[2] = space
;
5769 if (symbol_contains_sep
) {
5770 // Remove the separator from the symbol, since it
5771 // should not be removed if showbase is absent.
5772 __curr_symbol_
.erase(__curr_symbol_
.begin());
5779 case 3: // The sign string immediately precedes the currency symbol.
5780 pat
.field
[0] = value
;
5781 pat
.field
[3] = symbol
;
5782 switch (sep_by_space
)
5784 case 0: // No space separates the currency symbol and value.
5785 pat
.field
[1] = none
;
5786 pat
.field
[2] = sign
;
5788 case 1: // Space between currency-and-sign or currency and value.
5789 pat
.field
[1] = space
;
5790 pat
.field
[2] = sign
;
5791 if (symbol_contains_sep
) {
5792 // Remove the separator from the symbol, since it
5793 // has already appeared before the sign.
5794 __curr_symbol_
.erase(__curr_symbol_
.begin());
5797 case 2: // Space between sign and currency or value.
5798 pat
.field
[1] = sign
;
5799 pat
.field
[2] = none
;
5800 if (!symbol_contains_sep
) {
5801 // We insert the space into the symbol instead of
5802 // setting pat.field[2]=space so that when
5803 // showbase is not set, the space goes away too.
5804 __curr_symbol_
.insert(0, 1, space_char
);
5811 case 4: // The sign string immediately succeeds the currency symbol.
5812 pat
.field
[0] = value
;
5813 pat
.field
[3] = sign
;
5814 switch (sep_by_space
)
5816 case 0: // No space separates the currency symbol and value.
5817 pat
.field
[1] = none
;
5818 pat
.field
[2] = symbol
;
5820 case 1: // Space between currency-and-sign or currency and value.
5821 pat
.field
[1] = none
;
5822 pat
.field
[2] = symbol
;
5823 if (!symbol_contains_sep
) {
5824 // We insert the space into the symbol instead of
5825 // setting pat.field[1]=space so that when
5826 // showbase is not set, the space goes away too.
5827 __curr_symbol_
.insert(0, 1, space_char
);
5830 case 2: // Space between sign and currency or value.
5831 pat
.field
[1] = symbol
;
5832 pat
.field
[2] = space
;
5833 if (symbol_contains_sep
) {
5834 // Remove the separator from the symbol, since it
5835 // should not disappear when showbase is absent.
5836 __curr_symbol_
.erase(__curr_symbol_
.begin());
5847 case 1: // curr_symbol before value
5850 case 0: // Parentheses surround the quantity and currency symbol.
5851 pat
.field
[0] = sign
;
5852 pat
.field
[1] = symbol
;
5853 pat
.field
[2] = none
; // Any space appears in the symbol.
5854 pat
.field
[3] = value
;
5855 switch (sep_by_space
)
5857 case 0: // No space separates the currency symbol and value.
5858 // This case may have changed between C99 and C11;
5859 // assume the currency symbol matches the intention.
5860 case 2: // Space between sign and currency or value.
5861 // The "sign" is two parentheses, so no space here either.
5863 case 1: // Space between currency-and-sign or currency and value.
5864 if (!symbol_contains_sep
) {
5865 // We insert the space into the symbol instead of
5866 // setting pat.field[2]=space so that when
5867 // showbase is not set, the space goes away too.
5868 __curr_symbol_
.insert(0, 1, space_char
);
5875 case 1: // The sign string precedes the quantity and currency symbol.
5876 pat
.field
[0] = sign
;
5877 pat
.field
[3] = value
;
5878 switch (sep_by_space
)
5880 case 0: // No space separates the currency symbol and value.
5881 pat
.field
[1] = symbol
;
5882 pat
.field
[2] = none
;
5884 case 1: // Space between currency-and-sign or currency and value.
5885 pat
.field
[1] = symbol
;
5886 pat
.field
[2] = none
;
5887 if (!symbol_contains_sep
) {
5888 // We insert the space into the symbol instead of
5889 // setting pat.field[2]=space so that when
5890 // showbase is not set, the space goes away too.
5891 __curr_symbol_
.push_back(space_char
);
5894 case 2: // Space between sign and currency or value.
5895 pat
.field
[1] = space
;
5896 pat
.field
[2] = symbol
;
5897 if (symbol_contains_sep
) {
5898 // Remove the separator from the symbol, since it
5899 // has already appeared after the sign.
5900 __curr_symbol_
.pop_back();
5907 case 2: // The sign string succeeds the quantity and currency symbol.
5908 pat
.field
[0] = symbol
;
5909 pat
.field
[3] = sign
;
5910 switch (sep_by_space
)
5912 case 0: // No space separates the currency symbol and value.
5913 pat
.field
[1] = none
;
5914 pat
.field
[2] = value
;
5916 case 1: // Space between currency-and-sign or currency and value.
5917 pat
.field
[1] = none
;
5918 pat
.field
[2] = value
;
5919 if (!symbol_contains_sep
) {
5920 // We insert the space into the symbol instead of
5921 // setting pat.field[1]=space so that when
5922 // showbase is not set, the space goes away too.
5923 __curr_symbol_
.push_back(space_char
);
5926 case 2: // Space between sign and currency or value.
5927 pat
.field
[1] = value
;
5928 pat
.field
[2] = space
;
5929 if (symbol_contains_sep
) {
5930 // Remove the separator from the symbol, since it
5931 // will appear before the sign.
5932 __curr_symbol_
.pop_back();
5939 case 3: // The sign string immediately precedes the currency symbol.
5940 pat
.field
[0] = sign
;
5941 pat
.field
[3] = value
;
5942 switch (sep_by_space
)
5944 case 0: // No space separates the currency symbol and value.
5945 pat
.field
[1] = symbol
;
5946 pat
.field
[2] = none
;
5948 case 1: // Space between currency-and-sign or currency and value.
5949 pat
.field
[1] = symbol
;
5950 pat
.field
[2] = none
;
5951 if (!symbol_contains_sep
) {
5952 // We insert the space into the symbol instead of
5953 // setting pat.field[2]=space so that when
5954 // showbase is not set, the space goes away too.
5955 __curr_symbol_
.push_back(space_char
);
5958 case 2: // Space between sign and currency or value.
5959 pat
.field
[1] = space
;
5960 pat
.field
[2] = symbol
;
5961 if (symbol_contains_sep
) {
5962 // Remove the separator from the symbol, since it
5963 // has already appeared after the sign.
5964 __curr_symbol_
.pop_back();
5971 case 4: // The sign string immediately succeeds the currency symbol.
5972 pat
.field
[0] = symbol
;
5973 pat
.field
[3] = value
;
5974 switch (sep_by_space
)
5976 case 0: // No space separates the currency symbol and value.
5977 pat
.field
[1] = sign
;
5978 pat
.field
[2] = none
;
5980 case 1: // Space between currency-and-sign or currency and value.
5981 pat
.field
[1] = sign
;
5982 pat
.field
[2] = space
;
5983 if (symbol_contains_sep
) {
5984 // Remove the separator from the symbol, since it
5985 // should not disappear when showbase is absent.
5986 __curr_symbol_
.pop_back();
5989 case 2: // Space between sign and currency or value.
5990 pat
.field
[1] = none
;
5991 pat
.field
[2] = sign
;
5992 if (!symbol_contains_sep
) {
5993 // We insert the space into the symbol instead of
5994 // setting pat.field[1]=space so that when
5995 // showbase is not set, the space goes away too.
5996 __curr_symbol_
.push_back(space_char
);
6010 pat
.field
[0] = symbol
;
6011 pat
.field
[1] = sign
;
6012 pat
.field
[2] = none
;
6013 pat
.field
[3] = value
;
6018 moneypunct_byname
<char, false>::init(const char* nm
)
6020 typedef moneypunct
<char, false> base
;
6021 __libcpp_unique_locale
loc(nm
);
6023 __throw_runtime_error("moneypunct_byname"
6024 " failed to construct for " + string(nm
));
6026 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6027 if (!checked_string_to_char_convert(__decimal_point_
,
6028 lc
->mon_decimal_point
,
6030 __decimal_point_
= base::do_decimal_point();
6031 if (!checked_string_to_char_convert(__thousands_sep_
,
6032 lc
->mon_thousands_sep
,
6034 __thousands_sep_
= base::do_thousands_sep();
6036 __grouping_
= lc
->mon_grouping
;
6037 __curr_symbol_
= lc
->currency_symbol
;
6038 if (lc
->frac_digits
!= CHAR_MAX
)
6039 __frac_digits_
= lc
->frac_digits
;
6041 __frac_digits_
= base::do_frac_digits();
6042 if (lc
->p_sign_posn
== 0)
6043 __positive_sign_
= "()";
6045 __positive_sign_
= lc
->positive_sign
;
6046 if (lc
->n_sign_posn
== 0)
6047 __negative_sign_
= "()";
6049 __negative_sign_
= lc
->negative_sign
;
6050 // Assume the positive and negative formats will want spaces in
6051 // the same places in curr_symbol since there's no way to
6052 // represent anything else.
6053 string_type __dummy_curr_symbol
= __curr_symbol_
;
6054 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6055 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6056 __init_pat(__neg_format_
, __curr_symbol_
, false,
6057 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6062 moneypunct_byname
<char, true>::init(const char* nm
)
6064 typedef moneypunct
<char, true> base
;
6065 __libcpp_unique_locale
loc(nm
);
6067 __throw_runtime_error("moneypunct_byname"
6068 " failed to construct for " + string(nm
));
6070 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6071 if (!checked_string_to_char_convert(__decimal_point_
,
6072 lc
->mon_decimal_point
,
6074 __decimal_point_
= base::do_decimal_point();
6075 if (!checked_string_to_char_convert(__thousands_sep_
,
6076 lc
->mon_thousands_sep
,
6078 __thousands_sep_
= base::do_thousands_sep();
6079 __grouping_
= lc
->mon_grouping
;
6080 __curr_symbol_
= lc
->int_curr_symbol
;
6081 if (lc
->int_frac_digits
!= CHAR_MAX
)
6082 __frac_digits_
= lc
->int_frac_digits
;
6084 __frac_digits_
= base::do_frac_digits();
6085 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6086 if (lc
->p_sign_posn
== 0)
6087 #else // _LIBCPP_MSVCRT
6088 if (lc
->int_p_sign_posn
== 0)
6089 #endif // !_LIBCPP_MSVCRT
6090 __positive_sign_
= "()";
6092 __positive_sign_
= lc
->positive_sign
;
6093 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6094 if(lc
->n_sign_posn
== 0)
6095 #else // _LIBCPP_MSVCRT
6096 if (lc
->int_n_sign_posn
== 0)
6097 #endif // !_LIBCPP_MSVCRT
6098 __negative_sign_
= "()";
6100 __negative_sign_
= lc
->negative_sign
;
6101 // Assume the positive and negative formats will want spaces in
6102 // the same places in curr_symbol since there's no way to
6103 // represent anything else.
6104 string_type __dummy_curr_symbol
= __curr_symbol_
;
6105 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6106 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6107 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6108 __init_pat(__neg_format_
, __curr_symbol_
, true,
6109 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6110 #else // _LIBCPP_MSVCRT
6111 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6112 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6113 lc
->int_p_sign_posn
, ' ');
6114 __init_pat(__neg_format_
, __curr_symbol_
, true,
6115 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6116 lc
->int_n_sign_posn
, ' ');
6117 #endif // !_LIBCPP_MSVCRT
6122 moneypunct_byname
<wchar_t, false>::init(const char* nm
)
6124 typedef moneypunct
<wchar_t, false> base
;
6125 __libcpp_unique_locale
loc(nm
);
6127 __throw_runtime_error("moneypunct_byname"
6128 " failed to construct for " + string(nm
));
6129 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6130 if (!checked_string_to_wchar_convert(__decimal_point_
,
6131 lc
->mon_decimal_point
,
6133 __decimal_point_
= base::do_decimal_point();
6134 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6135 lc
->mon_thousands_sep
,
6137 __thousands_sep_
= base::do_thousands_sep();
6138 __grouping_
= lc
->mon_grouping
;
6141 const char* bb
= lc
->currency_symbol
;
6142 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6143 if (j
== size_t(-1))
6144 __throw_runtime_error("locale not supported");
6145 wchar_t* wbe
= wbuf
+ j
;
6146 __curr_symbol_
.assign(wbuf
, wbe
);
6147 if (lc
->frac_digits
!= CHAR_MAX
)
6148 __frac_digits_
= lc
->frac_digits
;
6150 __frac_digits_
= base::do_frac_digits();
6151 if (lc
->p_sign_posn
== 0)
6152 __positive_sign_
= L
"()";
6156 bb
= lc
->positive_sign
;
6157 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6158 if (j
== size_t(-1))
6159 __throw_runtime_error("locale not supported");
6161 __positive_sign_
.assign(wbuf
, wbe
);
6163 if (lc
->n_sign_posn
== 0)
6164 __negative_sign_
= L
"()";
6168 bb
= lc
->negative_sign
;
6169 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6170 if (j
== size_t(-1))
6171 __throw_runtime_error("locale not supported");
6173 __negative_sign_
.assign(wbuf
, wbe
);
6175 // Assume the positive and negative formats will want spaces in
6176 // the same places in curr_symbol since there's no way to
6177 // represent anything else.
6178 string_type __dummy_curr_symbol
= __curr_symbol_
;
6179 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6180 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6181 __init_pat(__neg_format_
, __curr_symbol_
, false,
6182 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6187 moneypunct_byname
<wchar_t, true>::init(const char* nm
)
6189 typedef moneypunct
<wchar_t, true> base
;
6190 __libcpp_unique_locale
loc(nm
);
6192 __throw_runtime_error("moneypunct_byname"
6193 " failed to construct for " + string(nm
));
6195 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6196 if (!checked_string_to_wchar_convert(__decimal_point_
,
6197 lc
->mon_decimal_point
,
6199 __decimal_point_
= base::do_decimal_point();
6200 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6201 lc
->mon_thousands_sep
,
6203 __thousands_sep_
= base::do_thousands_sep();
6204 __grouping_
= lc
->mon_grouping
;
6207 const char* bb
= lc
->int_curr_symbol
;
6208 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6209 if (j
== size_t(-1))
6210 __throw_runtime_error("locale not supported");
6211 wchar_t* wbe
= wbuf
+ j
;
6212 __curr_symbol_
.assign(wbuf
, wbe
);
6213 if (lc
->int_frac_digits
!= CHAR_MAX
)
6214 __frac_digits_
= lc
->int_frac_digits
;
6216 __frac_digits_
= base::do_frac_digits();
6217 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6218 if (lc
->p_sign_posn
== 0)
6219 #else // _LIBCPP_MSVCRT
6220 if (lc
->int_p_sign_posn
== 0)
6221 #endif // !_LIBCPP_MSVCRT
6222 __positive_sign_
= L
"()";
6226 bb
= lc
->positive_sign
;
6227 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6228 if (j
== size_t(-1))
6229 __throw_runtime_error("locale not supported");
6231 __positive_sign_
.assign(wbuf
, wbe
);
6233 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6234 if (lc
->n_sign_posn
== 0)
6235 #else // _LIBCPP_MSVCRT
6236 if (lc
->int_n_sign_posn
== 0)
6237 #endif // !_LIBCPP_MSVCRT
6238 __negative_sign_
= L
"()";
6242 bb
= lc
->negative_sign
;
6243 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6244 if (j
== size_t(-1))
6245 __throw_runtime_error("locale not supported");
6247 __negative_sign_
.assign(wbuf
, wbe
);
6249 // Assume the positive and negative formats will want spaces in
6250 // the same places in curr_symbol since there's no way to
6251 // represent anything else.
6252 string_type __dummy_curr_symbol
= __curr_symbol_
;
6253 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6254 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6255 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6256 __init_pat(__neg_format_
, __curr_symbol_
, true,
6257 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6258 #else // _LIBCPP_MSVCRT
6259 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6260 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6261 lc
->int_p_sign_posn
, L
' ');
6262 __init_pat(__neg_format_
, __curr_symbol_
, true,
6263 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6264 lc
->int_n_sign_posn
, L
' ');
6265 #endif // !_LIBCPP_MSVCRT
6268 void __do_nothing(void*) {}
6270 void __throw_runtime_error(const char* msg
)
6272 #ifndef _LIBCPP_NO_EXCEPTIONS
6273 throw runtime_error(msg
);
6280 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<char>;
6281 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<wchar_t>;
6283 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<char>;
6284 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<wchar_t>;
6286 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<char>;
6287 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<wchar_t>;
6289 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<char>;
6290 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<wchar_t>;
6292 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<char>;
6293 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<wchar_t>;
6295 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<char>;
6296 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<wchar_t>;
6298 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<char>;
6299 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<wchar_t>;
6301 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<char>;
6302 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<wchar_t>;
6304 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<char>;
6305 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<wchar_t>;
6307 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, false>;
6308 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, true>;
6309 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, false>;
6310 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, true>;
6312 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, false>;
6313 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, true>;
6314 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, false>;
6315 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, true>;
6317 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<char>;
6318 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<wchar_t>;
6320 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<char>;
6321 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<wchar_t>;
6323 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<char>;
6324 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<wchar_t>;
6326 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<char>;
6327 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<wchar_t>;
6329 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<char>;
6330 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<wchar_t>;
6332 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<char>;
6333 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<wchar_t>;
6335 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char, char, mbstate_t>;
6336 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<wchar_t, char, mbstate_t>;
6337 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DEPRECATED_IN_CXX20 codecvt_byname
<char16_t
, char, mbstate_t>;
6338 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DEPRECATED_IN_CXX20 codecvt_byname
<char32_t
, char, mbstate_t>;
6339 #ifndef _LIBCPP_NO_HAS_CHAR8_T
6340 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char8_t
, mbstate_t>;
6341 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char8_t
, mbstate_t>;
6344 _LIBCPP_END_NAMESPACE_STD