1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include <__utility/unreachable.h>
18 #include <type_traits>
22 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
27 # include <sys/localedef.h> // for __lc_ctype_ptr
30 #if defined(_LIBCPP_MSVCRT)
31 # define _CTYPE_DISABLE_MACROS
34 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
35 # include "__support/win32/locale_win32.h"
36 #elif !defined(__BIONIC__) && !defined(__NuttX__)
37 # include <langinfo.h>
40 #include "include/atomic_support.h"
41 #include "include/sso_allocator.h"
43 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
44 // lots of noise in the build log, but no bugs that I know of.
45 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
48 #include <__undef_macros>
50 _LIBCPP_BEGIN_NAMESPACE_STD
52 struct __libcpp_unique_locale
{
53 __libcpp_unique_locale(const char* nm
) : __loc_(newlocale(LC_ALL_MASK
, nm
, 0)) {}
55 ~__libcpp_unique_locale() {
60 explicit operator bool() const { return __loc_
; }
62 locale_t
& get() { return __loc_
; }
66 __libcpp_unique_locale(__libcpp_unique_locale
const&);
67 __libcpp_unique_locale
& operator=(__libcpp_unique_locale
const&);
72 // In theory this could create a race condition. In practice
73 // the race condition is non-fatal since it will just create
74 // a little resource leak. Better approach would be appreciated.
75 static locale_t result
= newlocale(LC_ALL_MASK
, "C", 0);
78 #endif // __cloc_defined
84 void operator()(locale::facet
* p
) {p
->__release_shared();}
87 template <class T
, class ...Args
>
90 static typename aligned_storage
<sizeof(T
)>::type buf
;
91 auto *obj
= ::new (&buf
) T(args
...);
95 template <typename T
, size_t N
>
99 countof(const T (&)[N
])
104 template <typename T
>
108 countof(const T
* const begin
, const T
* const end
)
110 return static_cast<size_t>(end
- begin
);
113 _LIBCPP_NORETURN
static void __throw_runtime_error(const string
&msg
)
115 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
116 throw runtime_error(msg
);
125 const locale::category
locale::none
;
126 const locale::category
locale::collate
;
127 const locale::category
locale::ctype
;
128 const locale::category
locale::monetary
;
129 const locale::category
locale::numeric
;
130 const locale::category
locale::time
;
131 const locale::category
locale::messages
;
132 const locale::category
locale::all
;
134 class _LIBCPP_HIDDEN
locale::__imp
138 vector
<facet
*, __sso_allocator
<facet
*, N
> > facets_
;
141 explicit __imp(size_t refs
= 0);
142 explicit __imp(const string
& name
, size_t refs
= 0);
144 __imp(const __imp
&, const string
&, locale::category c
);
145 __imp(const __imp
& other
, const __imp
& one
, locale::category c
);
146 __imp(const __imp
&, facet
* f
, long id
);
149 const string
& name() const {return name_
;}
150 bool has_facet(long id
) const
151 {return static_cast<size_t>(id
) < facets_
.size() && facets_
[static_cast<size_t>(id
)];}
152 const locale::facet
* use_facet(long id
) const;
154 static const locale
& make_classic();
155 static locale
& make_global();
157 void install(facet
* f
, long id
);
158 template <class F
> void install(F
* f
) {install(f
, f
->id
.__get());}
159 template <class F
> void install_from(const __imp
& other
);
162 locale::__imp::__imp(size_t refs
)
168 install(&make
<_VSTD::collate
<char> >(1u));
169 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
170 install(&make
<_VSTD::collate
<wchar_t> >(1u));
172 install(&make
<_VSTD::ctype
<char> >(nullptr, false, 1u));
173 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
174 install(&make
<_VSTD::ctype
<wchar_t> >(1u));
176 install(&make
<codecvt
<char, char, mbstate_t> >(1u));
177 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
178 install(&make
<codecvt
<wchar_t, char, mbstate_t> >(1u));
180 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
181 install(&make
<codecvt
<char16_t
, char, mbstate_t> >(1u));
182 install(&make
<codecvt
<char32_t
, char, mbstate_t> >(1u));
183 _LIBCPP_SUPPRESS_DEPRECATED_POP
184 #ifndef _LIBCPP_HAS_NO_CHAR8_T
185 install(&make
<codecvt
<char16_t
, char8_t
, mbstate_t> >(1u));
186 install(&make
<codecvt
<char32_t
, char8_t
, mbstate_t> >(1u));
188 install(&make
<numpunct
<char> >(1u));
189 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
190 install(&make
<numpunct
<wchar_t> >(1u));
192 install(&make
<num_get
<char> >(1u));
193 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
194 install(&make
<num_get
<wchar_t> >(1u));
196 install(&make
<num_put
<char> >(1u));
197 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
198 install(&make
<num_put
<wchar_t> >(1u));
200 install(&make
<moneypunct
<char, false> >(1u));
201 install(&make
<moneypunct
<char, true> >(1u));
202 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
203 install(&make
<moneypunct
<wchar_t, false> >(1u));
204 install(&make
<moneypunct
<wchar_t, true> >(1u));
206 install(&make
<money_get
<char> >(1u));
207 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
208 install(&make
<money_get
<wchar_t> >(1u));
210 install(&make
<money_put
<char> >(1u));
211 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
212 install(&make
<money_put
<wchar_t> >(1u));
214 install(&make
<time_get
<char> >(1u));
215 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
216 install(&make
<time_get
<wchar_t> >(1u));
218 install(&make
<time_put
<char> >(1u));
219 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
220 install(&make
<time_put
<wchar_t> >(1u));
222 install(&make
<_VSTD::messages
<char> >(1u));
223 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
224 install(&make
<_VSTD::messages
<wchar_t> >(1u));
228 locale::__imp::__imp(const string
& name
, size_t refs
)
233 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
236 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
237 facets_
= locale::classic().__locale_
->facets_
;
238 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
240 facets_
[i
]->__add_shared();
241 install(new collate_byname
<char>(name_
));
242 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
243 install(new collate_byname
<wchar_t>(name_
));
245 install(new ctype_byname
<char>(name_
));
246 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
247 install(new ctype_byname
<wchar_t>(name_
));
249 install(new codecvt_byname
<char, char, mbstate_t>(name_
));
250 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
251 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name_
));
253 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
254 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name_
));
255 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name_
));
256 _LIBCPP_SUPPRESS_DEPRECATED_POP
257 #ifndef _LIBCPP_HAS_NO_CHAR8_T
258 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name_
));
259 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name_
));
261 install(new numpunct_byname
<char>(name_
));
262 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
263 install(new numpunct_byname
<wchar_t>(name_
));
265 install(new moneypunct_byname
<char, false>(name_
));
266 install(new moneypunct_byname
<char, true>(name_
));
267 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
268 install(new moneypunct_byname
<wchar_t, false>(name_
));
269 install(new moneypunct_byname
<wchar_t, true>(name_
));
271 install(new time_get_byname
<char>(name_
));
272 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
273 install(new time_get_byname
<wchar_t>(name_
));
275 install(new time_put_byname
<char>(name_
));
276 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
277 install(new time_put_byname
<wchar_t>(name_
));
279 install(new messages_byname
<char>(name_
));
280 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
281 install(new messages_byname
<wchar_t>(name_
));
283 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
287 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
289 facets_
[i
]->__release_shared();
292 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
295 locale::__imp::__imp(const __imp
& other
)
296 : facets_(max
<size_t>(N
, other
.facets_
.size())),
299 facets_
= other
.facets_
;
300 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
302 facets_
[i
]->__add_shared();
305 locale::__imp::__imp(const __imp
& other
, const string
& name
, locale::category c
)
309 facets_
= other
.facets_
;
310 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
312 facets_
[i
]->__add_shared();
313 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
316 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
317 if (c
& locale::collate
)
319 install(new collate_byname
<char>(name
));
320 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
321 install(new collate_byname
<wchar_t>(name
));
324 if (c
& locale::ctype
)
326 install(new ctype_byname
<char>(name
));
327 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
328 install(new ctype_byname
<wchar_t>(name
));
330 install(new codecvt_byname
<char, char, mbstate_t>(name
));
331 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
332 install(new codecvt_byname
<wchar_t, char, mbstate_t>(name
));
334 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
335 install(new codecvt_byname
<char16_t
, char, mbstate_t>(name
));
336 install(new codecvt_byname
<char32_t
, char, mbstate_t>(name
));
337 _LIBCPP_SUPPRESS_DEPRECATED_POP
338 #ifndef _LIBCPP_HAS_NO_CHAR8_T
339 install(new codecvt_byname
<char16_t
, char8_t
, mbstate_t>(name
));
340 install(new codecvt_byname
<char32_t
, char8_t
, mbstate_t>(name
));
343 if (c
& locale::monetary
)
345 install(new moneypunct_byname
<char, false>(name
));
346 install(new moneypunct_byname
<char, true>(name
));
347 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
348 install(new moneypunct_byname
<wchar_t, false>(name
));
349 install(new moneypunct_byname
<wchar_t, true>(name
));
352 if (c
& locale::numeric
)
354 install(new numpunct_byname
<char>(name
));
355 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
356 install(new numpunct_byname
<wchar_t>(name
));
359 if (c
& locale::time
)
361 install(new time_get_byname
<char>(name
));
362 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
363 install(new time_get_byname
<wchar_t>(name
));
365 install(new time_put_byname
<char>(name
));
366 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
367 install(new time_put_byname
<wchar_t>(name
));
370 if (c
& locale::messages
)
372 install(new messages_byname
<char>(name
));
373 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
374 install(new messages_byname
<wchar_t>(name
));
377 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
381 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
383 facets_
[i
]->__release_shared();
386 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
392 locale::__imp::install_from(const locale::__imp
& one
)
394 long id
= F::id
.__get();
395 install(const_cast<F
*>(static_cast<const F
*>(one
.use_facet(id
))), id
);
398 locale::__imp::__imp(const __imp
& other
, const __imp
& one
, locale::category c
)
402 facets_
= other
.facets_
;
403 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
405 facets_
[i
]->__add_shared();
406 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
409 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
410 if (c
& locale::collate
)
412 install_from
<_VSTD::collate
<char> >(one
);
413 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
414 install_from
<_VSTD::collate
<wchar_t> >(one
);
417 if (c
& locale::ctype
)
419 install_from
<_VSTD::ctype
<char> >(one
);
420 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
421 install_from
<_VSTD::ctype
<wchar_t> >(one
);
423 install_from
<_VSTD::codecvt
<char, char, mbstate_t> >(one
);
424 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
425 install_from
<_VSTD::codecvt
<char16_t
, char, mbstate_t> >(one
);
426 install_from
<_VSTD::codecvt
<char32_t
, char, mbstate_t> >(one
);
427 _LIBCPP_SUPPRESS_DEPRECATED_POP
428 #ifndef _LIBCPP_HAS_NO_CHAR8_T
429 install_from
<_VSTD::codecvt
<char16_t
, char8_t
, mbstate_t> >(one
);
430 install_from
<_VSTD::codecvt
<char32_t
, char8_t
, mbstate_t> >(one
);
432 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
433 install_from
<_VSTD::codecvt
<wchar_t, char, mbstate_t> >(one
);
436 if (c
& locale::monetary
)
438 install_from
<moneypunct
<char, false> >(one
);
439 install_from
<moneypunct
<char, true> >(one
);
440 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
441 install_from
<moneypunct
<wchar_t, false> >(one
);
442 install_from
<moneypunct
<wchar_t, true> >(one
);
444 install_from
<money_get
<char> >(one
);
445 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
446 install_from
<money_get
<wchar_t> >(one
);
448 install_from
<money_put
<char> >(one
);
449 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
450 install_from
<money_put
<wchar_t> >(one
);
453 if (c
& locale::numeric
)
455 install_from
<numpunct
<char> >(one
);
456 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
457 install_from
<numpunct
<wchar_t> >(one
);
459 install_from
<num_get
<char> >(one
);
460 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461 install_from
<num_get
<wchar_t> >(one
);
463 install_from
<num_put
<char> >(one
);
464 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
465 install_from
<num_put
<wchar_t> >(one
);
468 if (c
& locale::time
)
470 install_from
<time_get
<char> >(one
);
471 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
472 install_from
<time_get
<wchar_t> >(one
);
474 install_from
<time_put
<char> >(one
);
475 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
476 install_from
<time_put
<wchar_t> >(one
);
479 if (c
& locale::messages
)
481 install_from
<_VSTD::messages
<char> >(one
);
482 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
483 install_from
<_VSTD::messages
<wchar_t> >(one
);
486 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
490 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
492 facets_
[i
]->__release_shared();
495 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
498 locale::__imp::__imp(const __imp
& other
, facet
* f
, long id
)
499 : facets_(max
<size_t>(N
, other
.facets_
.size()+1)),
503 unique_ptr
<facet
, release
> hold(f
);
504 facets_
= other
.facets_
;
505 for (unsigned i
= 0; i
< other
.facets_
.size(); ++i
)
507 facets_
[i
]->__add_shared();
508 install(hold
.get(), id
);
511 locale::__imp::~__imp()
513 for (unsigned i
= 0; i
< facets_
.size(); ++i
)
515 facets_
[i
]->__release_shared();
519 locale::__imp::install(facet
* f
, long id
)
522 unique_ptr
<facet
, release
> hold(f
);
523 if (static_cast<size_t>(id
) >= facets_
.size())
524 facets_
.resize(static_cast<size_t>(id
+1));
525 if (facets_
[static_cast<size_t>(id
)])
526 facets_
[static_cast<size_t>(id
)]->__release_shared();
527 facets_
[static_cast<size_t>(id
)] = hold
.release();
531 locale::__imp::use_facet(long id
) const
535 return facets_
[static_cast<size_t>(id
)];
541 locale::__imp::make_classic()
543 // only one thread can get in here and it only gets in once
544 static aligned_storage
<sizeof(locale
)>::type buf
;
545 locale
* c
= reinterpret_cast<locale
*>(&buf
);
546 c
->__locale_
= &make
<__imp
>(1u);
553 static const locale
& c
= __imp::make_classic();
558 locale::__imp::make_global()
560 // only one thread can get in here and it only gets in once
561 static aligned_storage
<sizeof(locale
)>::type buf
;
562 auto *obj
= ::new (&buf
) locale(locale::classic());
569 static locale
& g
= __imp::make_global();
573 locale::locale() noexcept
574 : __locale_(__global().__locale_
)
576 __locale_
->__add_shared();
579 locale::locale(const locale
& l
) noexcept
580 : __locale_(l
.__locale_
)
582 __locale_
->__add_shared();
587 __locale_
->__release_shared();
591 locale::operator=(const locale
& other
) noexcept
593 other
.__locale_
->__add_shared();
594 __locale_
->__release_shared();
595 __locale_
= other
.__locale_
;
599 locale::locale(const char* name
)
600 : __locale_(name
? new __imp(name
)
601 : (__throw_runtime_error("locale constructed with null"), nullptr))
603 __locale_
->__add_shared();
606 locale::locale(const string
& name
)
607 : __locale_(new __imp(name
))
609 __locale_
->__add_shared();
612 locale::locale(const locale
& other
, const char* name
, category c
)
613 : __locale_(name
? new __imp(*other
.__locale_
, name
, c
)
614 : (__throw_runtime_error("locale constructed with null"), nullptr))
616 __locale_
->__add_shared();
619 locale::locale(const locale
& other
, const string
& name
, category c
)
620 : __locale_(new __imp(*other
.__locale_
, name
, c
))
622 __locale_
->__add_shared();
625 locale::locale(const locale
& other
, const locale
& one
, category c
)
626 : __locale_(new __imp(*other
.__locale_
, *one
.__locale_
, c
))
628 __locale_
->__add_shared();
634 return __locale_
->name();
638 locale::__install_ctor(const locale
& other
, facet
* f
, long id
)
641 __locale_
= new __imp(*other
.__locale_
, f
, id
);
643 __locale_
= other
.__locale_
;
644 __locale_
->__add_shared();
648 locale::global(const locale
& loc
)
650 locale
& g
= __global();
654 setlocale(LC_ALL
, g
.name().c_str());
659 locale::has_facet(id
& x
) const
661 return __locale_
->has_facet(x
.__get());
665 locale::use_facet(id
& x
) const
667 return __locale_
->use_facet(x
.__get());
671 locale::operator==(const locale
& y
) const
673 return (__locale_
== y
.__locale_
)
674 || (__locale_
->name() != "*" && __locale_
->name() == y
.__locale_
->name());
679 locale::facet::~facet()
684 locale::facet::__on_zero_shared() noexcept
691 int32_t locale::id::__next_id
= 0;
699 void (locale::id::* pmf_
)();
701 __fake_bind(void (locale::id::* pmf
)(), locale::id
* id
)
702 : id_(id
), pmf_(pmf
) {}
704 void operator()() const
715 call_once(__flag_
, __fake_bind(&locale::id::__init
, this));
722 __id_
= __libcpp_atomic_add(&__next_id
, 1);
725 // template <> class collate_byname<char>
727 collate_byname
<char>::collate_byname(const char* n
, size_t refs
)
728 : collate
<char>(refs
),
729 __l_(newlocale(LC_ALL_MASK
, n
, 0))
732 __throw_runtime_error("collate_byname<char>::collate_byname"
733 " failed to construct for " + string(n
));
736 collate_byname
<char>::collate_byname(const string
& name
, size_t refs
)
737 : collate
<char>(refs
),
738 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
741 __throw_runtime_error("collate_byname<char>::collate_byname"
742 " failed to construct for " + name
);
745 collate_byname
<char>::~collate_byname()
751 collate_byname
<char>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
752 const char_type
* __lo2
, const char_type
* __hi2
) const
754 string_type
lhs(__lo1
, __hi1
);
755 string_type
rhs(__lo2
, __hi2
);
756 int r
= strcoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
764 collate_byname
<char>::string_type
765 collate_byname
<char>::do_transform(const char_type
* lo
, const char_type
* hi
) const
767 const string_type
in(lo
, hi
);
768 string_type
out(strxfrm_l(0, in
.c_str(), 0, __l_
), char());
769 strxfrm_l(const_cast<char*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
773 // template <> class collate_byname<wchar_t>
775 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
776 collate_byname
<wchar_t>::collate_byname(const char* n
, size_t refs
)
777 : collate
<wchar_t>(refs
),
778 __l_(newlocale(LC_ALL_MASK
, n
, 0))
781 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
782 " failed to construct for " + string(n
));
785 collate_byname
<wchar_t>::collate_byname(const string
& name
, size_t refs
)
786 : collate
<wchar_t>(refs
),
787 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
790 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
791 " failed to construct for " + name
);
794 collate_byname
<wchar_t>::~collate_byname()
800 collate_byname
<wchar_t>::do_compare(const char_type
* __lo1
, const char_type
* __hi1
,
801 const char_type
* __lo2
, const char_type
* __hi2
) const
803 string_type
lhs(__lo1
, __hi1
);
804 string_type
rhs(__lo2
, __hi2
);
805 int r
= wcscoll_l(lhs
.c_str(), rhs
.c_str(), __l_
);
813 collate_byname
<wchar_t>::string_type
814 collate_byname
<wchar_t>::do_transform(const char_type
* lo
, const char_type
* hi
) const
816 const string_type
in(lo
, hi
);
817 string_type
out(wcsxfrm_l(0, in
.c_str(), 0, __l_
), wchar_t());
818 wcsxfrm_l(const_cast<wchar_t*>(out
.c_str()), in
.c_str(), out
.size()+1, __l_
);
821 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
823 const ctype_base::mask
ctype_base::space
;
824 const ctype_base::mask
ctype_base::print
;
825 const ctype_base::mask
ctype_base::cntrl
;
826 const ctype_base::mask
ctype_base::upper
;
827 const ctype_base::mask
ctype_base::lower
;
828 const ctype_base::mask
ctype_base::alpha
;
829 const ctype_base::mask
ctype_base::digit
;
830 const ctype_base::mask
ctype_base::punct
;
831 const ctype_base::mask
ctype_base::xdigit
;
832 const ctype_base::mask
ctype_base::blank
;
833 const ctype_base::mask
ctype_base::alnum
;
834 const ctype_base::mask
ctype_base::graph
;
836 // template <> class ctype<wchar_t>;
838 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
839 locale::id ctype
<wchar_t>::id
;
841 ctype
<wchar_t>::~ctype()
846 ctype
<wchar_t>::do_is(mask m
, char_type c
) const
848 return isascii(c
) ? (ctype
<char>::classic_table()[c
] & m
) != 0 : false;
852 ctype
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
854 for (; low
!= high
; ++low
, ++vec
)
855 *vec
= static_cast<mask
>(isascii(*low
) ?
856 ctype
<char>::classic_table()[*low
] : 0);
861 ctype
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
863 for (; low
!= high
; ++low
)
864 if (isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
))
870 ctype
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
872 for (; low
!= high
; ++low
)
873 if (!(isascii(*low
) && (ctype
<char>::classic_table()[*low
] & m
)))
879 ctype
<wchar_t>::do_toupper(char_type c
) const
881 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
882 return isascii(c
) ? _DefaultRuneLocale
.__mapupper
[c
] : c
;
883 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
884 defined(__NetBSD__) || defined(__MVS__)
885 return isascii(c
) ? ctype
<char>::__classic_upper_table()[c
] : c
;
887 return (isascii(c
) && iswlower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'a'+L
'A' : c
;
892 ctype
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
894 for (; low
!= high
; ++low
)
895 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
896 *low
= isascii(*low
) ? _DefaultRuneLocale
.__mapupper
[*low
] : *low
;
897 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
898 defined(__NetBSD__) || defined(__MVS__)
899 *low
= isascii(*low
) ? ctype
<char>::__classic_upper_table()[*low
]
902 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? (*low
-L
'a'+L
'A') : *low
;
908 ctype
<wchar_t>::do_tolower(char_type c
) const
910 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
911 return isascii(c
) ? _DefaultRuneLocale
.__maplower
[c
] : c
;
912 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
913 defined(__NetBSD__) || defined(__MVS__)
914 return isascii(c
) ? ctype
<char>::__classic_lower_table()[c
] : c
;
916 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-L
'A'+'a' : c
;
921 ctype
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
923 for (; low
!= high
; ++low
)
924 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
925 *low
= isascii(*low
) ? _DefaultRuneLocale
.__maplower
[*low
] : *low
;
926 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
927 defined(__NetBSD__) || defined(__MVS__)
928 *low
= isascii(*low
) ? ctype
<char>::__classic_lower_table()[*low
]
931 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-L
'A'+L
'a' : *low
;
937 ctype
<wchar_t>::do_widen(char c
) const
943 ctype
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
945 for (; low
!= high
; ++low
, ++dest
)
951 ctype
<wchar_t>::do_narrow(char_type c
, char dfault
) const
954 return static_cast<char>(c
);
959 ctype
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
961 for (; low
!= high
; ++low
, ++dest
)
963 *dest
= static_cast<char>(*low
);
968 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
970 // template <> class ctype<char>;
972 locale::id ctype
<char>::id
;
974 const size_t ctype
<char>::table_size
;
976 ctype
<char>::ctype(const mask
* tab
, bool del
, size_t refs
)
977 : locale::facet(refs
),
982 __tab_
= classic_table();
985 ctype
<char>::~ctype()
987 if (__tab_
&& __del_
)
992 ctype
<char>::do_toupper(char_type c
) const
994 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
996 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(c
)]) : c
;
997 #elif defined(__NetBSD__)
998 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]);
999 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1001 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c
)]) : c
;
1003 return (isascii(c
) && islower_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'a'+'A' : c
;
1008 ctype
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
1010 for (; low
!= high
; ++low
)
1011 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1012 *low
= isascii(*low
) ?
1013 static_cast<char>(_DefaultRuneLocale
.__mapupper
[static_cast<ptrdiff_t>(*low
)]) : *low
;
1014 #elif defined(__NetBSD__)
1015 *low
= static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low
)]);
1016 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1017 *low
= isascii(*low
) ?
1018 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low
)]) : *low
;
1020 *low
= (isascii(*low
) && islower_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'a'+'A' : *low
;
1026 ctype
<char>::do_tolower(char_type c
) const
1028 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1030 static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(c
)]) : c
;
1031 #elif defined(__NetBSD__)
1032 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c
)]);
1033 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1035 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c
)]) : c
;
1037 return (isascii(c
) && isupper_l(c
, _LIBCPP_GET_C_LOCALE
)) ? c
-'A'+'a' : c
;
1042 ctype
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1044 for (; low
!= high
; ++low
)
1045 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1046 *low
= isascii(*low
) ? static_cast<char>(_DefaultRuneLocale
.__maplower
[static_cast<ptrdiff_t>(*low
)]) : *low
;
1047 #elif defined(__NetBSD__)
1048 *low
= static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low
)]);
1049 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1050 *low
= isascii(*low
) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low
)]) : *low
;
1052 *low
= (isascii(*low
) && isupper_l(*low
, _LIBCPP_GET_C_LOCALE
)) ? *low
-'A'+'a' : *low
;
1058 ctype
<char>::do_widen(char c
) const
1064 ctype
<char>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1066 for (; low
!= high
; ++low
, ++dest
)
1072 ctype
<char>::do_narrow(char_type c
, char dfault
) const
1075 return static_cast<char>(c
);
1080 ctype
<char>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1082 for (; low
!= high
; ++low
, ++dest
)
1090 #if defined(__EMSCRIPTEN__)
1091 extern "C" const unsigned short ** __ctype_b_loc();
1092 extern "C" const int ** __ctype_tolower_loc();
1093 extern "C" const int ** __ctype_toupper_loc();
1096 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1097 const ctype
<char>::mask
*
1098 ctype
<char>::classic_table() noexcept
1100 static _LIBCPP_CONSTEXPR
const ctype
<char>::mask builtin_table
[table_size
] = {
1105 cntrl
, cntrl
| space
| blank
,
1106 cntrl
| space
, cntrl
| space
,
1107 cntrl
| space
, cntrl
| space
,
1117 space
| blank
| print
, punct
| print
,
1118 punct
| print
, punct
| print
,
1119 punct
| print
, punct
| print
,
1120 punct
| print
, punct
| print
,
1121 punct
| print
, punct
| print
,
1122 punct
| print
, punct
| print
,
1123 punct
| print
, punct
| print
,
1124 punct
| print
, punct
| print
,
1125 digit
| print
| xdigit
, digit
| print
| xdigit
,
1126 digit
| print
| xdigit
, digit
| print
| xdigit
,
1127 digit
| print
| xdigit
, digit
| print
| xdigit
,
1128 digit
| print
| xdigit
, digit
| print
| xdigit
,
1129 digit
| print
| xdigit
, digit
| print
| xdigit
,
1130 punct
| print
, punct
| print
,
1131 punct
| print
, punct
| print
,
1132 punct
| print
, punct
| print
,
1133 punct
| print
, upper
| xdigit
| print
| alpha
,
1134 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1135 upper
| xdigit
| print
| alpha
, upper
| xdigit
| print
| alpha
,
1136 upper
| xdigit
| print
| alpha
, upper
| print
| alpha
,
1137 upper
| print
| alpha
, upper
| print
| alpha
,
1138 upper
| print
| alpha
, upper
| print
| alpha
,
1139 upper
| print
| alpha
, upper
| print
| alpha
,
1140 upper
| print
| alpha
, upper
| print
| alpha
,
1141 upper
| print
| alpha
, upper
| print
| alpha
,
1142 upper
| print
| alpha
, upper
| print
| alpha
,
1143 upper
| print
| alpha
, upper
| print
| alpha
,
1144 upper
| print
| alpha
, upper
| print
| alpha
,
1145 upper
| print
| alpha
, upper
| print
| alpha
,
1146 upper
| print
| alpha
, punct
| print
,
1147 punct
| print
, punct
| print
,
1148 punct
| print
, punct
| print
,
1149 punct
| print
, lower
| xdigit
| print
| alpha
,
1150 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1151 lower
| xdigit
| print
| alpha
, lower
| xdigit
| print
| alpha
,
1152 lower
| xdigit
| print
| alpha
, lower
| print
| alpha
,
1153 lower
| print
| alpha
, lower
| print
| alpha
,
1154 lower
| print
| alpha
, lower
| print
| alpha
,
1155 lower
| print
| alpha
, lower
| print
| alpha
,
1156 lower
| print
| alpha
, lower
| print
| alpha
,
1157 lower
| print
| alpha
, lower
| print
| alpha
,
1158 lower
| print
| alpha
, lower
| print
| alpha
,
1159 lower
| print
| alpha
, lower
| print
| alpha
,
1160 lower
| print
| alpha
, lower
| print
| alpha
,
1161 lower
| print
| alpha
, lower
| print
| alpha
,
1162 lower
| print
| alpha
, punct
| print
,
1163 punct
| print
, punct
| print
,
1164 punct
| print
, cntrl
,
1165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1174 return builtin_table
;
1177 const ctype
<char>::mask
*
1178 ctype
<char>::classic_table() noexcept
1180 #if defined(__APPLE__) || defined(__FreeBSD__)
1181 return _DefaultRuneLocale
.__runetype
;
1182 #elif defined(__NetBSD__)
1183 return _C_ctype_tab_
+ 1;
1184 #elif defined(__GLIBC__)
1185 return _LIBCPP_GET_C_LOCALE
->__ctype_b
;
1186 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1187 return __pctype_func();
1188 #elif defined(__EMSCRIPTEN__)
1189 return *__ctype_b_loc();
1190 #elif defined(_NEWLIB_VERSION)
1191 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1194 return (const unsigned int *)__lc_ctype_ptr
->obj
->mask
;
1195 #elif defined(__MVS__)
1196 # if defined(__NATIVE_ASCII_F)
1197 return const_cast<const ctype
<char>::mask
*> (__OBJ_DATA(__lc_ctype_a
)->mask
);
1199 return const_cast<const ctype
<char>::mask
*> (__ctypec
);
1202 // Platform not supported: abort so the person doing the port knows what to
1204 # warning ctype<char>::classic_table() is not implemented
1205 printf("ctype<char>::classic_table() is not implemented\n");
1212 #if defined(__GLIBC__)
1214 ctype
<char>::__classic_lower_table() noexcept
1216 return _LIBCPP_GET_C_LOCALE
->__ctype_tolower
;
1220 ctype
<char>::__classic_upper_table() noexcept
1222 return _LIBCPP_GET_C_LOCALE
->__ctype_toupper
;
1224 #elif defined(__NetBSD__)
1226 ctype
<char>::__classic_lower_table() noexcept
1228 return _C_tolower_tab_
+ 1;
1232 ctype
<char>::__classic_upper_table() noexcept
1234 return _C_toupper_tab_
+ 1;
1237 #elif defined(__EMSCRIPTEN__)
1239 ctype
<char>::__classic_lower_table() noexcept
1241 return *__ctype_tolower_loc();
1245 ctype
<char>::__classic_upper_table() noexcept
1247 return *__ctype_toupper_loc();
1249 #elif defined(__MVS__)
1250 const unsigned short*
1251 ctype
<char>::__classic_lower_table() _NOEXCEPT
1253 # if defined(__NATIVE_ASCII_F)
1254 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->lower
);
1256 return const_cast<const unsigned short*>(__ctype
+ __TOLOWER_INDEX
);
1259 const unsigned short *
1260 ctype
<char>::__classic_upper_table() _NOEXCEPT
1262 # if defined(__NATIVE_ASCII_F)
1263 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a
)->upper
);
1265 return const_cast<const unsigned short*>(__ctype
+ __TOUPPER_INDEX
);
1268 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1270 // template <> class ctype_byname<char>
1272 ctype_byname
<char>::ctype_byname(const char* name
, size_t refs
)
1273 : ctype
<char>(0, false, refs
),
1274 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1277 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1278 " failed to construct for " + string(name
));
1281 ctype_byname
<char>::ctype_byname(const string
& name
, size_t refs
)
1282 : ctype
<char>(0, false, refs
),
1283 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1286 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1287 " failed to construct for " + name
);
1290 ctype_byname
<char>::~ctype_byname()
1296 ctype_byname
<char>::do_toupper(char_type c
) const
1298 return static_cast<char>(toupper_l(static_cast<unsigned char>(c
), __l_
));
1302 ctype_byname
<char>::do_toupper(char_type
* low
, const char_type
* high
) const
1304 for (; low
!= high
; ++low
)
1305 *low
= static_cast<char>(toupper_l(static_cast<unsigned char>(*low
), __l_
));
1310 ctype_byname
<char>::do_tolower(char_type c
) const
1312 return static_cast<char>(tolower_l(static_cast<unsigned char>(c
), __l_
));
1316 ctype_byname
<char>::do_tolower(char_type
* low
, const char_type
* high
) const
1318 for (; low
!= high
; ++low
)
1319 *low
= static_cast<char>(tolower_l(static_cast<unsigned char>(*low
), __l_
));
1323 // template <> class ctype_byname<wchar_t>
1325 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1326 ctype_byname
<wchar_t>::ctype_byname(const char* name
, size_t refs
)
1327 : ctype
<wchar_t>(refs
),
1328 __l_(newlocale(LC_ALL_MASK
, name
, 0))
1331 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1332 " failed to construct for " + string(name
));
1335 ctype_byname
<wchar_t>::ctype_byname(const string
& name
, size_t refs
)
1336 : ctype
<wchar_t>(refs
),
1337 __l_(newlocale(LC_ALL_MASK
, name
.c_str(), 0))
1340 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1341 " failed to construct for " + name
);
1344 ctype_byname
<wchar_t>::~ctype_byname()
1350 ctype_byname
<wchar_t>::do_is(mask m
, char_type c
) const
1352 #ifdef _LIBCPP_WCTYPE_IS_MASK
1353 return static_cast<bool>(iswctype_l(c
, m
, __l_
));
1355 bool result
= false;
1356 wint_t ch
= static_cast<wint_t>(c
);
1357 if ((m
& space
) == space
) result
|= (iswspace_l(ch
, __l_
) != 0);
1358 if ((m
& print
) == print
) result
|= (iswprint_l(ch
, __l_
) != 0);
1359 if ((m
& cntrl
) == cntrl
) result
|= (iswcntrl_l(ch
, __l_
) != 0);
1360 if ((m
& upper
) == upper
) result
|= (iswupper_l(ch
, __l_
) != 0);
1361 if ((m
& lower
) == lower
) result
|= (iswlower_l(ch
, __l_
) != 0);
1362 if ((m
& alpha
) == alpha
) result
|= (iswalpha_l(ch
, __l_
) != 0);
1363 if ((m
& digit
) == digit
) result
|= (iswdigit_l(ch
, __l_
) != 0);
1364 if ((m
& punct
) == punct
) result
|= (iswpunct_l(ch
, __l_
) != 0);
1365 if ((m
& xdigit
) == xdigit
) result
|= (iswxdigit_l(ch
, __l_
) != 0);
1366 if ((m
& blank
) == blank
) result
|= (iswblank_l(ch
, __l_
) != 0);
1372 ctype_byname
<wchar_t>::do_is(const char_type
* low
, const char_type
* high
, mask
* vec
) const
1374 for (; low
!= high
; ++low
, ++vec
)
1377 *vec
= static_cast<mask
>(ctype
<char>::classic_table()[*low
]);
1381 wint_t ch
= static_cast<wint_t>(*low
);
1382 if (iswspace_l(ch
, __l_
))
1384 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1385 if (iswprint_l(ch
, __l_
))
1388 if (iswcntrl_l(ch
, __l_
))
1390 if (iswupper_l(ch
, __l_
))
1392 if (iswlower_l(ch
, __l_
))
1394 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1395 if (iswalpha_l(ch
, __l_
))
1398 if (iswdigit_l(ch
, __l_
))
1400 if (iswpunct_l(ch
, __l_
))
1402 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1403 if (iswxdigit_l(ch
, __l_
))
1406 if (iswblank_l(ch
, __l_
))
1414 ctype_byname
<wchar_t>::do_scan_is(mask m
, const char_type
* low
, const char_type
* high
) const
1416 for (; low
!= high
; ++low
)
1418 #ifdef _LIBCPP_WCTYPE_IS_MASK
1419 if (iswctype_l(*low
, m
, __l_
))
1422 wint_t ch
= static_cast<wint_t>(*low
);
1423 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) break;
1424 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) break;
1425 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) break;
1426 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) break;
1427 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) break;
1428 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) break;
1429 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) break;
1430 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) break;
1431 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) break;
1432 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) break;
1439 ctype_byname
<wchar_t>::do_scan_not(mask m
, const char_type
* low
, const char_type
* high
) const
1441 for (; low
!= high
; ++low
)
1443 #ifdef _LIBCPP_WCTYPE_IS_MASK
1444 if (!iswctype_l(*low
, m
, __l_
))
1447 wint_t ch
= static_cast<wint_t>(*low
);
1448 if ((m
& space
) == space
&& iswspace_l(ch
, __l_
)) continue;
1449 if ((m
& print
) == print
&& iswprint_l(ch
, __l_
)) continue;
1450 if ((m
& cntrl
) == cntrl
&& iswcntrl_l(ch
, __l_
)) continue;
1451 if ((m
& upper
) == upper
&& iswupper_l(ch
, __l_
)) continue;
1452 if ((m
& lower
) == lower
&& iswlower_l(ch
, __l_
)) continue;
1453 if ((m
& alpha
) == alpha
&& iswalpha_l(ch
, __l_
)) continue;
1454 if ((m
& digit
) == digit
&& iswdigit_l(ch
, __l_
)) continue;
1455 if ((m
& punct
) == punct
&& iswpunct_l(ch
, __l_
)) continue;
1456 if ((m
& xdigit
) == xdigit
&& iswxdigit_l(ch
, __l_
)) continue;
1457 if ((m
& blank
) == blank
&& iswblank_l(ch
, __l_
)) continue;
1465 ctype_byname
<wchar_t>::do_toupper(char_type c
) const
1467 return towupper_l(c
, __l_
);
1471 ctype_byname
<wchar_t>::do_toupper(char_type
* low
, const char_type
* high
) const
1473 for (; low
!= high
; ++low
)
1474 *low
= towupper_l(*low
, __l_
);
1479 ctype_byname
<wchar_t>::do_tolower(char_type c
) const
1481 return towlower_l(c
, __l_
);
1485 ctype_byname
<wchar_t>::do_tolower(char_type
* low
, const char_type
* high
) const
1487 for (; low
!= high
; ++low
)
1488 *low
= towlower_l(*low
, __l_
);
1493 ctype_byname
<wchar_t>::do_widen(char c
) const
1495 return __libcpp_btowc_l(c
, __l_
);
1499 ctype_byname
<wchar_t>::do_widen(const char* low
, const char* high
, char_type
* dest
) const
1501 for (; low
!= high
; ++low
, ++dest
)
1502 *dest
= __libcpp_btowc_l(*low
, __l_
);
1507 ctype_byname
<wchar_t>::do_narrow(char_type c
, char dfault
) const
1509 int r
= __libcpp_wctob_l(c
, __l_
);
1510 return (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1514 ctype_byname
<wchar_t>::do_narrow(const char_type
* low
, const char_type
* high
, char dfault
, char* dest
) const
1516 for (; low
!= high
; ++low
, ++dest
)
1518 int r
= __libcpp_wctob_l(*low
, __l_
);
1519 *dest
= (r
!= EOF
) ? static_cast<char>(r
) : dfault
;
1523 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1525 // template <> class codecvt<char, char, mbstate_t>
1527 locale::id codecvt
<char, char, mbstate_t>::id
;
1529 codecvt
<char, char, mbstate_t>::~codecvt()
1533 codecvt
<char, char, mbstate_t>::result
1534 codecvt
<char, char, mbstate_t>::do_out(state_type
&,
1535 const intern_type
* frm
, const intern_type
*, const intern_type
*& frm_nxt
,
1536 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1543 codecvt
<char, char, mbstate_t>::result
1544 codecvt
<char, char, mbstate_t>::do_in(state_type
&,
1545 const extern_type
* frm
, const extern_type
*, const extern_type
*& frm_nxt
,
1546 intern_type
* to
, intern_type
*, intern_type
*& to_nxt
) const
1553 codecvt
<char, char, mbstate_t>::result
1554 codecvt
<char, char, mbstate_t>::do_unshift(state_type
&,
1555 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
1562 codecvt
<char, char, mbstate_t>::do_encoding() const noexcept
1568 codecvt
<char, char, mbstate_t>::do_always_noconv() const noexcept
1574 codecvt
<char, char, mbstate_t>::do_length(state_type
&,
1575 const extern_type
* frm
, const extern_type
* end
, size_t mx
) const
1577 return static_cast<int>(min
<size_t>(mx
, static_cast<size_t>(end
-frm
)));
1581 codecvt
<char, char, mbstate_t>::do_max_length() const noexcept
1586 // template <> class codecvt<wchar_t, char, mbstate_t>
1588 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1589 locale::id codecvt
<wchar_t, char, mbstate_t>::id
;
1591 codecvt
<wchar_t, char, mbstate_t>::codecvt(size_t refs
)
1592 : locale::facet(refs
),
1593 __l_(_LIBCPP_GET_C_LOCALE
)
1597 codecvt
<wchar_t, char, mbstate_t>::codecvt(const char* nm
, size_t refs
)
1598 : locale::facet(refs
),
1599 __l_(newlocale(LC_ALL_MASK
, nm
, 0))
1602 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1603 " failed to construct for " + string(nm
));
1606 codecvt
<wchar_t, char, mbstate_t>::~codecvt()
1608 if (__l_
!= _LIBCPP_GET_C_LOCALE
)
1612 codecvt
<wchar_t, char, mbstate_t>::result
1613 codecvt
<wchar_t, char, mbstate_t>::do_out(state_type
& st
,
1614 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
1615 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1617 // look for first internal null in frm
1618 const intern_type
* fend
= frm
;
1619 for (; fend
!= frm_end
; ++fend
)
1622 // loop over all null-terminated sequences in frm
1624 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1626 // save state in case it is needed to recover to_nxt on error
1627 mbstate_t save_state
= st
;
1628 size_t n
= __libcpp_wcsnrtombs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1629 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1630 if (n
== size_t(-1))
1632 // need to recover to_nxt
1633 for (to_nxt
= to
; frm
!= frm_nxt
; ++frm
)
1635 n
= __libcpp_wcrtomb_l(to_nxt
, *frm
, &save_state
, __l_
);
1636 if (n
== size_t(-1))
1646 if (to_nxt
== to_end
)
1648 if (fend
!= frm_end
) // set up next null terminated sequence
1650 // Try to write the terminating null
1651 extern_type tmp
[MB_LEN_MAX
];
1652 n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1653 if (n
== size_t(-1)) // on error
1655 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1657 for (extern_type
* p
= tmp
; n
; --n
) // write it
1660 // look for next null in frm
1661 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1666 return frm_nxt
== frm_end
? ok
: partial
;
1669 codecvt
<wchar_t, char, mbstate_t>::result
1670 codecvt
<wchar_t, char, mbstate_t>::do_in(state_type
& st
,
1671 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
1672 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
1674 // look for first internal null in frm
1675 const extern_type
* fend
= frm
;
1676 for (; fend
!= frm_end
; ++fend
)
1679 // loop over all null-terminated sequences in frm
1681 for (frm_nxt
= frm
; frm
!= frm_end
&& to
!= to_end
; frm
= frm_nxt
, to
= to_nxt
)
1683 // save state in case it is needed to recover to_nxt on error
1684 mbstate_t save_state
= st
;
1685 size_t n
= __libcpp_mbsnrtowcs_l(to
, &frm_nxt
, static_cast<size_t>(fend
-frm
),
1686 static_cast<size_t>(to_end
-to
), &st
, __l_
);
1687 if (n
== size_t(-1))
1689 // need to recover to_nxt
1690 for (to_nxt
= to
; frm
!= frm_nxt
; ++to_nxt
)
1692 n
= __libcpp_mbrtowc_l(to_nxt
, frm
, static_cast<size_t>(fend
-frm
),
1711 return frm_nxt
== frm_end
? ok
: partial
;
1713 if (n
== size_t(-1))
1716 if (to_nxt
== to_end
)
1718 if (fend
!= frm_end
) // set up next null terminated sequence
1720 // Try to write the terminating null
1721 n
= __libcpp_mbrtowc_l(to_nxt
, frm_nxt
, 1, &st
, __l_
);
1722 if (n
!= 0) // on error
1726 // look for next null in frm
1727 for (fend
= frm_nxt
; fend
!= frm_end
; ++fend
)
1732 return frm_nxt
== frm_end
? ok
: partial
;
1735 codecvt
<wchar_t, char, mbstate_t>::result
1736 codecvt
<wchar_t, char, mbstate_t>::do_unshift(state_type
& st
,
1737 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
1740 extern_type tmp
[MB_LEN_MAX
];
1741 size_t n
= __libcpp_wcrtomb_l(tmp
, intern_type(), &st
, __l_
);
1742 if (n
== size_t(-1) || n
== 0) // on error
1745 if (n
> static_cast<size_t>(to_end
-to_nxt
)) // is there room?
1747 for (extern_type
* p
= tmp
; n
; --n
) // write it
1753 codecvt
<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1755 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX
, __l_
) != 0)
1758 // stateless encoding
1759 if (__l_
== 0 || __libcpp_mb_cur_max_l(__l_
) == 1) // there are no known constant length encodings
1760 return 1; // which take more than 1 char to form a wchar_t
1765 codecvt
<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1771 codecvt
<wchar_t, char, mbstate_t>::do_length(state_type
& st
,
1772 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
1775 for (size_t nwchar_t
= 0; nwchar_t
< mx
&& frm
!= frm_end
; ++nwchar_t
)
1777 size_t n
= __libcpp_mbrlen_l(frm
, static_cast<size_t>(frm_end
-frm
), &st
, __l_
);
1797 codecvt
<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1799 return __l_
== 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_
));
1801 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1804 // UTF-32 UTF-16 UTF-8 # of code points
1805 // first second first second third fourth
1806 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1807 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1808 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1809 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1810 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1811 // 00D800 - 00DFFF invalid
1812 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1813 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1814 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1815 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1817 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1819 codecvt_base::result
1820 utf16_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
1821 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1822 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1826 if (mode
& generate_header
)
1828 if (to_end
-to_nxt
< 3)
1829 return codecvt_base::partial
;
1830 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1831 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1832 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1834 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1836 uint16_t wc1
= *frm_nxt
;
1838 return codecvt_base::error
;
1841 if (to_end
-to_nxt
< 1)
1842 return codecvt_base::partial
;
1843 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1845 else if (wc1
< 0x0800)
1847 if (to_end
-to_nxt
< 2)
1848 return codecvt_base::partial
;
1849 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1850 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1852 else if (wc1
< 0xD800)
1854 if (to_end
-to_nxt
< 3)
1855 return codecvt_base::partial
;
1856 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1857 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1858 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1860 else if (wc1
< 0xDC00)
1862 if (frm_end
-frm_nxt
< 2)
1863 return codecvt_base::partial
;
1864 uint16_t wc2
= frm_nxt
[1];
1865 if ((wc2
& 0xFC00) != 0xDC00)
1866 return codecvt_base::error
;
1867 if (to_end
-to_nxt
< 4)
1868 return codecvt_base::partial
;
1869 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1870 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1871 return codecvt_base::error
;
1873 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1874 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1875 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1876 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1877 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1879 else if (wc1
< 0xE000)
1881 return codecvt_base::error
;
1885 if (to_end
-to_nxt
< 3)
1886 return codecvt_base::partial
;
1887 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1888 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1889 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1892 return codecvt_base::ok
;
1896 codecvt_base::result
1897 utf16_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
1898 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
1899 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1903 if (mode
& generate_header
)
1905 if (to_end
-to_nxt
< 3)
1906 return codecvt_base::partial
;
1907 *to_nxt
++ = static_cast<uint8_t>(0xEF);
1908 *to_nxt
++ = static_cast<uint8_t>(0xBB);
1909 *to_nxt
++ = static_cast<uint8_t>(0xBF);
1911 for (; frm_nxt
< frm_end
; ++frm_nxt
)
1913 uint16_t wc1
= static_cast<uint16_t>(*frm_nxt
);
1915 return codecvt_base::error
;
1918 if (to_end
-to_nxt
< 1)
1919 return codecvt_base::partial
;
1920 *to_nxt
++ = static_cast<uint8_t>(wc1
);
1922 else if (wc1
< 0x0800)
1924 if (to_end
-to_nxt
< 2)
1925 return codecvt_base::partial
;
1926 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc1
>> 6));
1927 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x03F));
1929 else if (wc1
< 0xD800)
1931 if (to_end
-to_nxt
< 3)
1932 return codecvt_base::partial
;
1933 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1934 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1935 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1937 else if (wc1
< 0xDC00)
1939 if (frm_end
-frm_nxt
< 2)
1940 return codecvt_base::partial
;
1941 uint16_t wc2
= static_cast<uint16_t>(frm_nxt
[1]);
1942 if ((wc2
& 0xFC00) != 0xDC00)
1943 return codecvt_base::error
;
1944 if (to_end
-to_nxt
< 4)
1945 return codecvt_base::partial
;
1946 if (((((wc1
& 0x03C0UL
) >> 6) + 1) << 16) +
1947 ((wc1
& 0x003FUL
) << 10) + (wc2
& 0x03FF) > Maxcode
)
1948 return codecvt_base::error
;
1950 uint8_t z
= ((wc1
& 0x03C0) >> 6) + 1;
1951 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (z
>> 2));
1952 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((z
& 0x03) << 4) | ((wc1
& 0x003C) >> 2));
1953 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0003) << 4) | ((wc2
& 0x03C0) >> 6));
1954 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc2
& 0x003F));
1956 else if (wc1
< 0xE000)
1958 return codecvt_base::error
;
1962 if (to_end
-to_nxt
< 3)
1963 return codecvt_base::partial
;
1964 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc1
>> 12));
1965 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc1
& 0x0FC0) >> 6));
1966 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc1
& 0x003F));
1969 return codecvt_base::ok
;
1973 codecvt_base::result
1974 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
1975 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
1976 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
1980 if (mode
& consume_header
)
1982 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
1986 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
1988 uint8_t c1
= *frm_nxt
;
1990 return codecvt_base::error
;
1993 *to_nxt
= static_cast<uint16_t>(c1
);
1998 return codecvt_base::error
;
2002 if (frm_end
-frm_nxt
< 2)
2003 return codecvt_base::partial
;
2004 uint8_t c2
= frm_nxt
[1];
2005 if ((c2
& 0xC0) != 0x80)
2006 return codecvt_base::error
;
2007 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2009 return codecvt_base::error
;
2015 if (frm_end
-frm_nxt
< 3)
2016 return codecvt_base::partial
;
2017 uint8_t c2
= frm_nxt
[1];
2018 uint8_t c3
= frm_nxt
[2];
2022 if ((c2
& 0xE0) != 0xA0)
2023 return codecvt_base::error
;
2026 if ((c2
& 0xE0) != 0x80)
2027 return codecvt_base::error
;
2030 if ((c2
& 0xC0) != 0x80)
2031 return codecvt_base::error
;
2034 if ((c3
& 0xC0) != 0x80)
2035 return codecvt_base::error
;
2036 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2037 | ((c2
& 0x3F) << 6)
2040 return codecvt_base::error
;
2046 if (frm_end
-frm_nxt
< 4)
2047 return codecvt_base::partial
;
2048 uint8_t c2
= frm_nxt
[1];
2049 uint8_t c3
= frm_nxt
[2];
2050 uint8_t c4
= frm_nxt
[3];
2054 if (!(0x90 <= c2
&& c2
<= 0xBF))
2055 return codecvt_base::error
;
2058 if ((c2
& 0xF0) != 0x80)
2059 return codecvt_base::error
;
2062 if ((c2
& 0xC0) != 0x80)
2063 return codecvt_base::error
;
2066 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2067 return codecvt_base::error
;
2068 if (to_end
-to_nxt
< 2)
2069 return codecvt_base::partial
;
2070 if ((((c1
& 7UL) << 18) +
2071 ((c2
& 0x3FUL
) << 12) +
2072 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2073 return codecvt_base::error
;
2074 *to_nxt
= static_cast<uint16_t>(
2076 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2077 | ((c2
& 0x0F) << 2)
2078 | ((c3
& 0x30) >> 4));
2079 *++to_nxt
= static_cast<uint16_t>(
2081 | ((c3
& 0x0F) << 6)
2087 return codecvt_base::error
;
2090 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2094 codecvt_base::result
2095 utf8_to_utf16(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2096 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2097 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2101 if (mode
& consume_header
)
2103 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2107 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2109 uint8_t c1
= *frm_nxt
;
2111 return codecvt_base::error
;
2114 *to_nxt
= static_cast<uint32_t>(c1
);
2119 return codecvt_base::error
;
2123 if (frm_end
-frm_nxt
< 2)
2124 return codecvt_base::partial
;
2125 uint8_t c2
= frm_nxt
[1];
2126 if ((c2
& 0xC0) != 0x80)
2127 return codecvt_base::error
;
2128 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (c2
& 0x3F));
2130 return codecvt_base::error
;
2131 *to_nxt
= static_cast<uint32_t>(t
);
2136 if (frm_end
-frm_nxt
< 3)
2137 return codecvt_base::partial
;
2138 uint8_t c2
= frm_nxt
[1];
2139 uint8_t c3
= frm_nxt
[2];
2143 if ((c2
& 0xE0) != 0xA0)
2144 return codecvt_base::error
;
2147 if ((c2
& 0xE0) != 0x80)
2148 return codecvt_base::error
;
2151 if ((c2
& 0xC0) != 0x80)
2152 return codecvt_base::error
;
2155 if ((c3
& 0xC0) != 0x80)
2156 return codecvt_base::error
;
2157 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2158 | ((c2
& 0x3F) << 6)
2161 return codecvt_base::error
;
2162 *to_nxt
= static_cast<uint32_t>(t
);
2167 if (frm_end
-frm_nxt
< 4)
2168 return codecvt_base::partial
;
2169 uint8_t c2
= frm_nxt
[1];
2170 uint8_t c3
= frm_nxt
[2];
2171 uint8_t c4
= frm_nxt
[3];
2175 if (!(0x90 <= c2
&& c2
<= 0xBF))
2176 return codecvt_base::error
;
2179 if ((c2
& 0xF0) != 0x80)
2180 return codecvt_base::error
;
2183 if ((c2
& 0xC0) != 0x80)
2184 return codecvt_base::error
;
2187 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2188 return codecvt_base::error
;
2189 if (to_end
-to_nxt
< 2)
2190 return codecvt_base::partial
;
2191 if ((((c1
& 7UL) << 18) +
2192 ((c2
& 0x3FUL
) << 12) +
2193 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2194 return codecvt_base::error
;
2195 *to_nxt
= static_cast<uint32_t>(
2197 | (((((c1
& 0x07) << 2) | ((c2
& 0x30) >> 4)) - 1) << 6)
2198 | ((c2
& 0x0F) << 2)
2199 | ((c3
& 0x30) >> 4));
2200 *++to_nxt
= static_cast<uint32_t>(
2202 | ((c3
& 0x0F) << 6)
2208 return codecvt_base::error
;
2211 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2216 utf8_to_utf16_length(const uint8_t* frm
, const uint8_t* frm_end
,
2217 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2218 codecvt_mode mode
= codecvt_mode(0))
2220 const uint8_t* frm_nxt
= frm
;
2221 if (mode
& consume_header
)
2223 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2227 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
&& nchar16_t
< mx
; ++nchar16_t
)
2229 uint8_t c1
= *frm_nxt
;
2242 if ((frm_end
-frm_nxt
< 2) || (frm_nxt
[1] & 0xC0) != 0x80)
2244 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6) | (frm_nxt
[1] & 0x3F));
2251 if (frm_end
-frm_nxt
< 3)
2253 uint8_t c2
= frm_nxt
[1];
2254 uint8_t c3
= frm_nxt
[2];
2258 if ((c2
& 0xE0) != 0xA0)
2259 return static_cast<int>(frm_nxt
- frm
);
2262 if ((c2
& 0xE0) != 0x80)
2263 return static_cast<int>(frm_nxt
- frm
);
2266 if ((c2
& 0xC0) != 0x80)
2267 return static_cast<int>(frm_nxt
- frm
);
2270 if ((c3
& 0xC0) != 0x80)
2272 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2278 if (frm_end
-frm_nxt
< 4 || mx
-nchar16_t
< 2)
2280 uint8_t c2
= frm_nxt
[1];
2281 uint8_t c3
= frm_nxt
[2];
2282 uint8_t c4
= frm_nxt
[3];
2286 if (!(0x90 <= c2
&& c2
<= 0xBF))
2287 return static_cast<int>(frm_nxt
- frm
);
2290 if ((c2
& 0xF0) != 0x80)
2291 return static_cast<int>(frm_nxt
- frm
);
2294 if ((c2
& 0xC0) != 0x80)
2295 return static_cast<int>(frm_nxt
- frm
);
2298 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2300 if ((((c1
& 7UL) << 18) +
2301 ((c2
& 0x3FUL
) << 12) +
2302 ((c3
& 0x3FUL
) << 6) + (c4
& 0x3F)) > Maxcode
)
2312 return static_cast<int>(frm_nxt
- frm
);
2316 codecvt_base::result
2317 ucs4_to_utf8(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2318 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2319 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2323 if (mode
& generate_header
)
2325 if (to_end
-to_nxt
< 3)
2326 return codecvt_base::partial
;
2327 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2328 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2329 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2331 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2333 uint32_t wc
= *frm_nxt
;
2334 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2335 return codecvt_base::error
;
2338 if (to_end
-to_nxt
< 1)
2339 return codecvt_base::partial
;
2340 *to_nxt
++ = static_cast<uint8_t>(wc
);
2342 else if (wc
< 0x000800)
2344 if (to_end
-to_nxt
< 2)
2345 return codecvt_base::partial
;
2346 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2347 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2349 else if (wc
< 0x010000)
2351 if (to_end
-to_nxt
< 3)
2352 return codecvt_base::partial
;
2353 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2354 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2355 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2357 else // if (wc < 0x110000)
2359 if (to_end
-to_nxt
< 4)
2360 return codecvt_base::partial
;
2361 *to_nxt
++ = static_cast<uint8_t>(0xF0 | (wc
>> 18));
2362 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x03F000) >> 12));
2363 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x000FC0) >> 6));
2364 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x00003F));
2367 return codecvt_base::ok
;
2371 codecvt_base::result
2372 utf8_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2373 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2374 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2378 if (mode
& consume_header
)
2380 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2384 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2386 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2390 return codecvt_base::error
;
2391 *to_nxt
= static_cast<uint32_t>(c1
);
2396 return codecvt_base::error
;
2400 if (frm_end
-frm_nxt
< 2)
2401 return codecvt_base::partial
;
2402 uint8_t c2
= frm_nxt
[1];
2403 if ((c2
& 0xC0) != 0x80)
2404 return codecvt_base::error
;
2405 uint32_t t
= static_cast<uint32_t>(((c1
& 0x1F) << 6)
2408 return codecvt_base::error
;
2414 if (frm_end
-frm_nxt
< 3)
2415 return codecvt_base::partial
;
2416 uint8_t c2
= frm_nxt
[1];
2417 uint8_t c3
= frm_nxt
[2];
2421 if ((c2
& 0xE0) != 0xA0)
2422 return codecvt_base::error
;
2425 if ((c2
& 0xE0) != 0x80)
2426 return codecvt_base::error
;
2429 if ((c2
& 0xC0) != 0x80)
2430 return codecvt_base::error
;
2433 if ((c3
& 0xC0) != 0x80)
2434 return codecvt_base::error
;
2435 uint32_t t
= static_cast<uint32_t>(((c1
& 0x0F) << 12)
2436 | ((c2
& 0x3F) << 6)
2439 return codecvt_base::error
;
2445 if (frm_end
-frm_nxt
< 4)
2446 return codecvt_base::partial
;
2447 uint8_t c2
= frm_nxt
[1];
2448 uint8_t c3
= frm_nxt
[2];
2449 uint8_t c4
= frm_nxt
[3];
2453 if (!(0x90 <= c2
&& c2
<= 0xBF))
2454 return codecvt_base::error
;
2457 if ((c2
& 0xF0) != 0x80)
2458 return codecvt_base::error
;
2461 if ((c2
& 0xC0) != 0x80)
2462 return codecvt_base::error
;
2465 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2466 return codecvt_base::error
;
2467 uint32_t t
= static_cast<uint32_t>(((c1
& 0x07) << 18)
2468 | ((c2
& 0x3F) << 12)
2469 | ((c3
& 0x3F) << 6)
2472 return codecvt_base::error
;
2478 return codecvt_base::error
;
2481 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2486 utf8_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2487 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2488 codecvt_mode mode
= codecvt_mode(0))
2490 const uint8_t* frm_nxt
= frm
;
2491 if (mode
& consume_header
)
2493 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2497 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2499 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2512 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2514 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2520 if (frm_end
-frm_nxt
< 3)
2522 uint8_t c2
= frm_nxt
[1];
2523 uint8_t c3
= frm_nxt
[2];
2527 if ((c2
& 0xE0) != 0xA0)
2528 return static_cast<int>(frm_nxt
- frm
);
2531 if ((c2
& 0xE0) != 0x80)
2532 return static_cast<int>(frm_nxt
- frm
);
2535 if ((c2
& 0xC0) != 0x80)
2536 return static_cast<int>(frm_nxt
- frm
);
2539 if ((c3
& 0xC0) != 0x80)
2541 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2547 if (frm_end
-frm_nxt
< 4)
2549 uint8_t c2
= frm_nxt
[1];
2550 uint8_t c3
= frm_nxt
[2];
2551 uint8_t c4
= frm_nxt
[3];
2555 if (!(0x90 <= c2
&& c2
<= 0xBF))
2556 return static_cast<int>(frm_nxt
- frm
);
2559 if ((c2
& 0xF0) != 0x80)
2560 return static_cast<int>(frm_nxt
- frm
);
2563 if ((c2
& 0xC0) != 0x80)
2564 return static_cast<int>(frm_nxt
- frm
);
2567 if ((c3
& 0xC0) != 0x80 || (c4
& 0xC0) != 0x80)
2569 if ((((c1
& 0x07u
) << 18) | ((c2
& 0x3Fu
) << 12) |
2570 ((c3
& 0x3Fu
) << 6) | (c4
& 0x3Fu
)) > Maxcode
)
2579 return static_cast<int>(frm_nxt
- frm
);
2583 codecvt_base::result
2584 ucs2_to_utf8(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
2585 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2586 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2590 if (mode
& generate_header
)
2592 if (to_end
-to_nxt
< 3)
2593 return codecvt_base::partial
;
2594 *to_nxt
++ = static_cast<uint8_t>(0xEF);
2595 *to_nxt
++ = static_cast<uint8_t>(0xBB);
2596 *to_nxt
++ = static_cast<uint8_t>(0xBF);
2598 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2600 uint16_t wc
= *frm_nxt
;
2601 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
2602 return codecvt_base::error
;
2605 if (to_end
-to_nxt
< 1)
2606 return codecvt_base::partial
;
2607 *to_nxt
++ = static_cast<uint8_t>(wc
);
2609 else if (wc
< 0x0800)
2611 if (to_end
-to_nxt
< 2)
2612 return codecvt_base::partial
;
2613 *to_nxt
++ = static_cast<uint8_t>(0xC0 | (wc
>> 6));
2614 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x03F));
2616 else // if (wc <= 0xFFFF)
2618 if (to_end
-to_nxt
< 3)
2619 return codecvt_base::partial
;
2620 *to_nxt
++ = static_cast<uint8_t>(0xE0 | (wc
>> 12));
2621 *to_nxt
++ = static_cast<uint8_t>(0x80 | ((wc
& 0x0FC0) >> 6));
2622 *to_nxt
++ = static_cast<uint8_t>(0x80 | (wc
& 0x003F));
2625 return codecvt_base::ok
;
2629 codecvt_base::result
2630 utf8_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2631 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
2632 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2636 if (mode
& consume_header
)
2638 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2642 for (; frm_nxt
< frm_end
&& to_nxt
< to_end
; ++to_nxt
)
2644 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2648 return codecvt_base::error
;
2649 *to_nxt
= static_cast<uint16_t>(c1
);
2654 return codecvt_base::error
;
2658 if (frm_end
-frm_nxt
< 2)
2659 return codecvt_base::partial
;
2660 uint8_t c2
= frm_nxt
[1];
2661 if ((c2
& 0xC0) != 0x80)
2662 return codecvt_base::error
;
2663 uint16_t t
= static_cast<uint16_t>(((c1
& 0x1F) << 6)
2666 return codecvt_base::error
;
2672 if (frm_end
-frm_nxt
< 3)
2673 return codecvt_base::partial
;
2674 uint8_t c2
= frm_nxt
[1];
2675 uint8_t c3
= frm_nxt
[2];
2679 if ((c2
& 0xE0) != 0xA0)
2680 return codecvt_base::error
;
2683 if ((c2
& 0xE0) != 0x80)
2684 return codecvt_base::error
;
2687 if ((c2
& 0xC0) != 0x80)
2688 return codecvt_base::error
;
2691 if ((c3
& 0xC0) != 0x80)
2692 return codecvt_base::error
;
2693 uint16_t t
= static_cast<uint16_t>(((c1
& 0x0F) << 12)
2694 | ((c2
& 0x3F) << 6)
2697 return codecvt_base::error
;
2703 return codecvt_base::error
;
2706 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2711 utf8_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
2712 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2713 codecvt_mode mode
= codecvt_mode(0))
2715 const uint8_t* frm_nxt
= frm
;
2716 if (mode
& consume_header
)
2718 if (frm_end
-frm_nxt
>= 3 && frm_nxt
[0] == 0xEF && frm_nxt
[1] == 0xBB &&
2722 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
&& nchar32_t
< mx
; ++nchar32_t
)
2724 uint8_t c1
= static_cast<uint8_t>(*frm_nxt
);
2737 if ((frm_end
-frm_nxt
< 2) || ((frm_nxt
[1] & 0xC0) != 0x80))
2739 if ((((c1
& 0x1Fu
) << 6) | (frm_nxt
[1] & 0x3Fu
)) > Maxcode
)
2745 if (frm_end
-frm_nxt
< 3)
2747 uint8_t c2
= frm_nxt
[1];
2748 uint8_t c3
= frm_nxt
[2];
2752 if ((c2
& 0xE0) != 0xA0)
2753 return static_cast<int>(frm_nxt
- frm
);
2756 if ((c2
& 0xE0) != 0x80)
2757 return static_cast<int>(frm_nxt
- frm
);
2760 if ((c2
& 0xC0) != 0x80)
2761 return static_cast<int>(frm_nxt
- frm
);
2764 if ((c3
& 0xC0) != 0x80)
2766 if ((((c1
& 0x0Fu
) << 12) | ((c2
& 0x3Fu
) << 6) | (c3
& 0x3Fu
)) > Maxcode
)
2775 return static_cast<int>(frm_nxt
- frm
);
2779 codecvt_base::result
2780 ucs4_to_utf16be(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2781 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2782 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2786 if (mode
& generate_header
)
2788 if (to_end
-to_nxt
< 2)
2789 return codecvt_base::partial
;
2790 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2791 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2793 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2795 uint32_t wc
= *frm_nxt
;
2796 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2797 return codecvt_base::error
;
2800 if (to_end
-to_nxt
< 2)
2801 return codecvt_base::partial
;
2802 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2803 *to_nxt
++ = static_cast<uint8_t>(wc
);
2807 if (to_end
-to_nxt
< 4)
2808 return codecvt_base::partial
;
2809 uint16_t t
= static_cast<uint16_t>(
2811 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2812 | ((wc
& 0x00FC00) >> 10));
2813 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2814 *to_nxt
++ = static_cast<uint8_t>(t
);
2815 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2816 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2817 *to_nxt
++ = static_cast<uint8_t>(t
);
2820 return codecvt_base::ok
;
2824 codecvt_base::result
2825 utf16be_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2826 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2827 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2831 if (mode
& consume_header
)
2833 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2836 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2838 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2839 if ((c1
& 0xFC00) == 0xDC00)
2840 return codecvt_base::error
;
2841 if ((c1
& 0xFC00) != 0xD800)
2844 return codecvt_base::error
;
2845 *to_nxt
= static_cast<uint32_t>(c1
);
2850 if (frm_end
-frm_nxt
< 4)
2851 return codecvt_base::partial
;
2852 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2853 if ((c2
& 0xFC00) != 0xDC00)
2854 return codecvt_base::error
;
2855 uint32_t t
= static_cast<uint32_t>(
2856 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2857 | ((c1
& 0x003F) << 10)
2860 return codecvt_base::error
;
2865 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
2870 utf16be_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
2871 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
2872 codecvt_mode mode
= codecvt_mode(0))
2874 const uint8_t* frm_nxt
= frm
;
2875 if (mode
& consume_header
)
2877 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
2880 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
2882 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
2883 if ((c1
& 0xFC00) == 0xDC00)
2885 if ((c1
& 0xFC00) != 0xD800)
2893 if (frm_end
-frm_nxt
< 4)
2895 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[2] << 8 | frm_nxt
[3]);
2896 if ((c2
& 0xFC00) != 0xDC00)
2898 uint32_t t
= static_cast<uint32_t>(
2899 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2900 | ((c1
& 0x003F) << 10)
2907 return static_cast<int>(frm_nxt
- frm
);
2911 codecvt_base::result
2912 ucs4_to_utf16le(const uint32_t* frm
, const uint32_t* frm_end
, const uint32_t*& frm_nxt
,
2913 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
2914 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2918 if (mode
& generate_header
)
2920 if (to_end
- to_nxt
< 2)
2921 return codecvt_base::partial
;
2922 *to_nxt
++ = static_cast<uint8_t>(0xFF);
2923 *to_nxt
++ = static_cast<uint8_t>(0xFE);
2925 for (; frm_nxt
< frm_end
; ++frm_nxt
)
2927 uint32_t wc
= *frm_nxt
;
2928 if ((wc
& 0xFFFFF800) == 0x00D800 || wc
> Maxcode
)
2929 return codecvt_base::error
;
2932 if (to_end
-to_nxt
< 2)
2933 return codecvt_base::partial
;
2934 *to_nxt
++ = static_cast<uint8_t>(wc
);
2935 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
2939 if (to_end
-to_nxt
< 4)
2940 return codecvt_base::partial
;
2941 uint16_t t
= static_cast<uint16_t>(
2943 | ((((wc
& 0x1F0000) >> 16) - 1) << 6)
2944 | ((wc
& 0x00FC00) >> 10));
2945 *to_nxt
++ = static_cast<uint8_t>(t
);
2946 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2947 t
= static_cast<uint16_t>(0xDC00 | (wc
& 0x03FF));
2948 *to_nxt
++ = static_cast<uint8_t>(t
);
2949 *to_nxt
++ = static_cast<uint8_t>(t
>> 8);
2952 return codecvt_base::ok
;
2956 codecvt_base::result
2957 utf16le_to_ucs4(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
2958 uint32_t* to
, uint32_t* to_end
, uint32_t*& to_nxt
,
2959 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
2963 if (mode
& consume_header
)
2965 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
2968 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
2970 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
2971 if ((c1
& 0xFC00) == 0xDC00)
2972 return codecvt_base::error
;
2973 if ((c1
& 0xFC00) != 0xD800)
2976 return codecvt_base::error
;
2977 *to_nxt
= static_cast<uint32_t>(c1
);
2982 if (frm_end
-frm_nxt
< 4)
2983 return codecvt_base::partial
;
2984 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
2985 if ((c2
& 0xFC00) != 0xDC00)
2986 return codecvt_base::error
;
2987 uint32_t t
= static_cast<uint32_t>(
2988 ((((c1
& 0x03C0) >> 6) + 1) << 16)
2989 | ((c1
& 0x003F) << 10)
2992 return codecvt_base::error
;
2997 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3002 utf16le_to_ucs4_length(const uint8_t* frm
, const uint8_t* frm_end
,
3003 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3004 codecvt_mode mode
= codecvt_mode(0))
3006 const uint8_t* frm_nxt
= frm
;
3007 if (mode
& consume_header
)
3009 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3012 for (size_t nchar32_t
= 0; frm_nxt
< frm_end
- 1 && nchar32_t
< mx
; ++nchar32_t
)
3014 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3015 if ((c1
& 0xFC00) == 0xDC00)
3017 if ((c1
& 0xFC00) != 0xD800)
3025 if (frm_end
-frm_nxt
< 4)
3027 uint16_t c2
= static_cast<uint16_t>(frm_nxt
[3] << 8 | frm_nxt
[2]);
3028 if ((c2
& 0xFC00) != 0xDC00)
3030 uint32_t t
= static_cast<uint32_t>(
3031 ((((c1
& 0x03C0) >> 6) + 1) << 16)
3032 | ((c1
& 0x003F) << 10)
3039 return static_cast<int>(frm_nxt
- frm
);
3043 codecvt_base::result
3044 ucs2_to_utf16be(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3045 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3046 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3050 if (mode
& generate_header
)
3052 if (to_end
-to_nxt
< 2)
3053 return codecvt_base::partial
;
3054 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3055 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3057 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3059 uint16_t wc
= *frm_nxt
;
3060 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3061 return codecvt_base::error
;
3062 if (to_end
-to_nxt
< 2)
3063 return codecvt_base::partial
;
3064 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3065 *to_nxt
++ = static_cast<uint8_t>(wc
);
3067 return codecvt_base::ok
;
3071 codecvt_base::result
3072 utf16be_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3073 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3074 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3078 if (mode
& consume_header
)
3080 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3083 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3085 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3086 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3087 return codecvt_base::error
;
3091 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3096 utf16be_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3097 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3098 codecvt_mode mode
= codecvt_mode(0))
3100 const uint8_t* frm_nxt
= frm
;
3101 if (mode
& consume_header
)
3103 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFE && frm_nxt
[1] == 0xFF)
3106 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3108 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[0] << 8 | frm_nxt
[1]);
3109 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3113 return static_cast<int>(frm_nxt
- frm
);
3117 codecvt_base::result
3118 ucs2_to_utf16le(const uint16_t* frm
, const uint16_t* frm_end
, const uint16_t*& frm_nxt
,
3119 uint8_t* to
, uint8_t* to_end
, uint8_t*& to_nxt
,
3120 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3124 if (mode
& generate_header
)
3126 if (to_end
-to_nxt
< 2)
3127 return codecvt_base::partial
;
3128 *to_nxt
++ = static_cast<uint8_t>(0xFF);
3129 *to_nxt
++ = static_cast<uint8_t>(0xFE);
3131 for (; frm_nxt
< frm_end
; ++frm_nxt
)
3133 uint16_t wc
= *frm_nxt
;
3134 if ((wc
& 0xF800) == 0xD800 || wc
> Maxcode
)
3135 return codecvt_base::error
;
3136 if (to_end
-to_nxt
< 2)
3137 return codecvt_base::partial
;
3138 *to_nxt
++ = static_cast<uint8_t>(wc
);
3139 *to_nxt
++ = static_cast<uint8_t>(wc
>> 8);
3141 return codecvt_base::ok
;
3145 codecvt_base::result
3146 utf16le_to_ucs2(const uint8_t* frm
, const uint8_t* frm_end
, const uint8_t*& frm_nxt
,
3147 uint16_t* to
, uint16_t* to_end
, uint16_t*& to_nxt
,
3148 unsigned long Maxcode
= 0x10FFFF, codecvt_mode mode
= codecvt_mode(0))
3152 if (mode
& consume_header
)
3154 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3157 for (; frm_nxt
< frm_end
- 1 && to_nxt
< to_end
; ++to_nxt
)
3159 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3160 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3161 return codecvt_base::error
;
3165 return frm_nxt
< frm_end
? codecvt_base::partial
: codecvt_base::ok
;
3170 utf16le_to_ucs2_length(const uint8_t* frm
, const uint8_t* frm_end
,
3171 size_t mx
, unsigned long Maxcode
= 0x10FFFF,
3172 codecvt_mode mode
= codecvt_mode(0))
3174 const uint8_t* frm_nxt
= frm
;
3176 if (mode
& consume_header
)
3178 if (frm_end
-frm_nxt
>= 2 && frm_nxt
[0] == 0xFF && frm_nxt
[1] == 0xFE)
3181 for (size_t nchar16_t
= 0; frm_nxt
< frm_end
- 1 && nchar16_t
< mx
; ++nchar16_t
)
3183 uint16_t c1
= static_cast<uint16_t>(frm_nxt
[1] << 8 | frm_nxt
[0]);
3184 if ((c1
& 0xF800) == 0xD800 || c1
> Maxcode
)
3188 return static_cast<int>(frm_nxt
- frm
);
3191 _LIBCPP_SUPPRESS_DEPRECATED_POP
3193 // template <> class codecvt<char16_t, char, mbstate_t>
3195 locale::id codecvt
<char16_t
, char, mbstate_t>::id
;
3197 codecvt
<char16_t
, char, mbstate_t>::~codecvt()
3201 codecvt
<char16_t
, char, mbstate_t>::result
3202 codecvt
<char16_t
, char, mbstate_t>::do_out(state_type
&,
3203 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3204 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3206 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3207 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3208 const uint16_t* _frm_nxt
= _frm
;
3209 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3210 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3211 uint8_t* _to_nxt
= _to
;
3212 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3213 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3214 to_nxt
= to
+ (_to_nxt
- _to
);
3218 codecvt
<char16_t
, char, mbstate_t>::result
3219 codecvt
<char16_t
, char, mbstate_t>::do_in(state_type
&,
3220 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3221 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3223 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3224 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3225 const uint8_t* _frm_nxt
= _frm
;
3226 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3227 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3228 uint16_t* _to_nxt
= _to
;
3229 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3230 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3231 to_nxt
= to
+ (_to_nxt
- _to
);
3235 codecvt
<char16_t
, char, mbstate_t>::result
3236 codecvt
<char16_t
, char, mbstate_t>::do_unshift(state_type
&,
3237 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3244 codecvt
<char16_t
, char, mbstate_t>::do_encoding() const noexcept
3250 codecvt
<char16_t
, char, mbstate_t>::do_always_noconv() const noexcept
3256 codecvt
<char16_t
, char, mbstate_t>::do_length(state_type
&,
3257 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3259 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3260 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3261 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3265 codecvt
<char16_t
, char, mbstate_t>::do_max_length() const noexcept
3270 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3272 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3274 locale::id codecvt
<char16_t
, char8_t
, mbstate_t>::id
;
3276 codecvt
<char16_t
, char8_t
, mbstate_t>::~codecvt()
3280 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3281 codecvt
<char16_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3282 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3283 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3285 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3286 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3287 const uint16_t* _frm_nxt
= _frm
;
3288 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3289 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3290 uint8_t* _to_nxt
= _to
;
3291 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3292 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3293 to_nxt
= to
+ (_to_nxt
- _to
);
3297 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3298 codecvt
<char16_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3299 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3300 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3302 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3303 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3304 const uint8_t* _frm_nxt
= _frm
;
3305 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3306 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3307 uint16_t* _to_nxt
= _to
;
3308 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3309 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3310 to_nxt
= to
+ (_to_nxt
- _to
);
3314 codecvt
<char16_t
, char8_t
, mbstate_t>::result
3315 codecvt
<char16_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3316 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3323 codecvt
<char16_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3329 codecvt
<char16_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3335 codecvt
<char16_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3336 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3338 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3339 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3340 return utf8_to_utf16_length(_frm
, _frm_end
, mx
);
3344 codecvt
<char16_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3351 // template <> class codecvt<char32_t, char, mbstate_t>
3353 locale::id codecvt
<char32_t
, char, mbstate_t>::id
;
3355 codecvt
<char32_t
, char, mbstate_t>::~codecvt()
3359 codecvt
<char32_t
, char, mbstate_t>::result
3360 codecvt
<char32_t
, char, mbstate_t>::do_out(state_type
&,
3361 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3362 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3364 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3365 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3366 const uint32_t* _frm_nxt
= _frm
;
3367 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3368 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3369 uint8_t* _to_nxt
= _to
;
3370 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3371 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3372 to_nxt
= to
+ (_to_nxt
- _to
);
3376 codecvt
<char32_t
, char, mbstate_t>::result
3377 codecvt
<char32_t
, char, mbstate_t>::do_in(state_type
&,
3378 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3379 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3381 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3382 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3383 const uint8_t* _frm_nxt
= _frm
;
3384 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3385 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3386 uint32_t* _to_nxt
= _to
;
3387 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3388 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3389 to_nxt
= to
+ (_to_nxt
- _to
);
3393 codecvt
<char32_t
, char, mbstate_t>::result
3394 codecvt
<char32_t
, char, mbstate_t>::do_unshift(state_type
&,
3395 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3402 codecvt
<char32_t
, char, mbstate_t>::do_encoding() const noexcept
3408 codecvt
<char32_t
, char, mbstate_t>::do_always_noconv() const noexcept
3414 codecvt
<char32_t
, char, mbstate_t>::do_length(state_type
&,
3415 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3417 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3418 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3419 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3423 codecvt
<char32_t
, char, mbstate_t>::do_max_length() const noexcept
3428 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3430 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3432 locale::id codecvt
<char32_t
, char8_t
, mbstate_t>::id
;
3434 codecvt
<char32_t
, char8_t
, mbstate_t>::~codecvt()
3438 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3439 codecvt
<char32_t
, char8_t
, mbstate_t>::do_out(state_type
&,
3440 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3441 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3443 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3444 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3445 const uint32_t* _frm_nxt
= _frm
;
3446 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3447 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3448 uint8_t* _to_nxt
= _to
;
3449 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3450 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3451 to_nxt
= to
+ (_to_nxt
- _to
);
3455 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3456 codecvt
<char32_t
, char8_t
, mbstate_t>::do_in(state_type
&,
3457 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3458 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3460 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3461 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3462 const uint8_t* _frm_nxt
= _frm
;
3463 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3464 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3465 uint32_t* _to_nxt
= _to
;
3466 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
);
3467 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3468 to_nxt
= to
+ (_to_nxt
- _to
);
3472 codecvt
<char32_t
, char8_t
, mbstate_t>::result
3473 codecvt
<char32_t
, char8_t
, mbstate_t>::do_unshift(state_type
&,
3474 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3481 codecvt
<char32_t
, char8_t
, mbstate_t>::do_encoding() const noexcept
3487 codecvt
<char32_t
, char8_t
, mbstate_t>::do_always_noconv() const noexcept
3493 codecvt
<char32_t
, char8_t
, mbstate_t>::do_length(state_type
&,
3494 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3496 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3497 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3498 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
);
3502 codecvt
<char32_t
, char8_t
, mbstate_t>::do_max_length() const noexcept
3509 // __codecvt_utf8<wchar_t>
3511 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3512 __codecvt_utf8
<wchar_t>::result
3513 __codecvt_utf8
<wchar_t>::do_out(state_type
&,
3514 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3515 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3517 #if defined(_LIBCPP_SHORT_WCHAR)
3518 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3519 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3520 const uint16_t* _frm_nxt
= _frm
;
3522 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3523 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3524 const uint32_t* _frm_nxt
= _frm
;
3526 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3527 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3528 uint8_t* _to_nxt
= _to
;
3529 #if defined(_LIBCPP_SHORT_WCHAR)
3530 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3531 __maxcode_
, __mode_
);
3533 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3534 __maxcode_
, __mode_
);
3536 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3537 to_nxt
= to
+ (_to_nxt
- _to
);
3541 __codecvt_utf8
<wchar_t>::result
3542 __codecvt_utf8
<wchar_t>::do_in(state_type
&,
3543 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3544 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3546 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3547 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3548 const uint8_t* _frm_nxt
= _frm
;
3549 #if defined(_LIBCPP_SHORT_WCHAR)
3550 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3551 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3552 uint16_t* _to_nxt
= _to
;
3553 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3554 __maxcode_
, __mode_
);
3556 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3557 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3558 uint32_t* _to_nxt
= _to
;
3559 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3560 __maxcode_
, __mode_
);
3562 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3563 to_nxt
= to
+ (_to_nxt
- _to
);
3567 __codecvt_utf8
<wchar_t>::result
3568 __codecvt_utf8
<wchar_t>::do_unshift(state_type
&,
3569 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3576 __codecvt_utf8
<wchar_t>::do_encoding() const noexcept
3582 __codecvt_utf8
<wchar_t>::do_always_noconv() const noexcept
3588 __codecvt_utf8
<wchar_t>::do_length(state_type
&,
3589 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3591 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3592 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3593 #if defined(_LIBCPP_SHORT_WCHAR)
3594 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3596 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3600 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3602 __codecvt_utf8
<wchar_t>::do_max_length() const noexcept
3604 #if defined(_LIBCPP_SHORT_WCHAR)
3605 if (__mode_
& consume_header
)
3609 if (__mode_
& consume_header
)
3614 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3616 // __codecvt_utf8<char16_t>
3618 __codecvt_utf8
<char16_t
>::result
3619 __codecvt_utf8
<char16_t
>::do_out(state_type
&,
3620 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3621 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3623 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3624 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3625 const uint16_t* _frm_nxt
= _frm
;
3626 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3627 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3628 uint8_t* _to_nxt
= _to
;
3629 result r
= ucs2_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3630 __maxcode_
, __mode_
);
3631 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3632 to_nxt
= to
+ (_to_nxt
- _to
);
3636 __codecvt_utf8
<char16_t
>::result
3637 __codecvt_utf8
<char16_t
>::do_in(state_type
&,
3638 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3639 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3641 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3642 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3643 const uint8_t* _frm_nxt
= _frm
;
3644 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3645 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3646 uint16_t* _to_nxt
= _to
;
3647 result r
= utf8_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3648 __maxcode_
, __mode_
);
3649 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3650 to_nxt
= to
+ (_to_nxt
- _to
);
3654 __codecvt_utf8
<char16_t
>::result
3655 __codecvt_utf8
<char16_t
>::do_unshift(state_type
&,
3656 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3663 __codecvt_utf8
<char16_t
>::do_encoding() const noexcept
3669 __codecvt_utf8
<char16_t
>::do_always_noconv() const noexcept
3675 __codecvt_utf8
<char16_t
>::do_length(state_type
&,
3676 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3678 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3679 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3680 return utf8_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3683 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3685 __codecvt_utf8
<char16_t
>::do_max_length() const noexcept
3687 if (__mode_
& consume_header
)
3691 _LIBCPP_SUPPRESS_DEPRECATED_POP
3693 // __codecvt_utf8<char32_t>
3695 __codecvt_utf8
<char32_t
>::result
3696 __codecvt_utf8
<char32_t
>::do_out(state_type
&,
3697 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3698 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3700 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3701 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3702 const uint32_t* _frm_nxt
= _frm
;
3703 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3704 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3705 uint8_t* _to_nxt
= _to
;
3706 result r
= ucs4_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3707 __maxcode_
, __mode_
);
3708 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3709 to_nxt
= to
+ (_to_nxt
- _to
);
3713 __codecvt_utf8
<char32_t
>::result
3714 __codecvt_utf8
<char32_t
>::do_in(state_type
&,
3715 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3716 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3718 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3719 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3720 const uint8_t* _frm_nxt
= _frm
;
3721 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3722 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3723 uint32_t* _to_nxt
= _to
;
3724 result r
= utf8_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3725 __maxcode_
, __mode_
);
3726 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3727 to_nxt
= to
+ (_to_nxt
- _to
);
3731 __codecvt_utf8
<char32_t
>::result
3732 __codecvt_utf8
<char32_t
>::do_unshift(state_type
&,
3733 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3740 __codecvt_utf8
<char32_t
>::do_encoding() const noexcept
3746 __codecvt_utf8
<char32_t
>::do_always_noconv() const noexcept
3752 __codecvt_utf8
<char32_t
>::do_length(state_type
&,
3753 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3755 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3756 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3757 return utf8_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3760 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3762 __codecvt_utf8
<char32_t
>::do_max_length() const noexcept
3764 if (__mode_
& consume_header
)
3768 _LIBCPP_SUPPRESS_DEPRECATED_POP
3770 // __codecvt_utf16<wchar_t, false>
3772 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3773 __codecvt_utf16
<wchar_t, false>::result
3774 __codecvt_utf16
<wchar_t, false>::do_out(state_type
&,
3775 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3776 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3778 #if defined(_LIBCPP_SHORT_WCHAR)
3779 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3780 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3781 const uint16_t* _frm_nxt
= _frm
;
3783 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3784 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3785 const uint32_t* _frm_nxt
= _frm
;
3787 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3788 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3789 uint8_t* _to_nxt
= _to
;
3790 #if defined(_LIBCPP_SHORT_WCHAR)
3791 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3792 __maxcode_
, __mode_
);
3794 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3795 __maxcode_
, __mode_
);
3797 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3798 to_nxt
= to
+ (_to_nxt
- _to
);
3802 __codecvt_utf16
<wchar_t, false>::result
3803 __codecvt_utf16
<wchar_t, false>::do_in(state_type
&,
3804 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3805 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3807 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3808 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3809 const uint8_t* _frm_nxt
= _frm
;
3810 #if defined(_LIBCPP_SHORT_WCHAR)
3811 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3812 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3813 uint16_t* _to_nxt
= _to
;
3814 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3815 __maxcode_
, __mode_
);
3817 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3818 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3819 uint32_t* _to_nxt
= _to
;
3820 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3821 __maxcode_
, __mode_
);
3823 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3824 to_nxt
= to
+ (_to_nxt
- _to
);
3828 __codecvt_utf16
<wchar_t, false>::result
3829 __codecvt_utf16
<wchar_t, false>::do_unshift(state_type
&,
3830 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3837 __codecvt_utf16
<wchar_t, false>::do_encoding() const noexcept
3843 __codecvt_utf16
<wchar_t, false>::do_always_noconv() const noexcept
3849 __codecvt_utf16
<wchar_t, false>::do_length(state_type
&,
3850 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3852 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3853 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3854 #if defined(_LIBCPP_SHORT_WCHAR)
3855 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3857 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3862 __codecvt_utf16
<wchar_t, false>::do_max_length() const noexcept
3864 #if defined(_LIBCPP_SHORT_WCHAR)
3865 if (__mode_
& consume_header
)
3869 if (__mode_
& consume_header
)
3875 // __codecvt_utf16<wchar_t, true>
3877 __codecvt_utf16
<wchar_t, true>::result
3878 __codecvt_utf16
<wchar_t, true>::do_out(state_type
&,
3879 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3880 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3882 #if defined(_LIBCPP_SHORT_WCHAR)
3883 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3884 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3885 const uint16_t* _frm_nxt
= _frm
;
3887 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
3888 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
3889 const uint32_t* _frm_nxt
= _frm
;
3891 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3892 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3893 uint8_t* _to_nxt
= _to
;
3894 #if defined(_LIBCPP_SHORT_WCHAR)
3895 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3896 __maxcode_
, __mode_
);
3898 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3899 __maxcode_
, __mode_
);
3901 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3902 to_nxt
= to
+ (_to_nxt
- _to
);
3906 __codecvt_utf16
<wchar_t, true>::result
3907 __codecvt_utf16
<wchar_t, true>::do_in(state_type
&,
3908 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
3909 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
3911 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3912 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3913 const uint8_t* _frm_nxt
= _frm
;
3914 #if defined(_LIBCPP_SHORT_WCHAR)
3915 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
3916 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
3917 uint16_t* _to_nxt
= _to
;
3918 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3919 __maxcode_
, __mode_
);
3921 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
3922 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
3923 uint32_t* _to_nxt
= _to
;
3924 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3925 __maxcode_
, __mode_
);
3927 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3928 to_nxt
= to
+ (_to_nxt
- _to
);
3932 __codecvt_utf16
<wchar_t, true>::result
3933 __codecvt_utf16
<wchar_t, true>::do_unshift(state_type
&,
3934 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
3941 __codecvt_utf16
<wchar_t, true>::do_encoding() const noexcept
3947 __codecvt_utf16
<wchar_t, true>::do_always_noconv() const noexcept
3953 __codecvt_utf16
<wchar_t, true>::do_length(state_type
&,
3954 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
3956 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
3957 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
3958 #if defined(_LIBCPP_SHORT_WCHAR)
3959 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3961 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
3966 __codecvt_utf16
<wchar_t, true>::do_max_length() const noexcept
3968 #if defined(_LIBCPP_SHORT_WCHAR)
3969 if (__mode_
& consume_header
)
3973 if (__mode_
& consume_header
)
3978 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3980 // __codecvt_utf16<char16_t, false>
3982 __codecvt_utf16
<char16_t
, false>::result
3983 __codecvt_utf16
<char16_t
, false>::do_out(state_type
&,
3984 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
3985 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
3987 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
3988 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
3989 const uint16_t* _frm_nxt
= _frm
;
3990 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
3991 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
3992 uint8_t* _to_nxt
= _to
;
3993 result r
= ucs2_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
3994 __maxcode_
, __mode_
);
3995 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
3996 to_nxt
= to
+ (_to_nxt
- _to
);
4000 __codecvt_utf16
<char16_t
, false>::result
4001 __codecvt_utf16
<char16_t
, false>::do_in(state_type
&,
4002 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4003 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4005 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4006 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4007 const uint8_t* _frm_nxt
= _frm
;
4008 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4009 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4010 uint16_t* _to_nxt
= _to
;
4011 result r
= utf16be_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4012 __maxcode_
, __mode_
);
4013 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4014 to_nxt
= to
+ (_to_nxt
- _to
);
4018 __codecvt_utf16
<char16_t
, false>::result
4019 __codecvt_utf16
<char16_t
, false>::do_unshift(state_type
&,
4020 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4027 __codecvt_utf16
<char16_t
, false>::do_encoding() const noexcept
4033 __codecvt_utf16
<char16_t
, false>::do_always_noconv() const noexcept
4039 __codecvt_utf16
<char16_t
, false>::do_length(state_type
&,
4040 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4042 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4043 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4044 return utf16be_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4047 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4049 __codecvt_utf16
<char16_t
, false>::do_max_length() const noexcept
4051 if (__mode_
& consume_header
)
4055 _LIBCPP_SUPPRESS_DEPRECATED_POP
4057 // __codecvt_utf16<char16_t, true>
4059 __codecvt_utf16
<char16_t
, true>::result
4060 __codecvt_utf16
<char16_t
, true>::do_out(state_type
&,
4061 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4062 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4064 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4065 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4066 const uint16_t* _frm_nxt
= _frm
;
4067 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4068 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4069 uint8_t* _to_nxt
= _to
;
4070 result r
= ucs2_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4071 __maxcode_
, __mode_
);
4072 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4073 to_nxt
= to
+ (_to_nxt
- _to
);
4077 __codecvt_utf16
<char16_t
, true>::result
4078 __codecvt_utf16
<char16_t
, true>::do_in(state_type
&,
4079 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4080 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4082 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4083 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4084 const uint8_t* _frm_nxt
= _frm
;
4085 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4086 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4087 uint16_t* _to_nxt
= _to
;
4088 result r
= utf16le_to_ucs2(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4089 __maxcode_
, __mode_
);
4090 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4091 to_nxt
= to
+ (_to_nxt
- _to
);
4095 __codecvt_utf16
<char16_t
, true>::result
4096 __codecvt_utf16
<char16_t
, true>::do_unshift(state_type
&,
4097 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4104 __codecvt_utf16
<char16_t
, true>::do_encoding() const noexcept
4110 __codecvt_utf16
<char16_t
, true>::do_always_noconv() const noexcept
4116 __codecvt_utf16
<char16_t
, true>::do_length(state_type
&,
4117 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4119 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4120 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4121 return utf16le_to_ucs2_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4124 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4126 __codecvt_utf16
<char16_t
, true>::do_max_length() const noexcept
4128 if (__mode_
& consume_header
)
4132 _LIBCPP_SUPPRESS_DEPRECATED_POP
4134 // __codecvt_utf16<char32_t, false>
4136 __codecvt_utf16
<char32_t
, false>::result
4137 __codecvt_utf16
<char32_t
, false>::do_out(state_type
&,
4138 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4139 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4141 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4142 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4143 const uint32_t* _frm_nxt
= _frm
;
4144 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4145 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4146 uint8_t* _to_nxt
= _to
;
4147 result r
= ucs4_to_utf16be(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4148 __maxcode_
, __mode_
);
4149 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4150 to_nxt
= to
+ (_to_nxt
- _to
);
4154 __codecvt_utf16
<char32_t
, false>::result
4155 __codecvt_utf16
<char32_t
, false>::do_in(state_type
&,
4156 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4157 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4159 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4160 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4161 const uint8_t* _frm_nxt
= _frm
;
4162 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4163 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4164 uint32_t* _to_nxt
= _to
;
4165 result r
= utf16be_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4166 __maxcode_
, __mode_
);
4167 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4168 to_nxt
= to
+ (_to_nxt
- _to
);
4172 __codecvt_utf16
<char32_t
, false>::result
4173 __codecvt_utf16
<char32_t
, false>::do_unshift(state_type
&,
4174 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4181 __codecvt_utf16
<char32_t
, false>::do_encoding() const noexcept
4187 __codecvt_utf16
<char32_t
, false>::do_always_noconv() const noexcept
4193 __codecvt_utf16
<char32_t
, false>::do_length(state_type
&,
4194 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4196 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4197 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4198 return utf16be_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4201 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4203 __codecvt_utf16
<char32_t
, false>::do_max_length() const noexcept
4205 if (__mode_
& consume_header
)
4209 _LIBCPP_SUPPRESS_DEPRECATED_POP
4211 // __codecvt_utf16<char32_t, true>
4213 __codecvt_utf16
<char32_t
, true>::result
4214 __codecvt_utf16
<char32_t
, true>::do_out(state_type
&,
4215 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4216 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4218 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4219 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4220 const uint32_t* _frm_nxt
= _frm
;
4221 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4222 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4223 uint8_t* _to_nxt
= _to
;
4224 result r
= ucs4_to_utf16le(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4225 __maxcode_
, __mode_
);
4226 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4227 to_nxt
= to
+ (_to_nxt
- _to
);
4231 __codecvt_utf16
<char32_t
, true>::result
4232 __codecvt_utf16
<char32_t
, true>::do_in(state_type
&,
4233 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4234 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4236 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4237 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4238 const uint8_t* _frm_nxt
= _frm
;
4239 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4240 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4241 uint32_t* _to_nxt
= _to
;
4242 result r
= utf16le_to_ucs4(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4243 __maxcode_
, __mode_
);
4244 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4245 to_nxt
= to
+ (_to_nxt
- _to
);
4249 __codecvt_utf16
<char32_t
, true>::result
4250 __codecvt_utf16
<char32_t
, true>::do_unshift(state_type
&,
4251 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4258 __codecvt_utf16
<char32_t
, true>::do_encoding() const noexcept
4264 __codecvt_utf16
<char32_t
, true>::do_always_noconv() const noexcept
4270 __codecvt_utf16
<char32_t
, true>::do_length(state_type
&,
4271 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4273 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4274 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4275 return utf16le_to_ucs4_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4278 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4280 __codecvt_utf16
<char32_t
, true>::do_max_length() const noexcept
4282 if (__mode_
& consume_header
)
4286 _LIBCPP_SUPPRESS_DEPRECATED_POP
4288 // __codecvt_utf8_utf16<wchar_t>
4290 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4291 __codecvt_utf8_utf16
<wchar_t>::result
4292 __codecvt_utf8_utf16
<wchar_t>::do_out(state_type
&,
4293 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4294 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4296 #if defined(_LIBCPP_SHORT_WCHAR)
4297 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4298 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4299 const uint16_t* _frm_nxt
= _frm
;
4301 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4302 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4303 const uint32_t* _frm_nxt
= _frm
;
4305 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4306 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4307 uint8_t* _to_nxt
= _to
;
4308 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4309 __maxcode_
, __mode_
);
4310 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4311 to_nxt
= to
+ (_to_nxt
- _to
);
4315 __codecvt_utf8_utf16
<wchar_t>::result
4316 __codecvt_utf8_utf16
<wchar_t>::do_in(state_type
&,
4317 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4318 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4320 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4321 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4322 const uint8_t* _frm_nxt
= _frm
;
4323 #if defined(_LIBCPP_SHORT_WCHAR)
4324 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4325 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4326 uint16_t* _to_nxt
= _to
;
4328 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4329 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4330 uint32_t* _to_nxt
= _to
;
4332 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4333 __maxcode_
, __mode_
);
4334 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4335 to_nxt
= to
+ (_to_nxt
- _to
);
4339 __codecvt_utf8_utf16
<wchar_t>::result
4340 __codecvt_utf8_utf16
<wchar_t>::do_unshift(state_type
&,
4341 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4348 __codecvt_utf8_utf16
<wchar_t>::do_encoding() const noexcept
4354 __codecvt_utf8_utf16
<wchar_t>::do_always_noconv() const noexcept
4360 __codecvt_utf8_utf16
<wchar_t>::do_length(state_type
&,
4361 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4363 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4364 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4365 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4369 __codecvt_utf8_utf16
<wchar_t>::do_max_length() const noexcept
4371 if (__mode_
& consume_header
)
4375 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4377 // __codecvt_utf8_utf16<char16_t>
4379 __codecvt_utf8_utf16
<char16_t
>::result
4380 __codecvt_utf8_utf16
<char16_t
>::do_out(state_type
&,
4381 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4382 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4384 const uint16_t* _frm
= reinterpret_cast<const uint16_t*>(frm
);
4385 const uint16_t* _frm_end
= reinterpret_cast<const uint16_t*>(frm_end
);
4386 const uint16_t* _frm_nxt
= _frm
;
4387 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4388 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4389 uint8_t* _to_nxt
= _to
;
4390 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4391 __maxcode_
, __mode_
);
4392 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4393 to_nxt
= to
+ (_to_nxt
- _to
);
4397 __codecvt_utf8_utf16
<char16_t
>::result
4398 __codecvt_utf8_utf16
<char16_t
>::do_in(state_type
&,
4399 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4400 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4402 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4403 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4404 const uint8_t* _frm_nxt
= _frm
;
4405 uint16_t* _to
= reinterpret_cast<uint16_t*>(to
);
4406 uint16_t* _to_end
= reinterpret_cast<uint16_t*>(to_end
);
4407 uint16_t* _to_nxt
= _to
;
4408 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4409 __maxcode_
, __mode_
);
4410 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4411 to_nxt
= to
+ (_to_nxt
- _to
);
4415 __codecvt_utf8_utf16
<char16_t
>::result
4416 __codecvt_utf8_utf16
<char16_t
>::do_unshift(state_type
&,
4417 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4424 __codecvt_utf8_utf16
<char16_t
>::do_encoding() const noexcept
4430 __codecvt_utf8_utf16
<char16_t
>::do_always_noconv() const noexcept
4436 __codecvt_utf8_utf16
<char16_t
>::do_length(state_type
&,
4437 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4439 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4440 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4441 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4444 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4446 __codecvt_utf8_utf16
<char16_t
>::do_max_length() const noexcept
4448 if (__mode_
& consume_header
)
4452 _LIBCPP_SUPPRESS_DEPRECATED_POP
4454 // __codecvt_utf8_utf16<char32_t>
4456 __codecvt_utf8_utf16
<char32_t
>::result
4457 __codecvt_utf8_utf16
<char32_t
>::do_out(state_type
&,
4458 const intern_type
* frm
, const intern_type
* frm_end
, const intern_type
*& frm_nxt
,
4459 extern_type
* to
, extern_type
* to_end
, extern_type
*& to_nxt
) const
4461 const uint32_t* _frm
= reinterpret_cast<const uint32_t*>(frm
);
4462 const uint32_t* _frm_end
= reinterpret_cast<const uint32_t*>(frm_end
);
4463 const uint32_t* _frm_nxt
= _frm
;
4464 uint8_t* _to
= reinterpret_cast<uint8_t*>(to
);
4465 uint8_t* _to_end
= reinterpret_cast<uint8_t*>(to_end
);
4466 uint8_t* _to_nxt
= _to
;
4467 result r
= utf16_to_utf8(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4468 __maxcode_
, __mode_
);
4469 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4470 to_nxt
= to
+ (_to_nxt
- _to
);
4474 __codecvt_utf8_utf16
<char32_t
>::result
4475 __codecvt_utf8_utf16
<char32_t
>::do_in(state_type
&,
4476 const extern_type
* frm
, const extern_type
* frm_end
, const extern_type
*& frm_nxt
,
4477 intern_type
* to
, intern_type
* to_end
, intern_type
*& to_nxt
) const
4479 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4480 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4481 const uint8_t* _frm_nxt
= _frm
;
4482 uint32_t* _to
= reinterpret_cast<uint32_t*>(to
);
4483 uint32_t* _to_end
= reinterpret_cast<uint32_t*>(to_end
);
4484 uint32_t* _to_nxt
= _to
;
4485 result r
= utf8_to_utf16(_frm
, _frm_end
, _frm_nxt
, _to
, _to_end
, _to_nxt
,
4486 __maxcode_
, __mode_
);
4487 frm_nxt
= frm
+ (_frm_nxt
- _frm
);
4488 to_nxt
= to
+ (_to_nxt
- _to
);
4492 __codecvt_utf8_utf16
<char32_t
>::result
4493 __codecvt_utf8_utf16
<char32_t
>::do_unshift(state_type
&,
4494 extern_type
* to
, extern_type
*, extern_type
*& to_nxt
) const
4501 __codecvt_utf8_utf16
<char32_t
>::do_encoding() const noexcept
4507 __codecvt_utf8_utf16
<char32_t
>::do_always_noconv() const noexcept
4513 __codecvt_utf8_utf16
<char32_t
>::do_length(state_type
&,
4514 const extern_type
* frm
, const extern_type
* frm_end
, size_t mx
) const
4516 const uint8_t* _frm
= reinterpret_cast<const uint8_t*>(frm
);
4517 const uint8_t* _frm_end
= reinterpret_cast<const uint8_t*>(frm_end
);
4518 return utf8_to_utf16_length(_frm
, _frm_end
, mx
, __maxcode_
, __mode_
);
4521 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4523 __codecvt_utf8_utf16
<char32_t
>::do_max_length() const noexcept
4525 if (__mode_
& consume_header
)
4529 _LIBCPP_SUPPRESS_DEPRECATED_POP
4531 // __narrow_to_utf8<16>
4533 __narrow_to_utf8
<16>::~__narrow_to_utf8()
4537 // __narrow_to_utf8<32>
4539 __narrow_to_utf8
<32>::~__narrow_to_utf8()
4543 // __widen_from_utf8<16>
4545 __widen_from_utf8
<16>::~__widen_from_utf8()
4549 // __widen_from_utf8<32>
4551 __widen_from_utf8
<32>::~__widen_from_utf8()
4555 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4556 static bool checked_string_to_wchar_convert(wchar_t& dest
,
4563 size_t ret
= __libcpp_mbrtowc_l(&out
, ptr
, strlen(ptr
), &mb
, loc
);
4564 if (ret
== static_cast<size_t>(-1) || ret
== static_cast<size_t>(-2)) {
4570 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4572 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4573 static bool is_narrow_non_breaking_space(const char* ptr
) {
4574 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4575 return ptr
[0] == '\xe2' && ptr
[1] == '\x80' && ptr
[2] == '\xaf';
4578 static bool is_non_breaking_space(const char* ptr
) {
4579 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4580 return ptr
[0] == '\xc2' && ptr
[1] == '\xa0';
4582 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4584 static bool checked_string_to_char_convert(char& dest
,
4594 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4595 // First convert the MBS into a wide char then attempt to narrow it using
4598 if (!checked_string_to_wchar_convert(wout
, ptr
, __loc
))
4601 if ((res
= __libcpp_wctob_l(wout
, __loc
)) != char_traits
<char>::eof()) {
4605 // FIXME: Work around specific multibyte sequences that we can reasonably
4606 // translate into a different single byte.
4608 case L
'\u202F': // narrow non-breaking space
4609 case L
'\u00A0': // non-breaking space
4615 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4616 // FIXME: Work around specific multibyte sequences that we can reasonably
4617 // translate into a different single byte.
4618 if (is_narrow_non_breaking_space(ptr
) || is_non_breaking_space(ptr
)) {
4624 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4625 __libcpp_unreachable();
4629 // numpunct<char> && numpunct<wchar_t>
4631 locale::id numpunct
< char >::id
;
4632 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4633 locale::id numpunct
<wchar_t>::id
;
4636 numpunct
<char>::numpunct(size_t refs
)
4637 : locale::facet(refs
),
4638 __decimal_point_('.'),
4639 __thousands_sep_(',')
4643 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4644 numpunct
<wchar_t>::numpunct(size_t refs
)
4645 : locale::facet(refs
),
4646 __decimal_point_(L
'.'),
4647 __thousands_sep_(L
',')
4652 numpunct
<char>::~numpunct()
4656 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4657 numpunct
<wchar_t>::~numpunct()
4662 char numpunct
< char >::do_decimal_point() const {return __decimal_point_
;}
4663 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4664 wchar_t numpunct
<wchar_t>::do_decimal_point() const {return __decimal_point_
;}
4667 char numpunct
< char >::do_thousands_sep() const {return __thousands_sep_
;}
4668 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4669 wchar_t numpunct
<wchar_t>::do_thousands_sep() const {return __thousands_sep_
;}
4672 string numpunct
< char >::do_grouping() const {return __grouping_
;}
4673 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4674 string numpunct
<wchar_t>::do_grouping() const {return __grouping_
;}
4677 string numpunct
< char >::do_truename() const {return "true";}
4678 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4679 wstring numpunct
<wchar_t>::do_truename() const {return L
"true";}
4682 string numpunct
< char >::do_falsename() const {return "false";}
4683 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4684 wstring numpunct
<wchar_t>::do_falsename() const {return L
"false";}
4687 // numpunct_byname<char>
4689 numpunct_byname
<char>::numpunct_byname(const char* nm
, size_t refs
)
4690 : numpunct
<char>(refs
)
4695 numpunct_byname
<char>::numpunct_byname(const string
& nm
, size_t refs
)
4696 : numpunct
<char>(refs
)
4701 numpunct_byname
<char>::~numpunct_byname()
4706 numpunct_byname
<char>::__init(const char* nm
)
4708 typedef numpunct
<char> base
;
4709 if (strcmp(nm
, "C") != 0)
4711 __libcpp_unique_locale
loc(nm
);
4713 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4714 " failed to construct for " + string(nm
));
4716 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4717 if (!checked_string_to_char_convert(__decimal_point_
, lc
->decimal_point
,
4719 __decimal_point_
= base::do_decimal_point();
4720 if (!checked_string_to_char_convert(__thousands_sep_
, lc
->thousands_sep
,
4722 __thousands_sep_
= base::do_thousands_sep();
4723 __grouping_
= lc
->grouping
;
4724 // localization for truename and falsename is not available
4728 // numpunct_byname<wchar_t>
4730 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4731 numpunct_byname
<wchar_t>::numpunct_byname(const char* nm
, size_t refs
)
4732 : numpunct
<wchar_t>(refs
)
4737 numpunct_byname
<wchar_t>::numpunct_byname(const string
& nm
, size_t refs
)
4738 : numpunct
<wchar_t>(refs
)
4743 numpunct_byname
<wchar_t>::~numpunct_byname()
4748 numpunct_byname
<wchar_t>::__init(const char* nm
)
4750 if (strcmp(nm
, "C") != 0)
4752 __libcpp_unique_locale
loc(nm
);
4754 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4755 " failed to construct for " + string(nm
));
4757 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
4758 checked_string_to_wchar_convert(__decimal_point_
, lc
->decimal_point
,
4760 checked_string_to_wchar_convert(__thousands_sep_
, lc
->thousands_sep
,
4762 __grouping_
= lc
->grouping
;
4763 // localization for truename and falsename is not available
4766 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4771 __num_get_base::__get_base(ios_base
& iob
)
4773 ios_base::fmtflags __basefield
= iob
.flags() & ios_base::basefield
;
4774 if (__basefield
== ios_base::oct
)
4776 else if (__basefield
== ios_base::hex
)
4778 else if (__basefield
== 0)
4783 const char __num_get_base::__src
[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4786 __check_grouping(const string
& __grouping
, unsigned* __g
, unsigned* __g_end
,
4787 ios_base::iostate
& __err
)
4789 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4790 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4791 if (__grouping
.size() != 0 && __g_end
- __g
> 1)
4793 reverse(__g
, __g_end
);
4794 const char* __ig
= __grouping
.data();
4795 const char* __eg
= __ig
+ __grouping
.size();
4796 for (unsigned* __r
= __g
; __r
< __g_end
-1; ++__r
)
4798 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4800 if (static_cast<unsigned>(*__ig
) != *__r
)
4802 __err
= ios_base::failbit
;
4806 if (__eg
- __ig
> 1)
4809 if (0 < *__ig
&& *__ig
< numeric_limits
<char>::max())
4811 if (static_cast<unsigned>(*__ig
) < __g_end
[-1] || __g_end
[-1] == 0)
4812 __err
= ios_base::failbit
;
4818 __num_put_base::__format_int(char* __fmtp
, const char* __len
, bool __signd
,
4819 ios_base::fmtflags __flags
)
4821 if ((__flags
& ios_base::showpos
) &&
4822 (__flags
& ios_base::basefield
) != ios_base::oct
&&
4823 (__flags
& ios_base::basefield
) != ios_base::hex
&&
4826 if (__flags
& ios_base::showbase
)
4829 *__fmtp
++ = *__len
++;
4830 if ((__flags
& ios_base::basefield
) == ios_base::oct
)
4832 else if ((__flags
& ios_base::basefield
) == ios_base::hex
)
4834 if (__flags
& ios_base::uppercase
)
4846 __num_put_base::__format_float(char* __fmtp
, const char* __len
,
4847 ios_base::fmtflags __flags
)
4849 bool specify_precision
= true;
4850 if (__flags
& ios_base::showpos
)
4852 if (__flags
& ios_base::showpoint
)
4854 ios_base::fmtflags floatfield
= __flags
& ios_base::floatfield
;
4855 bool uppercase
= (__flags
& ios_base::uppercase
) != 0;
4856 if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4857 specify_precision
= false;
4864 *__fmtp
++ = *__len
++;
4865 if (floatfield
== ios_base::fixed
)
4872 else if (floatfield
== ios_base::scientific
)
4879 else if (floatfield
== (ios_base::fixed
| ios_base::scientific
))
4893 return specify_precision
;
4897 __num_put_base::__identify_padding(char* __nb
, char* __ne
,
4898 const ios_base
& __iob
)
4900 switch (__iob
.flags() & ios_base::adjustfield
)
4902 case ios_base::internal
:
4903 if (__nb
[0] == '-' || __nb
[0] == '+')
4905 if (__ne
- __nb
>= 2 && __nb
[0] == '0'
4906 && (__nb
[1] == 'x' || __nb
[1] == 'X'))
4909 case ios_base::left
:
4911 case ios_base::right
:
4924 static string weeks
[14];
4925 weeks
[0] = "Sunday";
4926 weeks
[1] = "Monday";
4927 weeks
[2] = "Tuesday";
4928 weeks
[3] = "Wednesday";
4929 weeks
[4] = "Thursday";
4930 weeks
[5] = "Friday";
4931 weeks
[6] = "Saturday";
4942 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4947 static wstring weeks
[14];
4948 weeks
[0] = L
"Sunday";
4949 weeks
[1] = L
"Monday";
4950 weeks
[2] = L
"Tuesday";
4951 weeks
[3] = L
"Wednesday";
4952 weeks
[4] = L
"Thursday";
4953 weeks
[5] = L
"Friday";
4954 weeks
[6] = L
"Saturday";
4968 __time_get_c_storage
<char>::__weeks() const
4970 static const string
* weeks
= init_weeks();
4974 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4977 __time_get_c_storage
<wchar_t>::__weeks() const
4979 static const wstring
* weeks
= init_wweeks();
4988 static string months
[24];
4989 months
[0] = "January";
4990 months
[1] = "February";
4991 months
[2] = "March";
4992 months
[3] = "April";
4996 months
[7] = "August";
4997 months
[8] = "September";
4998 months
[9] = "October";
4999 months
[10] = "November";
5000 months
[11] = "December";
5016 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5021 static wstring months
[24];
5022 months
[0] = L
"January";
5023 months
[1] = L
"February";
5024 months
[2] = L
"March";
5025 months
[3] = L
"April";
5027 months
[5] = L
"June";
5028 months
[6] = L
"July";
5029 months
[7] = L
"August";
5030 months
[8] = L
"September";
5031 months
[9] = L
"October";
5032 months
[10] = L
"November";
5033 months
[11] = L
"December";
5034 months
[12] = L
"Jan";
5035 months
[13] = L
"Feb";
5036 months
[14] = L
"Mar";
5037 months
[15] = L
"Apr";
5038 months
[16] = L
"May";
5039 months
[17] = L
"Jun";
5040 months
[18] = L
"Jul";
5041 months
[19] = L
"Aug";
5042 months
[20] = L
"Sep";
5043 months
[21] = L
"Oct";
5044 months
[22] = L
"Nov";
5045 months
[23] = L
"Dec";
5052 __time_get_c_storage
<char>::__months() const
5054 static const string
* months
= init_months();
5058 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5061 __time_get_c_storage
<wchar_t>::__months() const
5063 static const wstring
* months
= init_wmonths();
5072 static string am_pm
[2];
5078 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5083 static wstring am_pm
[2];
5092 __time_get_c_storage
<char>::__am_pm() const
5094 static const string
* am_pm
= init_am_pm();
5098 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5101 __time_get_c_storage
<wchar_t>::__am_pm() const
5103 static const wstring
* am_pm
= init_wam_pm();
5110 __time_get_c_storage
<char>::__x() const
5112 static string
s("%m/%d/%y");
5116 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5119 __time_get_c_storage
<wchar_t>::__x() const
5121 static wstring
s(L
"%m/%d/%y");
5128 __time_get_c_storage
<char>::__X() const
5130 static string
s("%H:%M:%S");
5134 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5137 __time_get_c_storage
<wchar_t>::__X() const
5139 static wstring
s(L
"%H:%M:%S");
5146 __time_get_c_storage
<char>::__c() const
5148 static string
s("%a %b %d %H:%M:%S %Y");
5152 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5155 __time_get_c_storage
<wchar_t>::__c() const
5157 static wstring
s(L
"%a %b %d %H:%M:%S %Y");
5164 __time_get_c_storage
<char>::__r() const
5166 static string
s("%I:%M:%S %p");
5170 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5173 __time_get_c_storage
<wchar_t>::__r() const
5175 static wstring
s(L
"%I:%M:%S %p");
5182 __time_get::__time_get(const char* nm
)
5183 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5186 __throw_runtime_error("time_get_byname"
5187 " failed to construct for " + string(nm
));
5190 __time_get::__time_get(const string
& nm
)
5191 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5194 __throw_runtime_error("time_get_byname"
5195 " failed to construct for " + nm
);
5198 __time_get::~__time_get()
5203 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5207 __time_get_storage
<char>::__analyze(char fmt
, const ctype
<char>& ct
)
5223 size_t n
= strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5229 if (ct
.is(ctype_base::space
, *bb
))
5231 result
.push_back(' ');
5232 for (++bb
; bb
!= be
&& ct
.is(ctype_base::space
, *bb
); ++bb
)
5237 ios_base::iostate err
= ios_base::goodbit
;
5238 ptrdiff_t i
= __scan_keyword(w
, be
, this->__weeks_
, this->__weeks_
+14,
5243 result
.push_back('%');
5245 result
.push_back('A');
5247 result
.push_back('a');
5252 i
= __scan_keyword(w
, be
, this->__months_
, this->__months_
+24,
5257 result
.push_back('%');
5259 result
.push_back('B');
5261 result
.push_back('b');
5262 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5263 result
.back() = 'm';
5267 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5270 i
= __scan_keyword(w
, be
, this->__am_pm_
, this->__am_pm_
+2,
5271 ct
, err
, false) - this->__am_pm_
;
5274 result
.push_back('%');
5275 result
.push_back('p');
5281 if (ct
.is(ctype_base::digit
, *bb
))
5283 switch(__get_up_to_n_digits(bb
, be
, err
, ct
, 4))
5286 result
.push_back('%');
5287 result
.push_back('w');
5290 result
.push_back('%');
5291 result
.push_back('u');
5294 result
.push_back('%');
5295 result
.push_back('I');
5298 result
.push_back('%');
5299 result
.push_back('m');
5302 result
.push_back('%');
5303 result
.push_back('H');
5306 result
.push_back('%');
5307 result
.push_back('d');
5310 result
.push_back('%');
5311 result
.push_back('M');
5314 result
.push_back('%');
5315 result
.push_back('S');
5318 result
.push_back('%');
5319 result
.push_back('y');
5322 result
.push_back('%');
5323 result
.push_back('j');
5326 result
.push_back('%');
5327 result
.push_back('Y');
5330 for (; w
!= bb
; ++w
)
5331 result
.push_back(*w
);
5338 result
.push_back('%');
5339 result
.push_back('%');
5343 result
.push_back(*bb
);
5349 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5351 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5354 __time_get_storage
<wchar_t>::__analyze(char fmt
, const ctype
<wchar_t>& ct
)
5370 strftime_l(buf
, countof(buf
), f
, &t
, __loc_
);
5372 wchar_t* wbb
= wbuf
;
5374 const char* bb
= buf
;
5375 size_t j
= __libcpp_mbsrtowcs_l( wbb
, &bb
, countof(wbuf
), &mb
, __loc_
);
5376 if (j
== size_t(-1))
5377 __throw_runtime_error("locale not supported");
5378 wchar_t* wbe
= wbb
+ j
;
5382 if (ct
.is(ctype_base::space
, *wbb
))
5384 result
.push_back(L
' ');
5385 for (++wbb
; wbb
!= wbe
&& ct
.is(ctype_base::space
, *wbb
); ++wbb
)
5390 ios_base::iostate err
= ios_base::goodbit
;
5391 ptrdiff_t i
= __scan_keyword(w
, wbe
, this->__weeks_
, this->__weeks_
+14,
5396 result
.push_back(L
'%');
5398 result
.push_back(L
'A');
5400 result
.push_back(L
'a');
5405 i
= __scan_keyword(w
, wbe
, this->__months_
, this->__months_
+24,
5410 result
.push_back(L
'%');
5412 result
.push_back(L
'B');
5414 result
.push_back(L
'b');
5415 if (fmt
== 'x' && ct
.is(ctype_base::digit
, this->__months_
[i
][0]))
5416 result
.back() = L
'm';
5420 if (this->__am_pm_
[0].size() + this->__am_pm_
[1].size() > 0)
5423 i
= __scan_keyword(w
, wbe
, this->__am_pm_
, this->__am_pm_
+2,
5424 ct
, err
, false) - this->__am_pm_
;
5427 result
.push_back(L
'%');
5428 result
.push_back(L
'p');
5434 if (ct
.is(ctype_base::digit
, *wbb
))
5436 switch(__get_up_to_n_digits(wbb
, wbe
, err
, ct
, 4))
5439 result
.push_back(L
'%');
5440 result
.push_back(L
'w');
5443 result
.push_back(L
'%');
5444 result
.push_back(L
'u');
5447 result
.push_back(L
'%');
5448 result
.push_back(L
'I');
5451 result
.push_back(L
'%');
5452 result
.push_back(L
'm');
5455 result
.push_back(L
'%');
5456 result
.push_back(L
'H');
5459 result
.push_back(L
'%');
5460 result
.push_back(L
'd');
5463 result
.push_back(L
'%');
5464 result
.push_back(L
'M');
5467 result
.push_back(L
'%');
5468 result
.push_back(L
'S');
5471 result
.push_back(L
'%');
5472 result
.push_back(L
'y');
5475 result
.push_back(L
'%');
5476 result
.push_back(L
'j');
5479 result
.push_back(L
'%');
5480 result
.push_back(L
'Y');
5483 for (; w
!= wbb
; ++w
)
5484 result
.push_back(*w
);
5489 if (ct
.narrow(*wbb
, 0) == '%')
5491 result
.push_back(L
'%');
5492 result
.push_back(L
'%');
5496 result
.push_back(*wbb
);
5501 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5505 __time_get_storage
<char>::init(const ctype
<char>& ct
)
5510 for (int i
= 0; i
< 7; ++i
)
5513 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5515 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5516 __weeks_
[i
+7] = buf
;
5519 for (int i
= 0; i
< 12; ++i
)
5522 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5524 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5525 __months_
[i
+12] = buf
;
5529 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5532 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5534 __c_
= __analyze('c', ct
);
5535 __r_
= __analyze('r', ct
);
5536 __x_
= __analyze('x', ct
);
5537 __X_
= __analyze('X', ct
);
5540 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5543 __time_get_storage
<wchar_t>::init(const ctype
<wchar_t>& ct
)
5551 for (int i
= 0; i
< 7; ++i
)
5554 strftime_l(buf
, countof(buf
), "%A", &t
, __loc_
);
5556 const char* bb
= buf
;
5557 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5558 if (j
== size_t(-1) || j
== 0)
5559 __throw_runtime_error("locale not supported");
5561 __weeks_
[i
].assign(wbuf
, wbe
);
5562 strftime_l(buf
, countof(buf
), "%a", &t
, __loc_
);
5565 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5566 if (j
== size_t(-1) || j
== 0)
5567 __throw_runtime_error("locale not supported");
5569 __weeks_
[i
+7].assign(wbuf
, wbe
);
5572 for (int i
= 0; i
< 12; ++i
)
5575 strftime_l(buf
, countof(buf
), "%B", &t
, __loc_
);
5577 const char* bb
= buf
;
5578 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5579 if (j
== size_t(-1) || j
== 0)
5580 __throw_runtime_error("locale not supported");
5582 __months_
[i
].assign(wbuf
, wbe
);
5583 strftime_l(buf
, countof(buf
), "%b", &t
, __loc_
);
5586 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5587 if (j
== size_t(-1) || j
== 0)
5588 __throw_runtime_error("locale not supported");
5590 __months_
[i
+12].assign(wbuf
, wbe
);
5594 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5596 const char* bb
= buf
;
5597 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5598 if (j
== size_t(-1))
5599 __throw_runtime_error("locale not supported");
5601 __am_pm_
[0].assign(wbuf
, wbe
);
5603 strftime_l(buf
, countof(buf
), "%p", &t
, __loc_
);
5606 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, __loc_
);
5607 if (j
== size_t(-1))
5608 __throw_runtime_error("locale not supported");
5610 __am_pm_
[1].assign(wbuf
, wbe
);
5611 __c_
= __analyze('c', ct
);
5612 __r_
= __analyze('r', ct
);
5613 __x_
= __analyze('x', ct
);
5614 __X_
= __analyze('X', ct
);
5616 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5618 template <class CharT
>
5619 struct _LIBCPP_HIDDEN __time_get_temp
5620 : public ctype_byname
<CharT
>
5622 explicit __time_get_temp(const char* nm
)
5623 : ctype_byname
<CharT
>(nm
, 1) {}
5624 explicit __time_get_temp(const string
& nm
)
5625 : ctype_byname
<CharT
>(nm
, 1) {}
5629 __time_get_storage
<char>::__time_get_storage(const char* __nm
)
5632 const __time_get_temp
<char> ct(__nm
);
5637 __time_get_storage
<char>::__time_get_storage(const string
& __nm
)
5640 const __time_get_temp
<char> ct(__nm
);
5644 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5646 __time_get_storage
<wchar_t>::__time_get_storage(const char* __nm
)
5649 const __time_get_temp
<wchar_t> ct(__nm
);
5654 __time_get_storage
<wchar_t>::__time_get_storage(const string
& __nm
)
5657 const __time_get_temp
<wchar_t> ct(__nm
);
5660 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5663 time_base::dateorder
5664 __time_get_storage
<char>::__do_date_order() const
5667 for (i
= 0; i
< __x_
.size(); ++i
)
5675 for (++i
; i
< __x_
.size(); ++i
)
5678 if (i
== __x_
.size())
5684 for (++i
; i
< __x_
.size(); ++i
)
5687 if (i
== __x_
.size())
5691 return time_base::ymd
;
5694 for (++i
; i
< __x_
.size(); ++i
)
5697 if (i
== __x_
.size())
5701 return time_base::ydm
;
5706 for (++i
; i
< __x_
.size(); ++i
)
5709 if (i
== __x_
.size())
5714 for (++i
; i
< __x_
.size(); ++i
)
5717 if (i
== __x_
.size())
5720 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5721 return time_base::mdy
;
5726 for (++i
; i
< __x_
.size(); ++i
)
5729 if (i
== __x_
.size())
5734 for (++i
; i
< __x_
.size(); ++i
)
5737 if (i
== __x_
.size())
5740 if (__x_
[i
] == 'y' || __x_
[i
] == 'Y')
5741 return time_base::dmy
;
5746 return time_base::no_order
;
5749 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5751 time_base::dateorder
5752 __time_get_storage
<wchar_t>::__do_date_order() const
5755 for (i
= 0; i
< __x_
.size(); ++i
)
5756 if (__x_
[i
] == L
'%')
5763 for (++i
; i
< __x_
.size(); ++i
)
5764 if (__x_
[i
] == L
'%')
5766 if (i
== __x_
.size())
5772 for (++i
; i
< __x_
.size(); ++i
)
5773 if (__x_
[i
] == L
'%')
5775 if (i
== __x_
.size())
5778 if (__x_
[i
] == L
'd')
5779 return time_base::ymd
;
5782 for (++i
; i
< __x_
.size(); ++i
)
5783 if (__x_
[i
] == L
'%')
5785 if (i
== __x_
.size())
5788 if (__x_
[i
] == L
'm')
5789 return time_base::ydm
;
5794 for (++i
; i
< __x_
.size(); ++i
)
5795 if (__x_
[i
] == L
'%')
5797 if (i
== __x_
.size())
5800 if (__x_
[i
] == L
'd')
5802 for (++i
; i
< __x_
.size(); ++i
)
5803 if (__x_
[i
] == L
'%')
5805 if (i
== __x_
.size())
5808 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5809 return time_base::mdy
;
5814 for (++i
; i
< __x_
.size(); ++i
)
5815 if (__x_
[i
] == L
'%')
5817 if (i
== __x_
.size())
5820 if (__x_
[i
] == L
'm')
5822 for (++i
; i
< __x_
.size(); ++i
)
5823 if (__x_
[i
] == L
'%')
5825 if (i
== __x_
.size())
5828 if (__x_
[i
] == L
'y' || __x_
[i
] == L
'Y')
5829 return time_base::dmy
;
5834 return time_base::no_order
;
5836 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5840 __time_put::__time_put(const char* nm
)
5841 : __loc_(newlocale(LC_ALL_MASK
, nm
, 0))
5844 __throw_runtime_error("time_put_byname"
5845 " failed to construct for " + string(nm
));
5848 __time_put::__time_put(const string
& nm
)
5849 : __loc_(newlocale(LC_ALL_MASK
, nm
.c_str(), 0))
5852 __throw_runtime_error("time_put_byname"
5853 " failed to construct for " + nm
);
5856 __time_put::~__time_put()
5858 if (__loc_
!= _LIBCPP_GET_C_LOCALE
)
5863 __time_put::__do_put(char* __nb
, char*& __ne
, const tm
* __tm
,
5864 char __fmt
, char __mod
) const
5866 char fmt
[] = {'%', __fmt
, __mod
, 0};
5868 swap(fmt
[1], fmt
[2]);
5869 size_t n
= strftime_l(__nb
, countof(__nb
, __ne
), fmt
, __tm
, __loc_
);
5873 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5875 __time_put::__do_put(wchar_t* __wb
, wchar_t*& __we
, const tm
* __tm
,
5876 char __fmt
, char __mod
) const
5879 char* __ne
= __nar
+ 100;
5880 __do_put(__nar
, __ne
, __tm
, __fmt
, __mod
);
5882 const char* __nb
= __nar
;
5883 size_t j
= __libcpp_mbsrtowcs_l(__wb
, &__nb
, countof(__wb
, __we
), &mb
, __loc_
);
5884 if (j
== size_t(-1))
5885 __throw_runtime_error("locale not supported");
5888 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5890 // moneypunct_byname
5892 template <class charT
>
5895 __init_pat(money_base::pattern
& pat
, basic_string
<charT
>& __curr_symbol_
,
5896 bool intl
, char cs_precedes
, char sep_by_space
, char sign_posn
,
5899 const char sign
= static_cast<char>(money_base::sign
);
5900 const char space
= static_cast<char>(money_base::space
);
5901 const char none
= static_cast<char>(money_base::none
);
5902 const char symbol
= static_cast<char>(money_base::symbol
);
5903 const char value
= static_cast<char>(money_base::value
);
5904 const bool symbol_contains_sep
= intl
&& __curr_symbol_
.size() == 4;
5906 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5907 // function'. "Space between sign and symbol or value" means that
5908 // if the sign is adjacent to the symbol, there's a space between
5909 // them, and otherwise there's a space between the sign and value.
5911 // C11's localeconv specifies that the fourth character of an
5912 // international curr_symbol is used to separate the sign and
5913 // value when sep_by_space says to do so. C++ can't represent
5914 // that, so we just use a space. When sep_by_space says to
5915 // separate the symbol and value-or-sign with a space, we rearrange the
5916 // curr_symbol to put its spacing character on the correct side of
5919 // We also need to avoid adding an extra space between the sign
5920 // and value when the currency symbol is suppressed (by not
5921 // setting showbase). We match glibc's strfmon by interpreting
5922 // sep_by_space==1 as "omit the space when the currency symbol is
5925 // Users who want to get this right should use ICU instead.
5927 switch (cs_precedes
)
5929 case 0: // value before curr_symbol
5930 if (symbol_contains_sep
) {
5931 // Move the separator to before the symbol, to place it
5932 // between the value and symbol.
5933 rotate(__curr_symbol_
.begin(), __curr_symbol_
.begin() + 3,
5934 __curr_symbol_
.end());
5938 case 0: // Parentheses surround the quantity and currency symbol.
5939 pat
.field
[0] = sign
;
5940 pat
.field
[1] = value
;
5941 pat
.field
[2] = none
; // Any space appears in the symbol.
5942 pat
.field
[3] = symbol
;
5943 switch (sep_by_space
)
5945 case 0: // No space separates the currency symbol and value.
5946 // This case may have changed between C99 and C11;
5947 // assume the currency symbol matches the intention.
5948 case 2: // Space between sign and currency or value.
5949 // The "sign" is two parentheses, so no space here either.
5951 case 1: // Space between currency-and-sign or currency and value.
5952 if (!symbol_contains_sep
) {
5953 // We insert the space into the symbol instead of
5954 // setting pat.field[2]=space so that when
5955 // showbase is not set, the space goes away too.
5956 __curr_symbol_
.insert(0, 1, space_char
);
5963 case 1: // The sign string precedes the quantity and currency symbol.
5964 pat
.field
[0] = sign
;
5965 pat
.field
[3] = symbol
;
5966 switch (sep_by_space
)
5968 case 0: // No space separates the currency symbol and value.
5969 pat
.field
[1] = value
;
5970 pat
.field
[2] = none
;
5972 case 1: // Space between currency-and-sign or currency and value.
5973 pat
.field
[1] = value
;
5974 pat
.field
[2] = none
;
5975 if (!symbol_contains_sep
) {
5976 // We insert the space into the symbol instead of
5977 // setting pat.field[2]=space so that when
5978 // showbase is not set, the space goes away too.
5979 __curr_symbol_
.insert(0, 1, space_char
);
5982 case 2: // Space between sign and currency or value.
5983 pat
.field
[1] = space
;
5984 pat
.field
[2] = value
;
5985 if (symbol_contains_sep
) {
5986 // Remove the separator from the symbol, since it
5987 // has already appeared after the sign.
5988 __curr_symbol_
.erase(__curr_symbol_
.begin());
5995 case 2: // The sign string succeeds the quantity and currency symbol.
5996 pat
.field
[0] = value
;
5997 pat
.field
[3] = sign
;
5998 switch (sep_by_space
)
6000 case 0: // No space separates the currency symbol and value.
6001 pat
.field
[1] = none
;
6002 pat
.field
[2] = symbol
;
6004 case 1: // Space between currency-and-sign or currency and value.
6005 if (!symbol_contains_sep
) {
6006 // We insert the space into the symbol instead of
6007 // setting pat.field[1]=space so that when
6008 // showbase is not set, the space goes away too.
6009 __curr_symbol_
.insert(0, 1, space_char
);
6011 pat
.field
[1] = none
;
6012 pat
.field
[2] = symbol
;
6014 case 2: // Space between sign and currency or value.
6015 pat
.field
[1] = symbol
;
6016 pat
.field
[2] = space
;
6017 if (symbol_contains_sep
) {
6018 // Remove the separator from the symbol, since it
6019 // should not be removed if showbase is absent.
6020 __curr_symbol_
.erase(__curr_symbol_
.begin());
6027 case 3: // The sign string immediately precedes the currency symbol.
6028 pat
.field
[0] = value
;
6029 pat
.field
[3] = symbol
;
6030 switch (sep_by_space
)
6032 case 0: // No space separates the currency symbol and value.
6033 pat
.field
[1] = none
;
6034 pat
.field
[2] = sign
;
6036 case 1: // Space between currency-and-sign or currency and value.
6037 pat
.field
[1] = space
;
6038 pat
.field
[2] = sign
;
6039 if (symbol_contains_sep
) {
6040 // Remove the separator from the symbol, since it
6041 // has already appeared before the sign.
6042 __curr_symbol_
.erase(__curr_symbol_
.begin());
6045 case 2: // Space between sign and currency or value.
6046 pat
.field
[1] = sign
;
6047 pat
.field
[2] = none
;
6048 if (!symbol_contains_sep
) {
6049 // We insert the space into the symbol instead of
6050 // setting pat.field[2]=space so that when
6051 // showbase is not set, the space goes away too.
6052 __curr_symbol_
.insert(0, 1, space_char
);
6059 case 4: // The sign string immediately succeeds the currency symbol.
6060 pat
.field
[0] = value
;
6061 pat
.field
[3] = sign
;
6062 switch (sep_by_space
)
6064 case 0: // No space separates the currency symbol and value.
6065 pat
.field
[1] = none
;
6066 pat
.field
[2] = symbol
;
6068 case 1: // Space between currency-and-sign or currency and value.
6069 pat
.field
[1] = none
;
6070 pat
.field
[2] = symbol
;
6071 if (!symbol_contains_sep
) {
6072 // We insert the space into the symbol instead of
6073 // setting pat.field[1]=space so that when
6074 // showbase is not set, the space goes away too.
6075 __curr_symbol_
.insert(0, 1, space_char
);
6078 case 2: // Space between sign and currency or value.
6079 pat
.field
[1] = symbol
;
6080 pat
.field
[2] = space
;
6081 if (symbol_contains_sep
) {
6082 // Remove the separator from the symbol, since it
6083 // should not disappear when showbase is absent.
6084 __curr_symbol_
.erase(__curr_symbol_
.begin());
6095 case 1: // curr_symbol before value
6098 case 0: // Parentheses surround the quantity and currency symbol.
6099 pat
.field
[0] = sign
;
6100 pat
.field
[1] = symbol
;
6101 pat
.field
[2] = none
; // Any space appears in the symbol.
6102 pat
.field
[3] = value
;
6103 switch (sep_by_space
)
6105 case 0: // No space separates the currency symbol and value.
6106 // This case may have changed between C99 and C11;
6107 // assume the currency symbol matches the intention.
6108 case 2: // Space between sign and currency or value.
6109 // The "sign" is two parentheses, so no space here either.
6111 case 1: // Space between currency-and-sign or currency and value.
6112 if (!symbol_contains_sep
) {
6113 // We insert the space into the symbol instead of
6114 // setting pat.field[2]=space so that when
6115 // showbase is not set, the space goes away too.
6116 __curr_symbol_
.insert(0, 1, space_char
);
6123 case 1: // The sign string precedes the quantity and currency symbol.
6124 pat
.field
[0] = sign
;
6125 pat
.field
[3] = value
;
6126 switch (sep_by_space
)
6128 case 0: // No space separates the currency symbol and value.
6129 pat
.field
[1] = symbol
;
6130 pat
.field
[2] = none
;
6132 case 1: // Space between currency-and-sign or currency and value.
6133 pat
.field
[1] = symbol
;
6134 pat
.field
[2] = none
;
6135 if (!symbol_contains_sep
) {
6136 // We insert the space into the symbol instead of
6137 // setting pat.field[2]=space so that when
6138 // showbase is not set, the space goes away too.
6139 __curr_symbol_
.push_back(space_char
);
6142 case 2: // Space between sign and currency or value.
6143 pat
.field
[1] = space
;
6144 pat
.field
[2] = symbol
;
6145 if (symbol_contains_sep
) {
6146 // Remove the separator from the symbol, since it
6147 // has already appeared after the sign.
6148 __curr_symbol_
.pop_back();
6155 case 2: // The sign string succeeds the quantity and currency symbol.
6156 pat
.field
[0] = symbol
;
6157 pat
.field
[3] = sign
;
6158 switch (sep_by_space
)
6160 case 0: // No space separates the currency symbol and value.
6161 pat
.field
[1] = none
;
6162 pat
.field
[2] = value
;
6164 case 1: // Space between currency-and-sign or currency and value.
6165 pat
.field
[1] = none
;
6166 pat
.field
[2] = value
;
6167 if (!symbol_contains_sep
) {
6168 // We insert the space into the symbol instead of
6169 // setting pat.field[1]=space so that when
6170 // showbase is not set, the space goes away too.
6171 __curr_symbol_
.push_back(space_char
);
6174 case 2: // Space between sign and currency or value.
6175 pat
.field
[1] = value
;
6176 pat
.field
[2] = space
;
6177 if (symbol_contains_sep
) {
6178 // Remove the separator from the symbol, since it
6179 // will appear before the sign.
6180 __curr_symbol_
.pop_back();
6187 case 3: // The sign string immediately precedes the currency symbol.
6188 pat
.field
[0] = sign
;
6189 pat
.field
[3] = value
;
6190 switch (sep_by_space
)
6192 case 0: // No space separates the currency symbol and value.
6193 pat
.field
[1] = symbol
;
6194 pat
.field
[2] = none
;
6196 case 1: // Space between currency-and-sign or currency and value.
6197 pat
.field
[1] = symbol
;
6198 pat
.field
[2] = none
;
6199 if (!symbol_contains_sep
) {
6200 // We insert the space into the symbol instead of
6201 // setting pat.field[2]=space so that when
6202 // showbase is not set, the space goes away too.
6203 __curr_symbol_
.push_back(space_char
);
6206 case 2: // Space between sign and currency or value.
6207 pat
.field
[1] = space
;
6208 pat
.field
[2] = symbol
;
6209 if (symbol_contains_sep
) {
6210 // Remove the separator from the symbol, since it
6211 // has already appeared after the sign.
6212 __curr_symbol_
.pop_back();
6219 case 4: // The sign string immediately succeeds the currency symbol.
6220 pat
.field
[0] = symbol
;
6221 pat
.field
[3] = value
;
6222 switch (sep_by_space
)
6224 case 0: // No space separates the currency symbol and value.
6225 pat
.field
[1] = sign
;
6226 pat
.field
[2] = none
;
6228 case 1: // Space between currency-and-sign or currency and value.
6229 pat
.field
[1] = sign
;
6230 pat
.field
[2] = space
;
6231 if (symbol_contains_sep
) {
6232 // Remove the separator from the symbol, since it
6233 // should not disappear when showbase is absent.
6234 __curr_symbol_
.pop_back();
6237 case 2: // Space between sign and currency or value.
6238 pat
.field
[1] = none
;
6239 pat
.field
[2] = sign
;
6240 if (!symbol_contains_sep
) {
6241 // We insert the space into the symbol instead of
6242 // setting pat.field[1]=space so that when
6243 // showbase is not set, the space goes away too.
6244 __curr_symbol_
.push_back(space_char
);
6258 pat
.field
[0] = symbol
;
6259 pat
.field
[1] = sign
;
6260 pat
.field
[2] = none
;
6261 pat
.field
[3] = value
;
6266 moneypunct_byname
<char, false>::init(const char* nm
)
6268 typedef moneypunct
<char, false> base
;
6269 __libcpp_unique_locale
loc(nm
);
6271 __throw_runtime_error("moneypunct_byname"
6272 " failed to construct for " + string(nm
));
6274 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6275 if (!checked_string_to_char_convert(__decimal_point_
,
6276 lc
->mon_decimal_point
,
6278 __decimal_point_
= base::do_decimal_point();
6279 if (!checked_string_to_char_convert(__thousands_sep_
,
6280 lc
->mon_thousands_sep
,
6282 __thousands_sep_
= base::do_thousands_sep();
6284 __grouping_
= lc
->mon_grouping
;
6285 __curr_symbol_
= lc
->currency_symbol
;
6286 if (lc
->frac_digits
!= CHAR_MAX
)
6287 __frac_digits_
= lc
->frac_digits
;
6289 __frac_digits_
= base::do_frac_digits();
6290 if (lc
->p_sign_posn
== 0)
6291 __positive_sign_
= "()";
6293 __positive_sign_
= lc
->positive_sign
;
6294 if (lc
->n_sign_posn
== 0)
6295 __negative_sign_
= "()";
6297 __negative_sign_
= lc
->negative_sign
;
6298 // Assume the positive and negative formats will want spaces in
6299 // the same places in curr_symbol since there's no way to
6300 // represent anything else.
6301 string_type __dummy_curr_symbol
= __curr_symbol_
;
6302 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6303 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6304 __init_pat(__neg_format_
, __curr_symbol_
, false,
6305 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6310 moneypunct_byname
<char, true>::init(const char* nm
)
6312 typedef moneypunct
<char, true> base
;
6313 __libcpp_unique_locale
loc(nm
);
6315 __throw_runtime_error("moneypunct_byname"
6316 " failed to construct for " + string(nm
));
6318 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6319 if (!checked_string_to_char_convert(__decimal_point_
,
6320 lc
->mon_decimal_point
,
6322 __decimal_point_
= base::do_decimal_point();
6323 if (!checked_string_to_char_convert(__thousands_sep_
,
6324 lc
->mon_thousands_sep
,
6326 __thousands_sep_
= base::do_thousands_sep();
6327 __grouping_
= lc
->mon_grouping
;
6328 __curr_symbol_
= lc
->int_curr_symbol
;
6329 if (lc
->int_frac_digits
!= CHAR_MAX
)
6330 __frac_digits_
= lc
->int_frac_digits
;
6332 __frac_digits_
= base::do_frac_digits();
6333 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6334 if (lc
->p_sign_posn
== 0)
6335 #else // _LIBCPP_MSVCRT
6336 if (lc
->int_p_sign_posn
== 0)
6337 #endif // !_LIBCPP_MSVCRT
6338 __positive_sign_
= "()";
6340 __positive_sign_
= lc
->positive_sign
;
6341 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6342 if(lc
->n_sign_posn
== 0)
6343 #else // _LIBCPP_MSVCRT
6344 if (lc
->int_n_sign_posn
== 0)
6345 #endif // !_LIBCPP_MSVCRT
6346 __negative_sign_
= "()";
6348 __negative_sign_
= lc
->negative_sign
;
6349 // Assume the positive and negative formats will want spaces in
6350 // the same places in curr_symbol since there's no way to
6351 // represent anything else.
6352 string_type __dummy_curr_symbol
= __curr_symbol_
;
6353 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6354 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6355 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, ' ');
6356 __init_pat(__neg_format_
, __curr_symbol_
, true,
6357 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, ' ');
6358 #else // _LIBCPP_MSVCRT
6359 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6360 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6361 lc
->int_p_sign_posn
, ' ');
6362 __init_pat(__neg_format_
, __curr_symbol_
, true,
6363 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6364 lc
->int_n_sign_posn
, ' ');
6365 #endif // !_LIBCPP_MSVCRT
6368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6371 moneypunct_byname
<wchar_t, false>::init(const char* nm
)
6373 typedef moneypunct
<wchar_t, false> base
;
6374 __libcpp_unique_locale
loc(nm
);
6376 __throw_runtime_error("moneypunct_byname"
6377 " failed to construct for " + string(nm
));
6378 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6379 if (!checked_string_to_wchar_convert(__decimal_point_
,
6380 lc
->mon_decimal_point
,
6382 __decimal_point_
= base::do_decimal_point();
6383 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6384 lc
->mon_thousands_sep
,
6386 __thousands_sep_
= base::do_thousands_sep();
6387 __grouping_
= lc
->mon_grouping
;
6390 const char* bb
= lc
->currency_symbol
;
6391 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6392 if (j
== size_t(-1))
6393 __throw_runtime_error("locale not supported");
6394 wchar_t* wbe
= wbuf
+ j
;
6395 __curr_symbol_
.assign(wbuf
, wbe
);
6396 if (lc
->frac_digits
!= CHAR_MAX
)
6397 __frac_digits_
= lc
->frac_digits
;
6399 __frac_digits_
= base::do_frac_digits();
6400 if (lc
->p_sign_posn
== 0)
6401 __positive_sign_
= L
"()";
6405 bb
= lc
->positive_sign
;
6406 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6407 if (j
== size_t(-1))
6408 __throw_runtime_error("locale not supported");
6410 __positive_sign_
.assign(wbuf
, wbe
);
6412 if (lc
->n_sign_posn
== 0)
6413 __negative_sign_
= L
"()";
6417 bb
= lc
->negative_sign
;
6418 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6419 if (j
== size_t(-1))
6420 __throw_runtime_error("locale not supported");
6422 __negative_sign_
.assign(wbuf
, wbe
);
6424 // Assume the positive and negative formats will want spaces in
6425 // the same places in curr_symbol since there's no way to
6426 // represent anything else.
6427 string_type __dummy_curr_symbol
= __curr_symbol_
;
6428 __init_pat(__pos_format_
, __dummy_curr_symbol
, false,
6429 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6430 __init_pat(__neg_format_
, __curr_symbol_
, false,
6431 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6436 moneypunct_byname
<wchar_t, true>::init(const char* nm
)
6438 typedef moneypunct
<wchar_t, true> base
;
6439 __libcpp_unique_locale
loc(nm
);
6441 __throw_runtime_error("moneypunct_byname"
6442 " failed to construct for " + string(nm
));
6444 lconv
* lc
= __libcpp_localeconv_l(loc
.get());
6445 if (!checked_string_to_wchar_convert(__decimal_point_
,
6446 lc
->mon_decimal_point
,
6448 __decimal_point_
= base::do_decimal_point();
6449 if (!checked_string_to_wchar_convert(__thousands_sep_
,
6450 lc
->mon_thousands_sep
,
6452 __thousands_sep_
= base::do_thousands_sep();
6453 __grouping_
= lc
->mon_grouping
;
6456 const char* bb
= lc
->int_curr_symbol
;
6457 size_t j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6458 if (j
== size_t(-1))
6459 __throw_runtime_error("locale not supported");
6460 wchar_t* wbe
= wbuf
+ j
;
6461 __curr_symbol_
.assign(wbuf
, wbe
);
6462 if (lc
->int_frac_digits
!= CHAR_MAX
)
6463 __frac_digits_
= lc
->int_frac_digits
;
6465 __frac_digits_
= base::do_frac_digits();
6466 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6467 if (lc
->p_sign_posn
== 0)
6468 #else // _LIBCPP_MSVCRT
6469 if (lc
->int_p_sign_posn
== 0)
6470 #endif // !_LIBCPP_MSVCRT
6471 __positive_sign_
= L
"()";
6475 bb
= lc
->positive_sign
;
6476 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6477 if (j
== size_t(-1))
6478 __throw_runtime_error("locale not supported");
6480 __positive_sign_
.assign(wbuf
, wbe
);
6482 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6483 if (lc
->n_sign_posn
== 0)
6484 #else // _LIBCPP_MSVCRT
6485 if (lc
->int_n_sign_posn
== 0)
6486 #endif // !_LIBCPP_MSVCRT
6487 __negative_sign_
= L
"()";
6491 bb
= lc
->negative_sign
;
6492 j
= __libcpp_mbsrtowcs_l(wbuf
, &bb
, countof(wbuf
), &mb
, loc
.get());
6493 if (j
== size_t(-1))
6494 __throw_runtime_error("locale not supported");
6496 __negative_sign_
.assign(wbuf
, wbe
);
6498 // Assume the positive and negative formats will want spaces in
6499 // the same places in curr_symbol since there's no way to
6500 // represent anything else.
6501 string_type __dummy_curr_symbol
= __curr_symbol_
;
6502 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6503 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6504 lc
->p_cs_precedes
, lc
->p_sep_by_space
, lc
->p_sign_posn
, L
' ');
6505 __init_pat(__neg_format_
, __curr_symbol_
, true,
6506 lc
->n_cs_precedes
, lc
->n_sep_by_space
, lc
->n_sign_posn
, L
' ');
6507 #else // _LIBCPP_MSVCRT
6508 __init_pat(__pos_format_
, __dummy_curr_symbol
, true,
6509 lc
->int_p_cs_precedes
, lc
->int_p_sep_by_space
,
6510 lc
->int_p_sign_posn
, L
' ');
6511 __init_pat(__neg_format_
, __curr_symbol_
, true,
6512 lc
->int_n_cs_precedes
, lc
->int_n_sep_by_space
,
6513 lc
->int_n_sign_posn
, L
' ');
6514 #endif // !_LIBCPP_MSVCRT
6516 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6518 void __do_nothing(void*) {}
6520 void __throw_runtime_error(const char* msg
)
6522 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6523 throw runtime_error(msg
);
6530 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<char>;
6531 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate
<wchar_t>;)
6533 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<char>;
6534 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get
<wchar_t>;)
6536 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<char>;
6537 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get
<wchar_t>;)
6539 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<char>;
6540 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put
<wchar_t>;)
6542 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<char>;
6543 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put
<wchar_t>;)
6545 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<char>;
6546 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get
<wchar_t>;)
6548 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<char>;
6549 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname
<wchar_t>;)
6551 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<char>;
6552 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put
<wchar_t>;)
6554 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<char>;
6555 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname
<wchar_t>;)
6557 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, false>;
6558 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<char, true>;
6559 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, false>;)
6560 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct
<wchar_t, true>;)
6562 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, false>;
6563 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<char, true>;
6564 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, false>;)
6565 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname
<wchar_t, true>;)
6567 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<char>;
6568 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get
<wchar_t>;)
6570 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<char>;
6571 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get
<wchar_t>;)
6573 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<char>;
6574 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put
<wchar_t>;)
6576 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<char>;
6577 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put
<wchar_t>;)
6579 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<char>;
6580 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages
<wchar_t>;)
6582 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<char>;
6583 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname
<wchar_t>;)
6585 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char, char, mbstate_t>;
6586 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<wchar_t, char, mbstate_t>;)
6587 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char, mbstate_t>;
6588 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char, mbstate_t>;
6589 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6590 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char16_t
, char8_t
, mbstate_t>;
6591 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname
<char32_t
, char8_t
, mbstate_t>;
6594 _LIBCPP_END_NAMESPACE_STD