[LoongArch] Fix register type in FCMP_*_D instructions definition
[llvm-project.git] / libcxx / src / locale.cpp
blobfd0e17a7007b47253ff959841dc71c112bf7f6ac
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 // On Solaris, we need to define something to make the C99 parts of localeconv
10 // visible.
11 #ifdef __sun__
12 #define _LCONV_C99
13 #endif
15 #include <__utility/unreachable.h>
16 #include <algorithm>
17 #include <clocale>
18 #include <codecvt>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <locale>
23 #include <string>
24 #include <type_traits>
25 #include <typeinfo>
26 #include <vector>
28 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
29 # include <cwctype>
30 #endif
32 #if defined(_AIX)
33 # include <sys/localedef.h> // for __lc_ctype_ptr
34 #endif
36 #if defined(_LIBCPP_MSVCRT)
37 # define _CTYPE_DISABLE_MACROS
38 #endif
40 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
41 # include "__support/win32/locale_win32.h"
42 #elif !defined(__BIONIC__) && !defined(__NuttX__)
43 # include <langinfo.h>
44 #endif
46 #include "include/atomic_support.h"
47 #include "include/sso_allocator.h"
49 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
50 // lots of noise in the build log, but no bugs that I know of.
51 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
53 _LIBCPP_PUSH_MACROS
54 #include <__undef_macros>
56 _LIBCPP_BEGIN_NAMESPACE_STD
58 struct __libcpp_unique_locale {
59 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
61 ~__libcpp_unique_locale() {
62 if (__loc_)
63 freelocale(__loc_);
66 explicit operator bool() const { return __loc_; }
68 locale_t& get() { return __loc_; }
70 locale_t __loc_;
71 private:
72 __libcpp_unique_locale(__libcpp_unique_locale const&);
73 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
76 #ifdef __cloc_defined
77 locale_t __cloc() {
78 // In theory this could create a race condition. In practice
79 // the race condition is non-fatal since it will just create
80 // a little resource leak. Better approach would be appreciated.
81 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
82 return result;
84 #endif // __cloc_defined
86 namespace {
88 struct release
90 void operator()(locale::facet* p) {p->__release_shared();}
93 template <class T, class ...Args>
94 T& make(Args ...args)
96 static typename aligned_storage<sizeof(T)>::type buf;
97 auto *obj = ::new (&buf) T(args...);
98 return *obj;
101 template <typename T, size_t N>
102 inline
103 _LIBCPP_CONSTEXPR
104 size_t
105 countof(const T (&)[N])
107 return N;
110 template <typename T>
111 inline
112 _LIBCPP_CONSTEXPR
113 size_t
114 countof(const T * const begin, const T * const end)
116 return static_cast<size_t>(end - begin);
119 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
121 #ifndef _LIBCPP_NO_EXCEPTIONS
122 throw runtime_error(msg);
123 #else
124 (void)msg;
125 _VSTD::abort();
126 #endif
131 const locale::category locale::none;
132 const locale::category locale::collate;
133 const locale::category locale::ctype;
134 const locale::category locale::monetary;
135 const locale::category locale::numeric;
136 const locale::category locale::time;
137 const locale::category locale::messages;
138 const locale::category locale::all;
140 class _LIBCPP_HIDDEN locale::__imp
141 : public facet
143 enum {N = 30};
144 #if defined(_LIBCPP_COMPILER_MSVC)
145 // FIXME: MSVC doesn't support aligned parameters by value.
146 // I can't get the __sso_allocator to work here
147 // for MSVC I think for this reason.
148 vector<facet*> facets_;
149 #else
150 vector<facet*, __sso_allocator<facet*, N> > facets_;
151 #endif
152 string name_;
153 public:
154 explicit __imp(size_t refs = 0);
155 explicit __imp(const string& name, size_t refs = 0);
156 __imp(const __imp&);
157 __imp(const __imp&, const string&, locale::category c);
158 __imp(const __imp& other, const __imp& one, locale::category c);
159 __imp(const __imp&, facet* f, long id);
160 ~__imp();
162 const string& name() const {return name_;}
163 bool has_facet(long id) const
164 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
165 const locale::facet* use_facet(long id) const;
167 static const locale& make_classic();
168 static locale& make_global();
169 private:
170 void install(facet* f, long id);
171 template <class F> void install(F* f) {install(f, f->id.__get());}
172 template <class F> void install_from(const __imp& other);
175 locale::__imp::__imp(size_t refs)
176 : facet(refs),
177 facets_(N),
178 name_("C")
180 facets_.clear();
181 install(&make<_VSTD::collate<char> >(1u));
182 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
183 install(&make<_VSTD::collate<wchar_t> >(1u));
184 #endif
185 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
186 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
187 install(&make<_VSTD::ctype<wchar_t> >(1u));
188 #endif
189 install(&make<codecvt<char, char, mbstate_t> >(1u));
190 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
191 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
192 #endif
193 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
194 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
195 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
196 _LIBCPP_SUPPRESS_DEPRECATED_POP
197 #ifndef _LIBCPP_HAS_NO_CHAR8_T
198 install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
199 install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
200 #endif
201 install(&make<numpunct<char> >(1u));
202 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
203 install(&make<numpunct<wchar_t> >(1u));
204 #endif
205 install(&make<num_get<char> >(1u));
206 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
207 install(&make<num_get<wchar_t> >(1u));
208 #endif
209 install(&make<num_put<char> >(1u));
210 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
211 install(&make<num_put<wchar_t> >(1u));
212 #endif
213 install(&make<moneypunct<char, false> >(1u));
214 install(&make<moneypunct<char, true> >(1u));
215 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
216 install(&make<moneypunct<wchar_t, false> >(1u));
217 install(&make<moneypunct<wchar_t, true> >(1u));
218 #endif
219 install(&make<money_get<char> >(1u));
220 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
221 install(&make<money_get<wchar_t> >(1u));
222 #endif
223 install(&make<money_put<char> >(1u));
224 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
225 install(&make<money_put<wchar_t> >(1u));
226 #endif
227 install(&make<time_get<char> >(1u));
228 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
229 install(&make<time_get<wchar_t> >(1u));
230 #endif
231 install(&make<time_put<char> >(1u));
232 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
233 install(&make<time_put<wchar_t> >(1u));
234 #endif
235 install(&make<_VSTD::messages<char> >(1u));
236 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
237 install(&make<_VSTD::messages<wchar_t> >(1u));
238 #endif
241 locale::__imp::__imp(const string& name, size_t refs)
242 : facet(refs),
243 facets_(N),
244 name_(name)
246 #ifndef _LIBCPP_NO_EXCEPTIONS
249 #endif // _LIBCPP_NO_EXCEPTIONS
250 facets_ = locale::classic().__locale_->facets_;
251 for (unsigned i = 0; i < facets_.size(); ++i)
252 if (facets_[i])
253 facets_[i]->__add_shared();
254 install(new collate_byname<char>(name_));
255 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
256 install(new collate_byname<wchar_t>(name_));
257 #endif
258 install(new ctype_byname<char>(name_));
259 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
260 install(new ctype_byname<wchar_t>(name_));
261 #endif
262 install(new codecvt_byname<char, char, mbstate_t>(name_));
263 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
264 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
265 #endif
266 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
267 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
268 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
269 _LIBCPP_SUPPRESS_DEPRECATED_POP
270 #ifndef _LIBCPP_HAS_NO_CHAR8_T
271 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
272 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
273 #endif
274 install(new numpunct_byname<char>(name_));
275 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
276 install(new numpunct_byname<wchar_t>(name_));
277 #endif
278 install(new moneypunct_byname<char, false>(name_));
279 install(new moneypunct_byname<char, true>(name_));
280 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
281 install(new moneypunct_byname<wchar_t, false>(name_));
282 install(new moneypunct_byname<wchar_t, true>(name_));
283 #endif
284 install(new time_get_byname<char>(name_));
285 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
286 install(new time_get_byname<wchar_t>(name_));
287 #endif
288 install(new time_put_byname<char>(name_));
289 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
290 install(new time_put_byname<wchar_t>(name_));
291 #endif
292 install(new messages_byname<char>(name_));
293 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
294 install(new messages_byname<wchar_t>(name_));
295 #endif
296 #ifndef _LIBCPP_NO_EXCEPTIONS
298 catch (...)
300 for (unsigned i = 0; i < facets_.size(); ++i)
301 if (facets_[i])
302 facets_[i]->__release_shared();
303 throw;
305 #endif // _LIBCPP_NO_EXCEPTIONS
308 locale::__imp::__imp(const __imp& other)
309 : facets_(max<size_t>(N, other.facets_.size())),
310 name_(other.name_)
312 facets_ = other.facets_;
313 for (unsigned i = 0; i < facets_.size(); ++i)
314 if (facets_[i])
315 facets_[i]->__add_shared();
318 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
319 : facets_(N),
320 name_("*")
322 facets_ = other.facets_;
323 for (unsigned i = 0; i < facets_.size(); ++i)
324 if (facets_[i])
325 facets_[i]->__add_shared();
326 #ifndef _LIBCPP_NO_EXCEPTIONS
329 #endif // _LIBCPP_NO_EXCEPTIONS
330 if (c & locale::collate)
332 install(new collate_byname<char>(name));
333 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
334 install(new collate_byname<wchar_t>(name));
335 #endif
337 if (c & locale::ctype)
339 install(new ctype_byname<char>(name));
340 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
341 install(new ctype_byname<wchar_t>(name));
342 #endif
343 install(new codecvt_byname<char, char, mbstate_t>(name));
344 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
345 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
346 #endif
347 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
348 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
349 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
350 _LIBCPP_SUPPRESS_DEPRECATED_POP
351 #ifndef _LIBCPP_HAS_NO_CHAR8_T
352 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
353 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
354 #endif
356 if (c & locale::monetary)
358 install(new moneypunct_byname<char, false>(name));
359 install(new moneypunct_byname<char, true>(name));
360 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
361 install(new moneypunct_byname<wchar_t, false>(name));
362 install(new moneypunct_byname<wchar_t, true>(name));
363 #endif
365 if (c & locale::numeric)
367 install(new numpunct_byname<char>(name));
368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
369 install(new numpunct_byname<wchar_t>(name));
370 #endif
372 if (c & locale::time)
374 install(new time_get_byname<char>(name));
375 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
376 install(new time_get_byname<wchar_t>(name));
377 #endif
378 install(new time_put_byname<char>(name));
379 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
380 install(new time_put_byname<wchar_t>(name));
381 #endif
383 if (c & locale::messages)
385 install(new messages_byname<char>(name));
386 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
387 install(new messages_byname<wchar_t>(name));
388 #endif
390 #ifndef _LIBCPP_NO_EXCEPTIONS
392 catch (...)
394 for (unsigned i = 0; i < facets_.size(); ++i)
395 if (facets_[i])
396 facets_[i]->__release_shared();
397 throw;
399 #endif // _LIBCPP_NO_EXCEPTIONS
402 template<class F>
403 inline
404 void
405 locale::__imp::install_from(const locale::__imp& one)
407 long id = F::id.__get();
408 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
411 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
412 : facets_(N),
413 name_("*")
415 facets_ = other.facets_;
416 for (unsigned i = 0; i < facets_.size(); ++i)
417 if (facets_[i])
418 facets_[i]->__add_shared();
419 #ifndef _LIBCPP_NO_EXCEPTIONS
422 #endif // _LIBCPP_NO_EXCEPTIONS
423 if (c & locale::collate)
425 install_from<_VSTD::collate<char> >(one);
426 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
427 install_from<_VSTD::collate<wchar_t> >(one);
428 #endif
430 if (c & locale::ctype)
432 install_from<_VSTD::ctype<char> >(one);
433 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
434 install_from<_VSTD::ctype<wchar_t> >(one);
435 #endif
436 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
437 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
438 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
439 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
440 _LIBCPP_SUPPRESS_DEPRECATED_POP
441 #ifndef _LIBCPP_HAS_NO_CHAR8_T
442 install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
443 install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
444 #endif
445 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
446 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
447 #endif
449 if (c & locale::monetary)
451 install_from<moneypunct<char, false> >(one);
452 install_from<moneypunct<char, true> >(one);
453 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
454 install_from<moneypunct<wchar_t, false> >(one);
455 install_from<moneypunct<wchar_t, true> >(one);
456 #endif
457 install_from<money_get<char> >(one);
458 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
459 install_from<money_get<wchar_t> >(one);
460 #endif
461 install_from<money_put<char> >(one);
462 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
463 install_from<money_put<wchar_t> >(one);
464 #endif
466 if (c & locale::numeric)
468 install_from<numpunct<char> >(one);
469 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
470 install_from<numpunct<wchar_t> >(one);
471 #endif
472 install_from<num_get<char> >(one);
473 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
474 install_from<num_get<wchar_t> >(one);
475 #endif
476 install_from<num_put<char> >(one);
477 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
478 install_from<num_put<wchar_t> >(one);
479 #endif
481 if (c & locale::time)
483 install_from<time_get<char> >(one);
484 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
485 install_from<time_get<wchar_t> >(one);
486 #endif
487 install_from<time_put<char> >(one);
488 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
489 install_from<time_put<wchar_t> >(one);
490 #endif
492 if (c & locale::messages)
494 install_from<_VSTD::messages<char> >(one);
495 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
496 install_from<_VSTD::messages<wchar_t> >(one);
497 #endif
499 #ifndef _LIBCPP_NO_EXCEPTIONS
501 catch (...)
503 for (unsigned i = 0; i < facets_.size(); ++i)
504 if (facets_[i])
505 facets_[i]->__release_shared();
506 throw;
508 #endif // _LIBCPP_NO_EXCEPTIONS
511 locale::__imp::__imp(const __imp& other, facet* f, long id)
512 : facets_(max<size_t>(N, other.facets_.size()+1)),
513 name_("*")
515 f->__add_shared();
516 unique_ptr<facet, release> hold(f);
517 facets_ = other.facets_;
518 for (unsigned i = 0; i < other.facets_.size(); ++i)
519 if (facets_[i])
520 facets_[i]->__add_shared();
521 install(hold.get(), id);
524 locale::__imp::~__imp()
526 for (unsigned i = 0; i < facets_.size(); ++i)
527 if (facets_[i])
528 facets_[i]->__release_shared();
531 void
532 locale::__imp::install(facet* f, long id)
534 f->__add_shared();
535 unique_ptr<facet, release> hold(f);
536 if (static_cast<size_t>(id) >= facets_.size())
537 facets_.resize(static_cast<size_t>(id+1));
538 if (facets_[static_cast<size_t>(id)])
539 facets_[static_cast<size_t>(id)]->__release_shared();
540 facets_[static_cast<size_t>(id)] = hold.release();
543 const locale::facet*
544 locale::__imp::use_facet(long id) const
546 if (!has_facet(id))
547 __throw_bad_cast();
548 return facets_[static_cast<size_t>(id)];
551 // locale
553 const locale&
554 locale::__imp::make_classic()
556 // only one thread can get in here and it only gets in once
557 static aligned_storage<sizeof(locale)>::type buf;
558 locale* c = reinterpret_cast<locale*>(&buf);
559 c->__locale_ = &make<__imp>(1u);
560 return *c;
563 const locale&
564 locale::classic()
566 static const locale& c = __imp::make_classic();
567 return c;
570 locale&
571 locale::__imp::make_global()
573 // only one thread can get in here and it only gets in once
574 static aligned_storage<sizeof(locale)>::type buf;
575 auto *obj = ::new (&buf) locale(locale::classic());
576 return *obj;
579 locale&
580 locale::__global()
582 static locale& g = __imp::make_global();
583 return g;
586 locale::locale() noexcept
587 : __locale_(__global().__locale_)
589 __locale_->__add_shared();
592 locale::locale(const locale& l) noexcept
593 : __locale_(l.__locale_)
595 __locale_->__add_shared();
598 locale::~locale()
600 __locale_->__release_shared();
603 const locale&
604 locale::operator=(const locale& other) noexcept
606 other.__locale_->__add_shared();
607 __locale_->__release_shared();
608 __locale_ = other.__locale_;
609 return *this;
612 locale::locale(const char* name)
613 : __locale_(name ? new __imp(name)
614 : (__throw_runtime_error("locale constructed with null"), nullptr))
616 __locale_->__add_shared();
619 locale::locale(const string& name)
620 : __locale_(new __imp(name))
622 __locale_->__add_shared();
625 locale::locale(const locale& other, const char* name, category c)
626 : __locale_(name ? new __imp(*other.__locale_, name, c)
627 : (__throw_runtime_error("locale constructed with null"), nullptr))
629 __locale_->__add_shared();
632 locale::locale(const locale& other, const string& name, category c)
633 : __locale_(new __imp(*other.__locale_, name, c))
635 __locale_->__add_shared();
638 locale::locale(const locale& other, const locale& one, category c)
639 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
641 __locale_->__add_shared();
644 string
645 locale::name() const
647 return __locale_->name();
650 void
651 locale::__install_ctor(const locale& other, facet* f, long id)
653 if (f)
654 __locale_ = new __imp(*other.__locale_, f, id);
655 else
656 __locale_ = other.__locale_;
657 __locale_->__add_shared();
660 locale
661 locale::global(const locale& loc)
663 locale& g = __global();
664 locale r = g;
665 g = loc;
666 if (g.name() != "*")
667 setlocale(LC_ALL, g.name().c_str());
668 return r;
671 bool
672 locale::has_facet(id& x) const
674 return __locale_->has_facet(x.__get());
677 const locale::facet*
678 locale::use_facet(id& x) const
680 return __locale_->use_facet(x.__get());
683 bool
684 locale::operator==(const locale& y) const
686 return (__locale_ == y.__locale_)
687 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
690 // locale::facet
692 locale::facet::~facet()
696 void
697 locale::facet::__on_zero_shared() noexcept
699 delete this;
702 // locale::id
704 int32_t locale::id::__next_id = 0;
706 namespace
709 class __fake_bind
711 locale::id* id_;
712 void (locale::id::* pmf_)();
713 public:
714 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
715 : id_(id), pmf_(pmf) {}
717 void operator()() const
719 (id_->*pmf_)();
725 long
726 locale::id::__get()
728 call_once(__flag_, __fake_bind(&locale::id::__init, this));
729 return __id_ - 1;
732 void
733 locale::id::__init()
735 __id_ = __libcpp_atomic_add(&__next_id, 1);
738 // template <> class collate_byname<char>
740 collate_byname<char>::collate_byname(const char* n, size_t refs)
741 : collate<char>(refs),
742 __l(newlocale(LC_ALL_MASK, n, 0))
744 if (__l == 0)
745 __throw_runtime_error("collate_byname<char>::collate_byname"
746 " failed to construct for " + string(n));
749 collate_byname<char>::collate_byname(const string& name, size_t refs)
750 : collate<char>(refs),
751 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
753 if (__l == 0)
754 __throw_runtime_error("collate_byname<char>::collate_byname"
755 " failed to construct for " + name);
758 collate_byname<char>::~collate_byname()
760 freelocale(__l);
764 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
765 const char_type* __lo2, const char_type* __hi2) const
767 string_type lhs(__lo1, __hi1);
768 string_type rhs(__lo2, __hi2);
769 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
770 if (r < 0)
771 return -1;
772 if (r > 0)
773 return 1;
774 return r;
777 collate_byname<char>::string_type
778 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
780 const string_type in(lo, hi);
781 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
782 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
783 return out;
786 // template <> class collate_byname<wchar_t>
788 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
789 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
790 : collate<wchar_t>(refs),
791 __l(newlocale(LC_ALL_MASK, n, 0))
793 if (__l == 0)
794 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
795 " failed to construct for " + string(n));
798 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
799 : collate<wchar_t>(refs),
800 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
802 if (__l == 0)
803 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
804 " failed to construct for " + name);
807 collate_byname<wchar_t>::~collate_byname()
809 freelocale(__l);
813 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
814 const char_type* __lo2, const char_type* __hi2) const
816 string_type lhs(__lo1, __hi1);
817 string_type rhs(__lo2, __hi2);
818 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
819 if (r < 0)
820 return -1;
821 if (r > 0)
822 return 1;
823 return r;
826 collate_byname<wchar_t>::string_type
827 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
829 const string_type in(lo, hi);
830 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
831 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
832 return out;
834 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
836 const ctype_base::mask ctype_base::space;
837 const ctype_base::mask ctype_base::print;
838 const ctype_base::mask ctype_base::cntrl;
839 const ctype_base::mask ctype_base::upper;
840 const ctype_base::mask ctype_base::lower;
841 const ctype_base::mask ctype_base::alpha;
842 const ctype_base::mask ctype_base::digit;
843 const ctype_base::mask ctype_base::punct;
844 const ctype_base::mask ctype_base::xdigit;
845 const ctype_base::mask ctype_base::blank;
846 const ctype_base::mask ctype_base::alnum;
847 const ctype_base::mask ctype_base::graph;
849 // template <> class ctype<wchar_t>;
851 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
852 locale::id ctype<wchar_t>::id;
854 ctype<wchar_t>::~ctype()
858 bool
859 ctype<wchar_t>::do_is(mask m, char_type c) const
861 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
864 const wchar_t*
865 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
867 for (; low != high; ++low, ++vec)
868 *vec = static_cast<mask>(isascii(*low) ?
869 ctype<char>::classic_table()[*low] : 0);
870 return low;
873 const wchar_t*
874 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
876 for (; low != high; ++low)
877 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
878 break;
879 return low;
882 const wchar_t*
883 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
885 for (; low != high; ++low)
886 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
887 break;
888 return low;
891 wchar_t
892 ctype<wchar_t>::do_toupper(char_type c) const
894 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
895 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
896 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
897 defined(__NetBSD__) || defined(__MVS__)
898 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
899 #else
900 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
901 #endif
904 const wchar_t*
905 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
907 for (; low != high; ++low)
908 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
909 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
910 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
911 defined(__NetBSD__) || defined(__MVS__)
912 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
913 : *low;
914 #else
915 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
916 #endif
917 return low;
920 wchar_t
921 ctype<wchar_t>::do_tolower(char_type c) const
923 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
924 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
925 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
926 defined(__NetBSD__) || defined(__MVS__)
927 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
928 #else
929 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
930 #endif
933 const wchar_t*
934 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
936 for (; low != high; ++low)
937 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
938 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
939 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
940 defined(__NetBSD__) || defined(__MVS__)
941 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
942 : *low;
943 #else
944 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
945 #endif
946 return low;
949 wchar_t
950 ctype<wchar_t>::do_widen(char c) const
952 return c;
955 const char*
956 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
958 for (; low != high; ++low, ++dest)
959 *dest = *low;
960 return low;
963 char
964 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
966 if (isascii(c))
967 return static_cast<char>(c);
968 return dfault;
971 const wchar_t*
972 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
974 for (; low != high; ++low, ++dest)
975 if (isascii(*low))
976 *dest = static_cast<char>(*low);
977 else
978 *dest = dfault;
979 return low;
981 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
983 // template <> class ctype<char>;
985 locale::id ctype<char>::id;
987 const size_t ctype<char>::table_size;
989 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
990 : locale::facet(refs),
991 __tab_(tab),
992 __del_(del)
994 if (__tab_ == 0)
995 __tab_ = classic_table();
998 ctype<char>::~ctype()
1000 if (__tab_ && __del_)
1001 delete [] __tab_;
1004 char
1005 ctype<char>::do_toupper(char_type c) const
1007 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1008 return isascii(c) ?
1009 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
1010 #elif defined(__NetBSD__)
1011 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
1012 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1013 return isascii(c) ?
1014 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
1015 #else
1016 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
1017 #endif
1020 const char*
1021 ctype<char>::do_toupper(char_type* low, const char_type* high) const
1023 for (; low != high; ++low)
1024 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1025 *low = isascii(*low) ?
1026 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
1027 #elif defined(__NetBSD__)
1028 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
1029 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1030 *low = isascii(*low) ?
1031 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
1032 #else
1033 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
1034 #endif
1035 return low;
1038 char
1039 ctype<char>::do_tolower(char_type c) const
1041 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1042 return isascii(c) ?
1043 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
1044 #elif defined(__NetBSD__)
1045 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
1046 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1047 return isascii(c) ?
1048 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
1049 #else
1050 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
1051 #endif
1054 const char*
1055 ctype<char>::do_tolower(char_type* low, const char_type* high) const
1057 for (; low != high; ++low)
1058 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1059 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
1060 #elif defined(__NetBSD__)
1061 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
1062 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1063 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
1064 #else
1065 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
1066 #endif
1067 return low;
1070 char
1071 ctype<char>::do_widen(char c) const
1073 return c;
1076 const char*
1077 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1079 for (; low != high; ++low, ++dest)
1080 *dest = *low;
1081 return low;
1084 char
1085 ctype<char>::do_narrow(char_type c, char dfault) const
1087 if (isascii(c))
1088 return static_cast<char>(c);
1089 return dfault;
1092 const char*
1093 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1095 for (; low != high; ++low, ++dest)
1096 if (isascii(*low))
1097 *dest = *low;
1098 else
1099 *dest = dfault;
1100 return low;
1103 #if defined(__EMSCRIPTEN__)
1104 extern "C" const unsigned short ** __ctype_b_loc();
1105 extern "C" const int ** __ctype_tolower_loc();
1106 extern "C" const int ** __ctype_toupper_loc();
1107 #endif
1109 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1110 const ctype<char>::mask*
1111 ctype<char>::classic_table() noexcept
1113 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1114 cntrl, cntrl,
1115 cntrl, cntrl,
1116 cntrl, cntrl,
1117 cntrl, cntrl,
1118 cntrl, cntrl | space | blank,
1119 cntrl | space, cntrl | space,
1120 cntrl | space, cntrl | space,
1121 cntrl, cntrl,
1122 cntrl, cntrl,
1123 cntrl, cntrl,
1124 cntrl, cntrl,
1125 cntrl, cntrl,
1126 cntrl, cntrl,
1127 cntrl, cntrl,
1128 cntrl, cntrl,
1129 cntrl, cntrl,
1130 space | blank | print, punct | print,
1131 punct | print, punct | print,
1132 punct | print, punct | print,
1133 punct | print, punct | print,
1134 punct | print, punct | print,
1135 punct | print, punct | print,
1136 punct | print, punct | print,
1137 punct | print, punct | print,
1138 digit | print | xdigit, digit | print | xdigit,
1139 digit | print | xdigit, digit | print | xdigit,
1140 digit | print | xdigit, digit | print | xdigit,
1141 digit | print | xdigit, digit | print | xdigit,
1142 digit | print | xdigit, digit | print | xdigit,
1143 punct | print, punct | print,
1144 punct | print, punct | print,
1145 punct | print, punct | print,
1146 punct | print, upper | xdigit | print | alpha,
1147 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1148 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1149 upper | xdigit | print | alpha, upper | print | alpha,
1150 upper | print | alpha, upper | print | alpha,
1151 upper | print | alpha, upper | print | alpha,
1152 upper | print | alpha, upper | print | alpha,
1153 upper | print | alpha, upper | print | alpha,
1154 upper | print | alpha, upper | print | alpha,
1155 upper | print | alpha, upper | print | alpha,
1156 upper | print | alpha, upper | print | alpha,
1157 upper | print | alpha, upper | print | alpha,
1158 upper | print | alpha, upper | print | alpha,
1159 upper | print | alpha, punct | print,
1160 punct | print, punct | print,
1161 punct | print, punct | print,
1162 punct | print, lower | xdigit | print | alpha,
1163 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1164 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1165 lower | xdigit | print | alpha, lower | print | alpha,
1166 lower | print | alpha, lower | print | alpha,
1167 lower | print | alpha, lower | print | alpha,
1168 lower | print | alpha, lower | print | alpha,
1169 lower | print | alpha, lower | print | alpha,
1170 lower | print | alpha, lower | print | alpha,
1171 lower | print | alpha, lower | print | alpha,
1172 lower | print | alpha, lower | print | alpha,
1173 lower | print | alpha, lower | print | alpha,
1174 lower | print | alpha, lower | print | alpha,
1175 lower | print | alpha, punct | print,
1176 punct | print, punct | print,
1177 punct | print, cntrl,
1178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1187 return builtin_table;
1189 #else
1190 const ctype<char>::mask*
1191 ctype<char>::classic_table() noexcept
1193 #if defined(__APPLE__) || defined(__FreeBSD__)
1194 return _DefaultRuneLocale.__runetype;
1195 #elif defined(__NetBSD__)
1196 return _C_ctype_tab_ + 1;
1197 #elif defined(__GLIBC__)
1198 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1199 #elif defined(__sun__)
1200 return __ctype_mask;
1201 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1202 return __pctype_func();
1203 #elif defined(__EMSCRIPTEN__)
1204 return *__ctype_b_loc();
1205 #elif defined(_NEWLIB_VERSION)
1206 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1207 return _ctype_ + 1;
1208 #elif defined(_AIX)
1209 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1210 #elif defined(__MVS__)
1211 # if defined(__NATIVE_ASCII_F)
1212 return const_cast<const ctype<char>::mask*> (__OBJ_DATA(__lc_ctype_a)->mask);
1213 # else
1214 return const_cast<const ctype<char>::mask*> (__ctypec);
1215 # endif
1216 #else
1217 // Platform not supported: abort so the person doing the port knows what to
1218 // fix
1219 # warning ctype<char>::classic_table() is not implemented
1220 printf("ctype<char>::classic_table() is not implemented\n");
1221 abort();
1222 return NULL;
1223 #endif
1225 #endif
1227 #if defined(__GLIBC__)
1228 const int*
1229 ctype<char>::__classic_lower_table() noexcept
1231 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1234 const int*
1235 ctype<char>::__classic_upper_table() noexcept
1237 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1239 #elif defined(__NetBSD__)
1240 const short*
1241 ctype<char>::__classic_lower_table() noexcept
1243 return _C_tolower_tab_ + 1;
1246 const short*
1247 ctype<char>::__classic_upper_table() noexcept
1249 return _C_toupper_tab_ + 1;
1252 #elif defined(__EMSCRIPTEN__)
1253 const int*
1254 ctype<char>::__classic_lower_table() noexcept
1256 return *__ctype_tolower_loc();
1259 const int*
1260 ctype<char>::__classic_upper_table() noexcept
1262 return *__ctype_toupper_loc();
1264 #elif defined(__MVS__)
1265 const unsigned short*
1266 ctype<char>::__classic_lower_table() _NOEXCEPT
1268 # if defined(__NATIVE_ASCII_F)
1269 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);
1270 # else
1271 return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);
1272 # endif
1274 const unsigned short *
1275 ctype<char>::__classic_upper_table() _NOEXCEPT
1277 # if defined(__NATIVE_ASCII_F)
1278 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);
1279 # else
1280 return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);
1281 # endif
1283 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1285 // template <> class ctype_byname<char>
1287 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1288 : ctype<char>(0, false, refs),
1289 __l(newlocale(LC_ALL_MASK, name, 0))
1291 if (__l == 0)
1292 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1293 " failed to construct for " + string(name));
1296 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1297 : ctype<char>(0, false, refs),
1298 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1300 if (__l == 0)
1301 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1302 " failed to construct for " + name);
1305 ctype_byname<char>::~ctype_byname()
1307 freelocale(__l);
1310 char
1311 ctype_byname<char>::do_toupper(char_type c) const
1313 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1316 const char*
1317 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1319 for (; low != high; ++low)
1320 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1321 return low;
1324 char
1325 ctype_byname<char>::do_tolower(char_type c) const
1327 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1330 const char*
1331 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1333 for (; low != high; ++low)
1334 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1335 return low;
1338 // template <> class ctype_byname<wchar_t>
1340 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1341 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1342 : ctype<wchar_t>(refs),
1343 __l(newlocale(LC_ALL_MASK, name, 0))
1345 if (__l == 0)
1346 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1347 " failed to construct for " + string(name));
1350 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1351 : ctype<wchar_t>(refs),
1352 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1354 if (__l == 0)
1355 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1356 " failed to construct for " + name);
1359 ctype_byname<wchar_t>::~ctype_byname()
1361 freelocale(__l);
1364 bool
1365 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1367 #ifdef _LIBCPP_WCTYPE_IS_MASK
1368 return static_cast<bool>(iswctype_l(c, m, __l));
1369 #else
1370 bool result = false;
1371 wint_t ch = static_cast<wint_t>(c);
1372 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1373 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1374 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1375 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1376 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1377 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1378 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1379 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1380 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1381 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1382 return result;
1383 #endif
1386 const wchar_t*
1387 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1389 for (; low != high; ++low, ++vec)
1391 if (isascii(*low))
1392 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1393 else
1395 *vec = 0;
1396 wint_t ch = static_cast<wint_t>(*low);
1397 if (iswspace_l(ch, __l))
1398 *vec |= space;
1399 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1400 if (iswprint_l(ch, __l))
1401 *vec |= print;
1402 #endif
1403 if (iswcntrl_l(ch, __l))
1404 *vec |= cntrl;
1405 if (iswupper_l(ch, __l))
1406 *vec |= upper;
1407 if (iswlower_l(ch, __l))
1408 *vec |= lower;
1409 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1410 if (iswalpha_l(ch, __l))
1411 *vec |= alpha;
1412 #endif
1413 if (iswdigit_l(ch, __l))
1414 *vec |= digit;
1415 if (iswpunct_l(ch, __l))
1416 *vec |= punct;
1417 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1418 if (iswxdigit_l(ch, __l))
1419 *vec |= xdigit;
1420 #endif
1421 #if !defined(__sun__)
1422 if (iswblank_l(ch, __l))
1423 *vec |= blank;
1424 #endif
1427 return low;
1430 const wchar_t*
1431 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1433 for (; low != high; ++low)
1435 #ifdef _LIBCPP_WCTYPE_IS_MASK
1436 if (iswctype_l(*low, m, __l))
1437 break;
1438 #else
1439 wint_t ch = static_cast<wint_t>(*low);
1440 if ((m & space) == space && iswspace_l(ch, __l)) break;
1441 if ((m & print) == print && iswprint_l(ch, __l)) break;
1442 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1443 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1444 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1445 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1446 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1447 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1448 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1449 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1450 #endif
1452 return low;
1455 const wchar_t*
1456 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1458 for (; low != high; ++low)
1460 #ifdef _LIBCPP_WCTYPE_IS_MASK
1461 if (!iswctype_l(*low, m, __l))
1462 break;
1463 #else
1464 wint_t ch = static_cast<wint_t>(*low);
1465 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1466 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1467 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1468 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1469 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1470 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1471 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1472 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1473 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1474 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1475 break;
1476 #endif
1478 return low;
1481 wchar_t
1482 ctype_byname<wchar_t>::do_toupper(char_type c) const
1484 return towupper_l(c, __l);
1487 const wchar_t*
1488 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1490 for (; low != high; ++low)
1491 *low = towupper_l(*low, __l);
1492 return low;
1495 wchar_t
1496 ctype_byname<wchar_t>::do_tolower(char_type c) const
1498 return towlower_l(c, __l);
1501 const wchar_t*
1502 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1504 for (; low != high; ++low)
1505 *low = towlower_l(*low, __l);
1506 return low;
1509 wchar_t
1510 ctype_byname<wchar_t>::do_widen(char c) const
1512 return __libcpp_btowc_l(c, __l);
1515 const char*
1516 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1518 for (; low != high; ++low, ++dest)
1519 *dest = __libcpp_btowc_l(*low, __l);
1520 return low;
1523 char
1524 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1526 int r = __libcpp_wctob_l(c, __l);
1527 return (r != EOF) ? static_cast<char>(r) : dfault;
1530 const wchar_t*
1531 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1533 for (; low != high; ++low, ++dest)
1535 int r = __libcpp_wctob_l(*low, __l);
1536 *dest = (r != EOF) ? static_cast<char>(r) : dfault;
1538 return low;
1540 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1542 // template <> class codecvt<char, char, mbstate_t>
1544 locale::id codecvt<char, char, mbstate_t>::id;
1546 codecvt<char, char, mbstate_t>::~codecvt()
1550 codecvt<char, char, mbstate_t>::result
1551 codecvt<char, char, mbstate_t>::do_out(state_type&,
1552 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1553 extern_type* to, extern_type*, extern_type*& to_nxt) const
1555 frm_nxt = frm;
1556 to_nxt = to;
1557 return noconv;
1560 codecvt<char, char, mbstate_t>::result
1561 codecvt<char, char, mbstate_t>::do_in(state_type&,
1562 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1563 intern_type* to, intern_type*, intern_type*& to_nxt) const
1565 frm_nxt = frm;
1566 to_nxt = to;
1567 return noconv;
1570 codecvt<char, char, mbstate_t>::result
1571 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1572 extern_type* to, extern_type*, extern_type*& to_nxt) const
1574 to_nxt = to;
1575 return noconv;
1579 codecvt<char, char, mbstate_t>::do_encoding() const noexcept
1581 return 1;
1584 bool
1585 codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
1587 return true;
1591 codecvt<char, char, mbstate_t>::do_length(state_type&,
1592 const extern_type* frm, const extern_type* end, size_t mx) const
1594 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1598 codecvt<char, char, mbstate_t>::do_max_length() const noexcept
1600 return 1;
1603 // template <> class codecvt<wchar_t, char, mbstate_t>
1605 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1606 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1608 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1609 : locale::facet(refs),
1610 __l(_LIBCPP_GET_C_LOCALE)
1614 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1615 : locale::facet(refs),
1616 __l(newlocale(LC_ALL_MASK, nm, 0))
1618 if (__l == 0)
1619 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1620 " failed to construct for " + string(nm));
1623 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1625 if (__l != _LIBCPP_GET_C_LOCALE)
1626 freelocale(__l);
1629 codecvt<wchar_t, char, mbstate_t>::result
1630 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1631 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1632 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1634 // look for first internal null in frm
1635 const intern_type* fend = frm;
1636 for (; fend != frm_end; ++fend)
1637 if (*fend == 0)
1638 break;
1639 // loop over all null-terminated sequences in frm
1640 to_nxt = to;
1641 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1643 // save state in case it is needed to recover to_nxt on error
1644 mbstate_t save_state = st;
1645 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1646 static_cast<size_t>(to_end-to), &st, __l);
1647 if (n == size_t(-1))
1649 // need to recover to_nxt
1650 for (to_nxt = to; frm != frm_nxt; ++frm)
1652 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1653 if (n == size_t(-1))
1654 break;
1655 to_nxt += n;
1657 frm_nxt = frm;
1658 return error;
1660 if (n == 0)
1661 return partial;
1662 to_nxt += n;
1663 if (to_nxt == to_end)
1664 break;
1665 if (fend != frm_end) // set up next null terminated sequence
1667 // Try to write the terminating null
1668 extern_type tmp[MB_LEN_MAX];
1669 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1670 if (n == size_t(-1)) // on error
1671 return error;
1672 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1673 return partial;
1674 for (extern_type* p = tmp; n; --n) // write it
1675 *to_nxt++ = *p++;
1676 ++frm_nxt;
1677 // look for next null in frm
1678 for (fend = frm_nxt; fend != frm_end; ++fend)
1679 if (*fend == 0)
1680 break;
1683 return frm_nxt == frm_end ? ok : partial;
1686 codecvt<wchar_t, char, mbstate_t>::result
1687 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1688 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1689 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1691 // look for first internal null in frm
1692 const extern_type* fend = frm;
1693 for (; fend != frm_end; ++fend)
1694 if (*fend == 0)
1695 break;
1696 // loop over all null-terminated sequences in frm
1697 to_nxt = to;
1698 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1700 // save state in case it is needed to recover to_nxt on error
1701 mbstate_t save_state = st;
1702 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1703 static_cast<size_t>(to_end-to), &st, __l);
1704 if (n == size_t(-1))
1706 // need to recover to_nxt
1707 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1709 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1710 &save_state, __l);
1711 switch (n)
1713 case 0:
1714 ++frm;
1715 break;
1716 case size_t(-1):
1717 frm_nxt = frm;
1718 return error;
1719 case size_t(-2):
1720 frm_nxt = frm;
1721 return partial;
1722 default:
1723 frm += n;
1724 break;
1727 frm_nxt = frm;
1728 return frm_nxt == frm_end ? ok : partial;
1730 if (n == size_t(-1))
1731 return error;
1732 to_nxt += n;
1733 if (to_nxt == to_end)
1734 break;
1735 if (fend != frm_end) // set up next null terminated sequence
1737 // Try to write the terminating null
1738 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1739 if (n != 0) // on error
1740 return error;
1741 ++to_nxt;
1742 ++frm_nxt;
1743 // look for next null in frm
1744 for (fend = frm_nxt; fend != frm_end; ++fend)
1745 if (*fend == 0)
1746 break;
1749 return frm_nxt == frm_end ? ok : partial;
1752 codecvt<wchar_t, char, mbstate_t>::result
1753 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1754 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1756 to_nxt = to;
1757 extern_type tmp[MB_LEN_MAX];
1758 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1759 if (n == size_t(-1) || n == 0) // on error
1760 return error;
1761 --n;
1762 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1763 return partial;
1764 for (extern_type* p = tmp; n; --n) // write it
1765 *to_nxt++ = *p++;
1766 return ok;
1770 codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1772 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1773 return -1;
1775 // stateless encoding
1776 if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1777 return 1; // which take more than 1 char to form a wchar_t
1778 return 0;
1781 bool
1782 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1784 return false;
1788 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1789 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1791 int nbytes = 0;
1792 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1794 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1795 switch (n)
1797 case 0:
1798 ++nbytes;
1799 ++frm;
1800 break;
1801 case size_t(-1):
1802 case size_t(-2):
1803 return nbytes;
1804 default:
1805 nbytes += n;
1806 frm += n;
1807 break;
1810 return nbytes;
1814 codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1816 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1818 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1820 // Valid UTF ranges
1821 // UTF-32 UTF-16 UTF-8 # of code points
1822 // first second first second third fourth
1823 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1824 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1825 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1826 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1827 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1828 // 00D800 - 00DFFF invalid
1829 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1830 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1831 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1832 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1834 static
1835 codecvt_base::result
1836 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1837 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1838 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1840 frm_nxt = frm;
1841 to_nxt = to;
1842 if (mode & generate_header)
1844 if (to_end-to_nxt < 3)
1845 return codecvt_base::partial;
1846 *to_nxt++ = static_cast<uint8_t>(0xEF);
1847 *to_nxt++ = static_cast<uint8_t>(0xBB);
1848 *to_nxt++ = static_cast<uint8_t>(0xBF);
1850 for (; frm_nxt < frm_end; ++frm_nxt)
1852 uint16_t wc1 = *frm_nxt;
1853 if (wc1 > Maxcode)
1854 return codecvt_base::error;
1855 if (wc1 < 0x0080)
1857 if (to_end-to_nxt < 1)
1858 return codecvt_base::partial;
1859 *to_nxt++ = static_cast<uint8_t>(wc1);
1861 else if (wc1 < 0x0800)
1863 if (to_end-to_nxt < 2)
1864 return codecvt_base::partial;
1865 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1866 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1868 else if (wc1 < 0xD800)
1870 if (to_end-to_nxt < 3)
1871 return codecvt_base::partial;
1872 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1873 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1874 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1876 else if (wc1 < 0xDC00)
1878 if (frm_end-frm_nxt < 2)
1879 return codecvt_base::partial;
1880 uint16_t wc2 = frm_nxt[1];
1881 if ((wc2 & 0xFC00) != 0xDC00)
1882 return codecvt_base::error;
1883 if (to_end-to_nxt < 4)
1884 return codecvt_base::partial;
1885 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1886 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1887 return codecvt_base::error;
1888 ++frm_nxt;
1889 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1890 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1891 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1892 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1893 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1895 else if (wc1 < 0xE000)
1897 return codecvt_base::error;
1899 else
1901 if (to_end-to_nxt < 3)
1902 return codecvt_base::partial;
1903 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1904 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1905 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1908 return codecvt_base::ok;
1911 static
1912 codecvt_base::result
1913 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1914 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1915 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1917 frm_nxt = frm;
1918 to_nxt = to;
1919 if (mode & generate_header)
1921 if (to_end-to_nxt < 3)
1922 return codecvt_base::partial;
1923 *to_nxt++ = static_cast<uint8_t>(0xEF);
1924 *to_nxt++ = static_cast<uint8_t>(0xBB);
1925 *to_nxt++ = static_cast<uint8_t>(0xBF);
1927 for (; frm_nxt < frm_end; ++frm_nxt)
1929 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1930 if (wc1 > Maxcode)
1931 return codecvt_base::error;
1932 if (wc1 < 0x0080)
1934 if (to_end-to_nxt < 1)
1935 return codecvt_base::partial;
1936 *to_nxt++ = static_cast<uint8_t>(wc1);
1938 else if (wc1 < 0x0800)
1940 if (to_end-to_nxt < 2)
1941 return codecvt_base::partial;
1942 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1943 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1945 else if (wc1 < 0xD800)
1947 if (to_end-to_nxt < 3)
1948 return codecvt_base::partial;
1949 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1950 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1951 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1953 else if (wc1 < 0xDC00)
1955 if (frm_end-frm_nxt < 2)
1956 return codecvt_base::partial;
1957 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1958 if ((wc2 & 0xFC00) != 0xDC00)
1959 return codecvt_base::error;
1960 if (to_end-to_nxt < 4)
1961 return codecvt_base::partial;
1962 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1963 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1964 return codecvt_base::error;
1965 ++frm_nxt;
1966 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1967 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1968 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1969 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1970 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1972 else if (wc1 < 0xE000)
1974 return codecvt_base::error;
1976 else
1978 if (to_end-to_nxt < 3)
1979 return codecvt_base::partial;
1980 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1981 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1982 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1985 return codecvt_base::ok;
1988 static
1989 codecvt_base::result
1990 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1991 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1992 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1994 frm_nxt = frm;
1995 to_nxt = to;
1996 if (mode & consume_header)
1998 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1999 frm_nxt[2] == 0xBF)
2000 frm_nxt += 3;
2002 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2004 uint8_t c1 = *frm_nxt;
2005 if (c1 > Maxcode)
2006 return codecvt_base::error;
2007 if (c1 < 0x80)
2009 *to_nxt = static_cast<uint16_t>(c1);
2010 ++frm_nxt;
2012 else if (c1 < 0xC2)
2014 return codecvt_base::error;
2016 else if (c1 < 0xE0)
2018 if (frm_end-frm_nxt < 2)
2019 return codecvt_base::partial;
2020 uint8_t c2 = frm_nxt[1];
2021 if ((c2 & 0xC0) != 0x80)
2022 return codecvt_base::error;
2023 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2024 if (t > Maxcode)
2025 return codecvt_base::error;
2026 *to_nxt = t;
2027 frm_nxt += 2;
2029 else if (c1 < 0xF0)
2031 if (frm_end-frm_nxt < 3)
2032 return codecvt_base::partial;
2033 uint8_t c2 = frm_nxt[1];
2034 uint8_t c3 = frm_nxt[2];
2035 switch (c1)
2037 case 0xE0:
2038 if ((c2 & 0xE0) != 0xA0)
2039 return codecvt_base::error;
2040 break;
2041 case 0xED:
2042 if ((c2 & 0xE0) != 0x80)
2043 return codecvt_base::error;
2044 break;
2045 default:
2046 if ((c2 & 0xC0) != 0x80)
2047 return codecvt_base::error;
2048 break;
2050 if ((c3 & 0xC0) != 0x80)
2051 return codecvt_base::error;
2052 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2053 | ((c2 & 0x3F) << 6)
2054 | (c3 & 0x3F));
2055 if (t > Maxcode)
2056 return codecvt_base::error;
2057 *to_nxt = t;
2058 frm_nxt += 3;
2060 else if (c1 < 0xF5)
2062 if (frm_end-frm_nxt < 4)
2063 return codecvt_base::partial;
2064 uint8_t c2 = frm_nxt[1];
2065 uint8_t c3 = frm_nxt[2];
2066 uint8_t c4 = frm_nxt[3];
2067 switch (c1)
2069 case 0xF0:
2070 if (!(0x90 <= c2 && c2 <= 0xBF))
2071 return codecvt_base::error;
2072 break;
2073 case 0xF4:
2074 if ((c2 & 0xF0) != 0x80)
2075 return codecvt_base::error;
2076 break;
2077 default:
2078 if ((c2 & 0xC0) != 0x80)
2079 return codecvt_base::error;
2080 break;
2082 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2083 return codecvt_base::error;
2084 if (to_end-to_nxt < 2)
2085 return codecvt_base::partial;
2086 if ((((c1 & 7UL) << 18) +
2087 ((c2 & 0x3FUL) << 12) +
2088 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2089 return codecvt_base::error;
2090 *to_nxt = static_cast<uint16_t>(
2091 0xD800
2092 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2093 | ((c2 & 0x0F) << 2)
2094 | ((c3 & 0x30) >> 4));
2095 *++to_nxt = static_cast<uint16_t>(
2096 0xDC00
2097 | ((c3 & 0x0F) << 6)
2098 | (c4 & 0x3F));
2099 frm_nxt += 4;
2101 else
2103 return codecvt_base::error;
2106 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2109 static
2110 codecvt_base::result
2111 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2112 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2113 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2115 frm_nxt = frm;
2116 to_nxt = to;
2117 if (mode & consume_header)
2119 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2120 frm_nxt[2] == 0xBF)
2121 frm_nxt += 3;
2123 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2125 uint8_t c1 = *frm_nxt;
2126 if (c1 > Maxcode)
2127 return codecvt_base::error;
2128 if (c1 < 0x80)
2130 *to_nxt = static_cast<uint32_t>(c1);
2131 ++frm_nxt;
2133 else if (c1 < 0xC2)
2135 return codecvt_base::error;
2137 else if (c1 < 0xE0)
2139 if (frm_end-frm_nxt < 2)
2140 return codecvt_base::partial;
2141 uint8_t c2 = frm_nxt[1];
2142 if ((c2 & 0xC0) != 0x80)
2143 return codecvt_base::error;
2144 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2145 if (t > Maxcode)
2146 return codecvt_base::error;
2147 *to_nxt = static_cast<uint32_t>(t);
2148 frm_nxt += 2;
2150 else if (c1 < 0xF0)
2152 if (frm_end-frm_nxt < 3)
2153 return codecvt_base::partial;
2154 uint8_t c2 = frm_nxt[1];
2155 uint8_t c3 = frm_nxt[2];
2156 switch (c1)
2158 case 0xE0:
2159 if ((c2 & 0xE0) != 0xA0)
2160 return codecvt_base::error;
2161 break;
2162 case 0xED:
2163 if ((c2 & 0xE0) != 0x80)
2164 return codecvt_base::error;
2165 break;
2166 default:
2167 if ((c2 & 0xC0) != 0x80)
2168 return codecvt_base::error;
2169 break;
2171 if ((c3 & 0xC0) != 0x80)
2172 return codecvt_base::error;
2173 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2174 | ((c2 & 0x3F) << 6)
2175 | (c3 & 0x3F));
2176 if (t > Maxcode)
2177 return codecvt_base::error;
2178 *to_nxt = static_cast<uint32_t>(t);
2179 frm_nxt += 3;
2181 else if (c1 < 0xF5)
2183 if (frm_end-frm_nxt < 4)
2184 return codecvt_base::partial;
2185 uint8_t c2 = frm_nxt[1];
2186 uint8_t c3 = frm_nxt[2];
2187 uint8_t c4 = frm_nxt[3];
2188 switch (c1)
2190 case 0xF0:
2191 if (!(0x90 <= c2 && c2 <= 0xBF))
2192 return codecvt_base::error;
2193 break;
2194 case 0xF4:
2195 if ((c2 & 0xF0) != 0x80)
2196 return codecvt_base::error;
2197 break;
2198 default:
2199 if ((c2 & 0xC0) != 0x80)
2200 return codecvt_base::error;
2201 break;
2203 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2204 return codecvt_base::error;
2205 if (to_end-to_nxt < 2)
2206 return codecvt_base::partial;
2207 if ((((c1 & 7UL) << 18) +
2208 ((c2 & 0x3FUL) << 12) +
2209 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2210 return codecvt_base::error;
2211 *to_nxt = static_cast<uint32_t>(
2212 0xD800
2213 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2214 | ((c2 & 0x0F) << 2)
2215 | ((c3 & 0x30) >> 4));
2216 *++to_nxt = static_cast<uint32_t>(
2217 0xDC00
2218 | ((c3 & 0x0F) << 6)
2219 | (c4 & 0x3F));
2220 frm_nxt += 4;
2222 else
2224 return codecvt_base::error;
2227 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2230 static
2232 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2233 size_t mx, unsigned long Maxcode = 0x10FFFF,
2234 codecvt_mode mode = codecvt_mode(0))
2236 const uint8_t* frm_nxt = frm;
2237 if (mode & consume_header)
2239 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2240 frm_nxt[2] == 0xBF)
2241 frm_nxt += 3;
2243 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2245 uint8_t c1 = *frm_nxt;
2246 if (c1 > Maxcode)
2247 break;
2248 if (c1 < 0x80)
2250 ++frm_nxt;
2252 else if (c1 < 0xC2)
2254 break;
2256 else if (c1 < 0xE0)
2258 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2259 break;
2260 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2261 if (t > Maxcode)
2262 break;
2263 frm_nxt += 2;
2265 else if (c1 < 0xF0)
2267 if (frm_end-frm_nxt < 3)
2268 break;
2269 uint8_t c2 = frm_nxt[1];
2270 uint8_t c3 = frm_nxt[2];
2271 switch (c1)
2273 case 0xE0:
2274 if ((c2 & 0xE0) != 0xA0)
2275 return static_cast<int>(frm_nxt - frm);
2276 break;
2277 case 0xED:
2278 if ((c2 & 0xE0) != 0x80)
2279 return static_cast<int>(frm_nxt - frm);
2280 break;
2281 default:
2282 if ((c2 & 0xC0) != 0x80)
2283 return static_cast<int>(frm_nxt - frm);
2284 break;
2286 if ((c3 & 0xC0) != 0x80)
2287 break;
2288 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2289 break;
2290 frm_nxt += 3;
2292 else if (c1 < 0xF5)
2294 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2295 break;
2296 uint8_t c2 = frm_nxt[1];
2297 uint8_t c3 = frm_nxt[2];
2298 uint8_t c4 = frm_nxt[3];
2299 switch (c1)
2301 case 0xF0:
2302 if (!(0x90 <= c2 && c2 <= 0xBF))
2303 return static_cast<int>(frm_nxt - frm);
2304 break;
2305 case 0xF4:
2306 if ((c2 & 0xF0) != 0x80)
2307 return static_cast<int>(frm_nxt - frm);
2308 break;
2309 default:
2310 if ((c2 & 0xC0) != 0x80)
2311 return static_cast<int>(frm_nxt - frm);
2312 break;
2314 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2315 break;
2316 if ((((c1 & 7UL) << 18) +
2317 ((c2 & 0x3FUL) << 12) +
2318 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2319 break;
2320 ++nchar16_t;
2321 frm_nxt += 4;
2323 else
2325 break;
2328 return static_cast<int>(frm_nxt - frm);
2331 static
2332 codecvt_base::result
2333 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2334 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2335 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2337 frm_nxt = frm;
2338 to_nxt = to;
2339 if (mode & generate_header)
2341 if (to_end-to_nxt < 3)
2342 return codecvt_base::partial;
2343 *to_nxt++ = static_cast<uint8_t>(0xEF);
2344 *to_nxt++ = static_cast<uint8_t>(0xBB);
2345 *to_nxt++ = static_cast<uint8_t>(0xBF);
2347 for (; frm_nxt < frm_end; ++frm_nxt)
2349 uint32_t wc = *frm_nxt;
2350 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2351 return codecvt_base::error;
2352 if (wc < 0x000080)
2354 if (to_end-to_nxt < 1)
2355 return codecvt_base::partial;
2356 *to_nxt++ = static_cast<uint8_t>(wc);
2358 else if (wc < 0x000800)
2360 if (to_end-to_nxt < 2)
2361 return codecvt_base::partial;
2362 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2363 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2365 else if (wc < 0x010000)
2367 if (to_end-to_nxt < 3)
2368 return codecvt_base::partial;
2369 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2370 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2371 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2373 else // if (wc < 0x110000)
2375 if (to_end-to_nxt < 4)
2376 return codecvt_base::partial;
2377 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2378 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2379 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2380 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2383 return codecvt_base::ok;
2386 static
2387 codecvt_base::result
2388 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2389 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2390 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2392 frm_nxt = frm;
2393 to_nxt = to;
2394 if (mode & consume_header)
2396 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2397 frm_nxt[2] == 0xBF)
2398 frm_nxt += 3;
2400 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2402 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2403 if (c1 < 0x80)
2405 if (c1 > Maxcode)
2406 return codecvt_base::error;
2407 *to_nxt = static_cast<uint32_t>(c1);
2408 ++frm_nxt;
2410 else if (c1 < 0xC2)
2412 return codecvt_base::error;
2414 else if (c1 < 0xE0)
2416 if (frm_end-frm_nxt < 2)
2417 return codecvt_base::partial;
2418 uint8_t c2 = frm_nxt[1];
2419 if ((c2 & 0xC0) != 0x80)
2420 return codecvt_base::error;
2421 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2422 | (c2 & 0x3F));
2423 if (t > Maxcode)
2424 return codecvt_base::error;
2425 *to_nxt = t;
2426 frm_nxt += 2;
2428 else if (c1 < 0xF0)
2430 if (frm_end-frm_nxt < 3)
2431 return codecvt_base::partial;
2432 uint8_t c2 = frm_nxt[1];
2433 uint8_t c3 = frm_nxt[2];
2434 switch (c1)
2436 case 0xE0:
2437 if ((c2 & 0xE0) != 0xA0)
2438 return codecvt_base::error;
2439 break;
2440 case 0xED:
2441 if ((c2 & 0xE0) != 0x80)
2442 return codecvt_base::error;
2443 break;
2444 default:
2445 if ((c2 & 0xC0) != 0x80)
2446 return codecvt_base::error;
2447 break;
2449 if ((c3 & 0xC0) != 0x80)
2450 return codecvt_base::error;
2451 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2452 | ((c2 & 0x3F) << 6)
2453 | (c3 & 0x3F));
2454 if (t > Maxcode)
2455 return codecvt_base::error;
2456 *to_nxt = t;
2457 frm_nxt += 3;
2459 else if (c1 < 0xF5)
2461 if (frm_end-frm_nxt < 4)
2462 return codecvt_base::partial;
2463 uint8_t c2 = frm_nxt[1];
2464 uint8_t c3 = frm_nxt[2];
2465 uint8_t c4 = frm_nxt[3];
2466 switch (c1)
2468 case 0xF0:
2469 if (!(0x90 <= c2 && c2 <= 0xBF))
2470 return codecvt_base::error;
2471 break;
2472 case 0xF4:
2473 if ((c2 & 0xF0) != 0x80)
2474 return codecvt_base::error;
2475 break;
2476 default:
2477 if ((c2 & 0xC0) != 0x80)
2478 return codecvt_base::error;
2479 break;
2481 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2482 return codecvt_base::error;
2483 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2484 | ((c2 & 0x3F) << 12)
2485 | ((c3 & 0x3F) << 6)
2486 | (c4 & 0x3F));
2487 if (t > Maxcode)
2488 return codecvt_base::error;
2489 *to_nxt = t;
2490 frm_nxt += 4;
2492 else
2494 return codecvt_base::error;
2497 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2500 static
2502 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2503 size_t mx, unsigned long Maxcode = 0x10FFFF,
2504 codecvt_mode mode = codecvt_mode(0))
2506 const uint8_t* frm_nxt = frm;
2507 if (mode & consume_header)
2509 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2510 frm_nxt[2] == 0xBF)
2511 frm_nxt += 3;
2513 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2515 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2516 if (c1 < 0x80)
2518 if (c1 > Maxcode)
2519 break;
2520 ++frm_nxt;
2522 else if (c1 < 0xC2)
2524 break;
2526 else if (c1 < 0xE0)
2528 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2529 break;
2530 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2531 break;
2532 frm_nxt += 2;
2534 else if (c1 < 0xF0)
2536 if (frm_end-frm_nxt < 3)
2537 break;
2538 uint8_t c2 = frm_nxt[1];
2539 uint8_t c3 = frm_nxt[2];
2540 switch (c1)
2542 case 0xE0:
2543 if ((c2 & 0xE0) != 0xA0)
2544 return static_cast<int>(frm_nxt - frm);
2545 break;
2546 case 0xED:
2547 if ((c2 & 0xE0) != 0x80)
2548 return static_cast<int>(frm_nxt - frm);
2549 break;
2550 default:
2551 if ((c2 & 0xC0) != 0x80)
2552 return static_cast<int>(frm_nxt - frm);
2553 break;
2555 if ((c3 & 0xC0) != 0x80)
2556 break;
2557 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2558 break;
2559 frm_nxt += 3;
2561 else if (c1 < 0xF5)
2563 if (frm_end-frm_nxt < 4)
2564 break;
2565 uint8_t c2 = frm_nxt[1];
2566 uint8_t c3 = frm_nxt[2];
2567 uint8_t c4 = frm_nxt[3];
2568 switch (c1)
2570 case 0xF0:
2571 if (!(0x90 <= c2 && c2 <= 0xBF))
2572 return static_cast<int>(frm_nxt - frm);
2573 break;
2574 case 0xF4:
2575 if ((c2 & 0xF0) != 0x80)
2576 return static_cast<int>(frm_nxt - frm);
2577 break;
2578 default:
2579 if ((c2 & 0xC0) != 0x80)
2580 return static_cast<int>(frm_nxt - frm);
2581 break;
2583 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2584 break;
2585 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2586 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2587 break;
2588 frm_nxt += 4;
2590 else
2592 break;
2595 return static_cast<int>(frm_nxt - frm);
2598 static
2599 codecvt_base::result
2600 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2601 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2602 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2604 frm_nxt = frm;
2605 to_nxt = to;
2606 if (mode & generate_header)
2608 if (to_end-to_nxt < 3)
2609 return codecvt_base::partial;
2610 *to_nxt++ = static_cast<uint8_t>(0xEF);
2611 *to_nxt++ = static_cast<uint8_t>(0xBB);
2612 *to_nxt++ = static_cast<uint8_t>(0xBF);
2614 for (; frm_nxt < frm_end; ++frm_nxt)
2616 uint16_t wc = *frm_nxt;
2617 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2618 return codecvt_base::error;
2619 if (wc < 0x0080)
2621 if (to_end-to_nxt < 1)
2622 return codecvt_base::partial;
2623 *to_nxt++ = static_cast<uint8_t>(wc);
2625 else if (wc < 0x0800)
2627 if (to_end-to_nxt < 2)
2628 return codecvt_base::partial;
2629 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2630 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2632 else // if (wc <= 0xFFFF)
2634 if (to_end-to_nxt < 3)
2635 return codecvt_base::partial;
2636 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2637 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2638 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2641 return codecvt_base::ok;
2644 static
2645 codecvt_base::result
2646 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2647 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2648 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2650 frm_nxt = frm;
2651 to_nxt = to;
2652 if (mode & consume_header)
2654 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2655 frm_nxt[2] == 0xBF)
2656 frm_nxt += 3;
2658 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2660 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2661 if (c1 < 0x80)
2663 if (c1 > Maxcode)
2664 return codecvt_base::error;
2665 *to_nxt = static_cast<uint16_t>(c1);
2666 ++frm_nxt;
2668 else if (c1 < 0xC2)
2670 return codecvt_base::error;
2672 else if (c1 < 0xE0)
2674 if (frm_end-frm_nxt < 2)
2675 return codecvt_base::partial;
2676 uint8_t c2 = frm_nxt[1];
2677 if ((c2 & 0xC0) != 0x80)
2678 return codecvt_base::error;
2679 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2680 | (c2 & 0x3F));
2681 if (t > Maxcode)
2682 return codecvt_base::error;
2683 *to_nxt = t;
2684 frm_nxt += 2;
2686 else if (c1 < 0xF0)
2688 if (frm_end-frm_nxt < 3)
2689 return codecvt_base::partial;
2690 uint8_t c2 = frm_nxt[1];
2691 uint8_t c3 = frm_nxt[2];
2692 switch (c1)
2694 case 0xE0:
2695 if ((c2 & 0xE0) != 0xA0)
2696 return codecvt_base::error;
2697 break;
2698 case 0xED:
2699 if ((c2 & 0xE0) != 0x80)
2700 return codecvt_base::error;
2701 break;
2702 default:
2703 if ((c2 & 0xC0) != 0x80)
2704 return codecvt_base::error;
2705 break;
2707 if ((c3 & 0xC0) != 0x80)
2708 return codecvt_base::error;
2709 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2710 | ((c2 & 0x3F) << 6)
2711 | (c3 & 0x3F));
2712 if (t > Maxcode)
2713 return codecvt_base::error;
2714 *to_nxt = t;
2715 frm_nxt += 3;
2717 else
2719 return codecvt_base::error;
2722 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2725 static
2727 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2728 size_t mx, unsigned long Maxcode = 0x10FFFF,
2729 codecvt_mode mode = codecvt_mode(0))
2731 const uint8_t* frm_nxt = frm;
2732 if (mode & consume_header)
2734 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2735 frm_nxt[2] == 0xBF)
2736 frm_nxt += 3;
2738 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2740 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2741 if (c1 < 0x80)
2743 if (c1 > Maxcode)
2744 break;
2745 ++frm_nxt;
2747 else if (c1 < 0xC2)
2749 break;
2751 else if (c1 < 0xE0)
2753 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2754 break;
2755 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2756 break;
2757 frm_nxt += 2;
2759 else if (c1 < 0xF0)
2761 if (frm_end-frm_nxt < 3)
2762 break;
2763 uint8_t c2 = frm_nxt[1];
2764 uint8_t c3 = frm_nxt[2];
2765 switch (c1)
2767 case 0xE0:
2768 if ((c2 & 0xE0) != 0xA0)
2769 return static_cast<int>(frm_nxt - frm);
2770 break;
2771 case 0xED:
2772 if ((c2 & 0xE0) != 0x80)
2773 return static_cast<int>(frm_nxt - frm);
2774 break;
2775 default:
2776 if ((c2 & 0xC0) != 0x80)
2777 return static_cast<int>(frm_nxt - frm);
2778 break;
2780 if ((c3 & 0xC0) != 0x80)
2781 break;
2782 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2783 break;
2784 frm_nxt += 3;
2786 else
2788 break;
2791 return static_cast<int>(frm_nxt - frm);
2794 static
2795 codecvt_base::result
2796 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2797 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2798 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2800 frm_nxt = frm;
2801 to_nxt = to;
2802 if (mode & generate_header)
2804 if (to_end-to_nxt < 2)
2805 return codecvt_base::partial;
2806 *to_nxt++ = static_cast<uint8_t>(0xFE);
2807 *to_nxt++ = static_cast<uint8_t>(0xFF);
2809 for (; frm_nxt < frm_end; ++frm_nxt)
2811 uint32_t wc = *frm_nxt;
2812 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2813 return codecvt_base::error;
2814 if (wc < 0x010000)
2816 if (to_end-to_nxt < 2)
2817 return codecvt_base::partial;
2818 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2819 *to_nxt++ = static_cast<uint8_t>(wc);
2821 else
2823 if (to_end-to_nxt < 4)
2824 return codecvt_base::partial;
2825 uint16_t t = static_cast<uint16_t>(
2826 0xD800
2827 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2828 | ((wc & 0x00FC00) >> 10));
2829 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2830 *to_nxt++ = static_cast<uint8_t>(t);
2831 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2832 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2833 *to_nxt++ = static_cast<uint8_t>(t);
2836 return codecvt_base::ok;
2839 static
2840 codecvt_base::result
2841 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2842 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2843 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2845 frm_nxt = frm;
2846 to_nxt = to;
2847 if (mode & consume_header)
2849 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2850 frm_nxt += 2;
2852 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2854 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2855 if ((c1 & 0xFC00) == 0xDC00)
2856 return codecvt_base::error;
2857 if ((c1 & 0xFC00) != 0xD800)
2859 if (c1 > Maxcode)
2860 return codecvt_base::error;
2861 *to_nxt = static_cast<uint32_t>(c1);
2862 frm_nxt += 2;
2864 else
2866 if (frm_end-frm_nxt < 4)
2867 return codecvt_base::partial;
2868 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2869 if ((c2 & 0xFC00) != 0xDC00)
2870 return codecvt_base::error;
2871 uint32_t t = static_cast<uint32_t>(
2872 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2873 | ((c1 & 0x003F) << 10)
2874 | (c2 & 0x03FF));
2875 if (t > Maxcode)
2876 return codecvt_base::error;
2877 *to_nxt = t;
2878 frm_nxt += 4;
2881 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2884 static
2886 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2887 size_t mx, unsigned long Maxcode = 0x10FFFF,
2888 codecvt_mode mode = codecvt_mode(0))
2890 const uint8_t* frm_nxt = frm;
2891 if (mode & consume_header)
2893 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2894 frm_nxt += 2;
2896 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2898 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2899 if ((c1 & 0xFC00) == 0xDC00)
2900 break;
2901 if ((c1 & 0xFC00) != 0xD800)
2903 if (c1 > Maxcode)
2904 break;
2905 frm_nxt += 2;
2907 else
2909 if (frm_end-frm_nxt < 4)
2910 break;
2911 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2912 if ((c2 & 0xFC00) != 0xDC00)
2913 break;
2914 uint32_t t = static_cast<uint32_t>(
2915 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2916 | ((c1 & 0x003F) << 10)
2917 | (c2 & 0x03FF));
2918 if (t > Maxcode)
2919 break;
2920 frm_nxt += 4;
2923 return static_cast<int>(frm_nxt - frm);
2926 static
2927 codecvt_base::result
2928 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2929 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2930 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2932 frm_nxt = frm;
2933 to_nxt = to;
2934 if (mode & generate_header)
2936 if (to_end - to_nxt < 2)
2937 return codecvt_base::partial;
2938 *to_nxt++ = static_cast<uint8_t>(0xFF);
2939 *to_nxt++ = static_cast<uint8_t>(0xFE);
2941 for (; frm_nxt < frm_end; ++frm_nxt)
2943 uint32_t wc = *frm_nxt;
2944 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2945 return codecvt_base::error;
2946 if (wc < 0x010000)
2948 if (to_end-to_nxt < 2)
2949 return codecvt_base::partial;
2950 *to_nxt++ = static_cast<uint8_t>(wc);
2951 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2953 else
2955 if (to_end-to_nxt < 4)
2956 return codecvt_base::partial;
2957 uint16_t t = static_cast<uint16_t>(
2958 0xD800
2959 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2960 | ((wc & 0x00FC00) >> 10));
2961 *to_nxt++ = static_cast<uint8_t>(t);
2962 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2963 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2964 *to_nxt++ = static_cast<uint8_t>(t);
2965 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2968 return codecvt_base::ok;
2971 static
2972 codecvt_base::result
2973 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2974 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2975 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2977 frm_nxt = frm;
2978 to_nxt = to;
2979 if (mode & consume_header)
2981 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2982 frm_nxt += 2;
2984 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2986 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2987 if ((c1 & 0xFC00) == 0xDC00)
2988 return codecvt_base::error;
2989 if ((c1 & 0xFC00) != 0xD800)
2991 if (c1 > Maxcode)
2992 return codecvt_base::error;
2993 *to_nxt = static_cast<uint32_t>(c1);
2994 frm_nxt += 2;
2996 else
2998 if (frm_end-frm_nxt < 4)
2999 return codecvt_base::partial;
3000 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3001 if ((c2 & 0xFC00) != 0xDC00)
3002 return codecvt_base::error;
3003 uint32_t t = static_cast<uint32_t>(
3004 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3005 | ((c1 & 0x003F) << 10)
3006 | (c2 & 0x03FF));
3007 if (t > Maxcode)
3008 return codecvt_base::error;
3009 *to_nxt = t;
3010 frm_nxt += 4;
3013 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3016 static
3018 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
3019 size_t mx, unsigned long Maxcode = 0x10FFFF,
3020 codecvt_mode mode = codecvt_mode(0))
3022 const uint8_t* frm_nxt = frm;
3023 if (mode & consume_header)
3025 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3026 frm_nxt += 2;
3028 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
3030 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3031 if ((c1 & 0xFC00) == 0xDC00)
3032 break;
3033 if ((c1 & 0xFC00) != 0xD800)
3035 if (c1 > Maxcode)
3036 break;
3037 frm_nxt += 2;
3039 else
3041 if (frm_end-frm_nxt < 4)
3042 break;
3043 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3044 if ((c2 & 0xFC00) != 0xDC00)
3045 break;
3046 uint32_t t = static_cast<uint32_t>(
3047 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3048 | ((c1 & 0x003F) << 10)
3049 | (c2 & 0x03FF));
3050 if (t > Maxcode)
3051 break;
3052 frm_nxt += 4;
3055 return static_cast<int>(frm_nxt - frm);
3058 static
3059 codecvt_base::result
3060 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3061 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3062 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3064 frm_nxt = frm;
3065 to_nxt = to;
3066 if (mode & generate_header)
3068 if (to_end-to_nxt < 2)
3069 return codecvt_base::partial;
3070 *to_nxt++ = static_cast<uint8_t>(0xFE);
3071 *to_nxt++ = static_cast<uint8_t>(0xFF);
3073 for (; frm_nxt < frm_end; ++frm_nxt)
3075 uint16_t wc = *frm_nxt;
3076 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3077 return codecvt_base::error;
3078 if (to_end-to_nxt < 2)
3079 return codecvt_base::partial;
3080 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3081 *to_nxt++ = static_cast<uint8_t>(wc);
3083 return codecvt_base::ok;
3086 static
3087 codecvt_base::result
3088 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3089 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3090 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3092 frm_nxt = frm;
3093 to_nxt = to;
3094 if (mode & consume_header)
3096 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3097 frm_nxt += 2;
3099 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3101 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3102 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3103 return codecvt_base::error;
3104 *to_nxt = c1;
3105 frm_nxt += 2;
3107 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3110 static
3112 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3113 size_t mx, unsigned long Maxcode = 0x10FFFF,
3114 codecvt_mode mode = codecvt_mode(0))
3116 const uint8_t* frm_nxt = frm;
3117 if (mode & consume_header)
3119 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3120 frm_nxt += 2;
3122 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3124 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3125 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3126 break;
3127 frm_nxt += 2;
3129 return static_cast<int>(frm_nxt - frm);
3132 static
3133 codecvt_base::result
3134 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3135 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3136 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3138 frm_nxt = frm;
3139 to_nxt = to;
3140 if (mode & generate_header)
3142 if (to_end-to_nxt < 2)
3143 return codecvt_base::partial;
3144 *to_nxt++ = static_cast<uint8_t>(0xFF);
3145 *to_nxt++ = static_cast<uint8_t>(0xFE);
3147 for (; frm_nxt < frm_end; ++frm_nxt)
3149 uint16_t wc = *frm_nxt;
3150 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3151 return codecvt_base::error;
3152 if (to_end-to_nxt < 2)
3153 return codecvt_base::partial;
3154 *to_nxt++ = static_cast<uint8_t>(wc);
3155 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3157 return codecvt_base::ok;
3160 static
3161 codecvt_base::result
3162 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3163 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3164 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3166 frm_nxt = frm;
3167 to_nxt = to;
3168 if (mode & consume_header)
3170 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3171 frm_nxt += 2;
3173 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3175 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3176 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3177 return codecvt_base::error;
3178 *to_nxt = c1;
3179 frm_nxt += 2;
3181 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3184 static
3186 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3187 size_t mx, unsigned long Maxcode = 0x10FFFF,
3188 codecvt_mode mode = codecvt_mode(0))
3190 const uint8_t* frm_nxt = frm;
3191 frm_nxt = frm;
3192 if (mode & consume_header)
3194 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3195 frm_nxt += 2;
3197 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3199 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3200 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3201 break;
3202 frm_nxt += 2;
3204 return static_cast<int>(frm_nxt - frm);
3207 // template <> class codecvt<char16_t, char, mbstate_t>
3209 locale::id codecvt<char16_t, char, mbstate_t>::id;
3211 codecvt<char16_t, char, mbstate_t>::~codecvt()
3215 codecvt<char16_t, char, mbstate_t>::result
3216 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3217 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3218 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3220 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3221 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3222 const uint16_t* _frm_nxt = _frm;
3223 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3224 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3225 uint8_t* _to_nxt = _to;
3226 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3227 frm_nxt = frm + (_frm_nxt - _frm);
3228 to_nxt = to + (_to_nxt - _to);
3229 return r;
3232 codecvt<char16_t, char, mbstate_t>::result
3233 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3234 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3235 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3237 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3238 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3239 const uint8_t* _frm_nxt = _frm;
3240 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3241 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3242 uint16_t* _to_nxt = _to;
3243 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3244 frm_nxt = frm + (_frm_nxt - _frm);
3245 to_nxt = to + (_to_nxt - _to);
3246 return r;
3249 codecvt<char16_t, char, mbstate_t>::result
3250 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3251 extern_type* to, extern_type*, extern_type*& to_nxt) const
3253 to_nxt = to;
3254 return noconv;
3258 codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
3260 return 0;
3263 bool
3264 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
3266 return false;
3270 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3271 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3273 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3274 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3275 return utf8_to_utf16_length(_frm, _frm_end, mx);
3279 codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
3281 return 4;
3284 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3286 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3288 locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
3290 codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
3294 codecvt<char16_t, char8_t, mbstate_t>::result
3295 codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
3296 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3297 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3299 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3300 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3301 const uint16_t* _frm_nxt = _frm;
3302 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3303 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3304 uint8_t* _to_nxt = _to;
3305 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3306 frm_nxt = frm + (_frm_nxt - _frm);
3307 to_nxt = to + (_to_nxt - _to);
3308 return r;
3311 codecvt<char16_t, char8_t, mbstate_t>::result
3312 codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
3313 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3314 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3316 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3317 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3318 const uint8_t* _frm_nxt = _frm;
3319 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3320 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3321 uint16_t* _to_nxt = _to;
3322 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3323 frm_nxt = frm + (_frm_nxt - _frm);
3324 to_nxt = to + (_to_nxt - _to);
3325 return r;
3328 codecvt<char16_t, char8_t, mbstate_t>::result
3329 codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
3330 extern_type* to, extern_type*, extern_type*& to_nxt) const
3332 to_nxt = to;
3333 return noconv;
3337 codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
3339 return 0;
3342 bool
3343 codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3345 return false;
3349 codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
3350 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3352 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3353 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3354 return utf8_to_utf16_length(_frm, _frm_end, mx);
3358 codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
3360 return 4;
3363 #endif
3365 // template <> class codecvt<char32_t, char, mbstate_t>
3367 locale::id codecvt<char32_t, char, mbstate_t>::id;
3369 codecvt<char32_t, char, mbstate_t>::~codecvt()
3373 codecvt<char32_t, char, mbstate_t>::result
3374 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3375 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3376 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3378 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3379 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3380 const uint32_t* _frm_nxt = _frm;
3381 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3382 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3383 uint8_t* _to_nxt = _to;
3384 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3385 frm_nxt = frm + (_frm_nxt - _frm);
3386 to_nxt = to + (_to_nxt - _to);
3387 return r;
3390 codecvt<char32_t, char, mbstate_t>::result
3391 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3392 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3393 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3395 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3396 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3397 const uint8_t* _frm_nxt = _frm;
3398 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3399 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3400 uint32_t* _to_nxt = _to;
3401 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3402 frm_nxt = frm + (_frm_nxt - _frm);
3403 to_nxt = to + (_to_nxt - _to);
3404 return r;
3407 codecvt<char32_t, char, mbstate_t>::result
3408 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3409 extern_type* to, extern_type*, extern_type*& to_nxt) const
3411 to_nxt = to;
3412 return noconv;
3416 codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
3418 return 0;
3421 bool
3422 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
3424 return false;
3428 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3429 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3431 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3432 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3433 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3437 codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
3439 return 4;
3442 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3444 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3446 locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
3448 codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
3452 codecvt<char32_t, char8_t, mbstate_t>::result
3453 codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
3454 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3455 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3457 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3458 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3459 const uint32_t* _frm_nxt = _frm;
3460 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3461 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3462 uint8_t* _to_nxt = _to;
3463 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3464 frm_nxt = frm + (_frm_nxt - _frm);
3465 to_nxt = to + (_to_nxt - _to);
3466 return r;
3469 codecvt<char32_t, char8_t, mbstate_t>::result
3470 codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
3471 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3472 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3474 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3475 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3476 const uint8_t* _frm_nxt = _frm;
3477 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3478 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3479 uint32_t* _to_nxt = _to;
3480 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3481 frm_nxt = frm + (_frm_nxt - _frm);
3482 to_nxt = to + (_to_nxt - _to);
3483 return r;
3486 codecvt<char32_t, char8_t, mbstate_t>::result
3487 codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
3488 extern_type* to, extern_type*, extern_type*& to_nxt) const
3490 to_nxt = to;
3491 return noconv;
3495 codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
3497 return 0;
3500 bool
3501 codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3503 return false;
3507 codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
3508 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3510 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3511 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3512 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3516 codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
3518 return 4;
3521 #endif
3523 // __codecvt_utf8<wchar_t>
3525 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3526 __codecvt_utf8<wchar_t>::result
3527 __codecvt_utf8<wchar_t>::do_out(state_type&,
3528 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3529 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3531 #if defined(_LIBCPP_SHORT_WCHAR)
3532 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3533 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3534 const uint16_t* _frm_nxt = _frm;
3535 #else
3536 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3537 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3538 const uint32_t* _frm_nxt = _frm;
3539 #endif
3540 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3541 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3542 uint8_t* _to_nxt = _to;
3543 #if defined(_LIBCPP_SHORT_WCHAR)
3544 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3545 _Maxcode_, _Mode_);
3546 #else
3547 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3548 _Maxcode_, _Mode_);
3549 #endif
3550 frm_nxt = frm + (_frm_nxt - _frm);
3551 to_nxt = to + (_to_nxt - _to);
3552 return r;
3555 __codecvt_utf8<wchar_t>::result
3556 __codecvt_utf8<wchar_t>::do_in(state_type&,
3557 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3558 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3560 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3561 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3562 const uint8_t* _frm_nxt = _frm;
3563 #if defined(_LIBCPP_SHORT_WCHAR)
3564 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3565 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3566 uint16_t* _to_nxt = _to;
3567 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3568 _Maxcode_, _Mode_);
3569 #else
3570 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3571 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3572 uint32_t* _to_nxt = _to;
3573 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3574 _Maxcode_, _Mode_);
3575 #endif
3576 frm_nxt = frm + (_frm_nxt - _frm);
3577 to_nxt = to + (_to_nxt - _to);
3578 return r;
3581 __codecvt_utf8<wchar_t>::result
3582 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3583 extern_type* to, extern_type*, extern_type*& to_nxt) const
3585 to_nxt = to;
3586 return noconv;
3590 __codecvt_utf8<wchar_t>::do_encoding() const noexcept
3592 return 0;
3595 bool
3596 __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
3598 return false;
3602 __codecvt_utf8<wchar_t>::do_length(state_type&,
3603 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3605 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3606 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3607 #if defined(_LIBCPP_SHORT_WCHAR)
3608 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3609 #else
3610 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3611 #endif
3615 __codecvt_utf8<wchar_t>::do_max_length() const noexcept
3617 #if defined(_LIBCPP_SHORT_WCHAR)
3618 if (_Mode_ & consume_header)
3619 return 6;
3620 return 3;
3621 #else
3622 if (_Mode_ & consume_header)
3623 return 7;
3624 return 4;
3625 #endif
3627 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3629 // __codecvt_utf8<char16_t>
3631 __codecvt_utf8<char16_t>::result
3632 __codecvt_utf8<char16_t>::do_out(state_type&,
3633 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3634 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3636 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3637 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3638 const uint16_t* _frm_nxt = _frm;
3639 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3640 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3641 uint8_t* _to_nxt = _to;
3642 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3643 _Maxcode_, _Mode_);
3644 frm_nxt = frm + (_frm_nxt - _frm);
3645 to_nxt = to + (_to_nxt - _to);
3646 return r;
3649 __codecvt_utf8<char16_t>::result
3650 __codecvt_utf8<char16_t>::do_in(state_type&,
3651 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3652 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3654 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3655 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3656 const uint8_t* _frm_nxt = _frm;
3657 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3658 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3659 uint16_t* _to_nxt = _to;
3660 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3661 _Maxcode_, _Mode_);
3662 frm_nxt = frm + (_frm_nxt - _frm);
3663 to_nxt = to + (_to_nxt - _to);
3664 return r;
3667 __codecvt_utf8<char16_t>::result
3668 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3669 extern_type* to, extern_type*, extern_type*& to_nxt) const
3671 to_nxt = to;
3672 return noconv;
3676 __codecvt_utf8<char16_t>::do_encoding() const noexcept
3678 return 0;
3681 bool
3682 __codecvt_utf8<char16_t>::do_always_noconv() const noexcept
3684 return false;
3688 __codecvt_utf8<char16_t>::do_length(state_type&,
3689 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3691 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3692 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3693 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3697 __codecvt_utf8<char16_t>::do_max_length() const noexcept
3699 if (_Mode_ & consume_header)
3700 return 6;
3701 return 3;
3704 // __codecvt_utf8<char32_t>
3706 __codecvt_utf8<char32_t>::result
3707 __codecvt_utf8<char32_t>::do_out(state_type&,
3708 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3709 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3711 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3712 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3713 const uint32_t* _frm_nxt = _frm;
3714 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3715 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3716 uint8_t* _to_nxt = _to;
3717 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3718 _Maxcode_, _Mode_);
3719 frm_nxt = frm + (_frm_nxt - _frm);
3720 to_nxt = to + (_to_nxt - _to);
3721 return r;
3724 __codecvt_utf8<char32_t>::result
3725 __codecvt_utf8<char32_t>::do_in(state_type&,
3726 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3727 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3729 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3730 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3731 const uint8_t* _frm_nxt = _frm;
3732 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3733 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3734 uint32_t* _to_nxt = _to;
3735 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3736 _Maxcode_, _Mode_);
3737 frm_nxt = frm + (_frm_nxt - _frm);
3738 to_nxt = to + (_to_nxt - _to);
3739 return r;
3742 __codecvt_utf8<char32_t>::result
3743 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3744 extern_type* to, extern_type*, extern_type*& to_nxt) const
3746 to_nxt = to;
3747 return noconv;
3751 __codecvt_utf8<char32_t>::do_encoding() const noexcept
3753 return 0;
3756 bool
3757 __codecvt_utf8<char32_t>::do_always_noconv() const noexcept
3759 return false;
3763 __codecvt_utf8<char32_t>::do_length(state_type&,
3764 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3766 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3767 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3768 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3772 __codecvt_utf8<char32_t>::do_max_length() const noexcept
3774 if (_Mode_ & consume_header)
3775 return 7;
3776 return 4;
3779 // __codecvt_utf16<wchar_t, false>
3781 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3782 __codecvt_utf16<wchar_t, false>::result
3783 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3784 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3785 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3787 #if defined(_LIBCPP_SHORT_WCHAR)
3788 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3789 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3790 const uint16_t* _frm_nxt = _frm;
3791 #else
3792 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3793 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3794 const uint32_t* _frm_nxt = _frm;
3795 #endif
3796 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3797 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3798 uint8_t* _to_nxt = _to;
3799 #if defined(_LIBCPP_SHORT_WCHAR)
3800 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3801 _Maxcode_, _Mode_);
3802 #else
3803 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3804 _Maxcode_, _Mode_);
3805 #endif
3806 frm_nxt = frm + (_frm_nxt - _frm);
3807 to_nxt = to + (_to_nxt - _to);
3808 return r;
3811 __codecvt_utf16<wchar_t, false>::result
3812 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3813 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3814 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3816 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3817 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3818 const uint8_t* _frm_nxt = _frm;
3819 #if defined(_LIBCPP_SHORT_WCHAR)
3820 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3821 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3822 uint16_t* _to_nxt = _to;
3823 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3824 _Maxcode_, _Mode_);
3825 #else
3826 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3827 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3828 uint32_t* _to_nxt = _to;
3829 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3830 _Maxcode_, _Mode_);
3831 #endif
3832 frm_nxt = frm + (_frm_nxt - _frm);
3833 to_nxt = to + (_to_nxt - _to);
3834 return r;
3837 __codecvt_utf16<wchar_t, false>::result
3838 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3839 extern_type* to, extern_type*, extern_type*& to_nxt) const
3841 to_nxt = to;
3842 return noconv;
3846 __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
3848 return 0;
3851 bool
3852 __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
3854 return false;
3858 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3859 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3861 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3862 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3863 #if defined(_LIBCPP_SHORT_WCHAR)
3864 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3865 #else
3866 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3867 #endif
3871 __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
3873 #if defined(_LIBCPP_SHORT_WCHAR)
3874 if (_Mode_ & consume_header)
3875 return 4;
3876 return 2;
3877 #else
3878 if (_Mode_ & consume_header)
3879 return 6;
3880 return 4;
3881 #endif
3884 // __codecvt_utf16<wchar_t, true>
3886 __codecvt_utf16<wchar_t, true>::result
3887 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3888 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3889 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3891 #if defined(_LIBCPP_SHORT_WCHAR)
3892 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3893 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3894 const uint16_t* _frm_nxt = _frm;
3895 #else
3896 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3897 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3898 const uint32_t* _frm_nxt = _frm;
3899 #endif
3900 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3901 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3902 uint8_t* _to_nxt = _to;
3903 #if defined(_LIBCPP_SHORT_WCHAR)
3904 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3905 _Maxcode_, _Mode_);
3906 #else
3907 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3908 _Maxcode_, _Mode_);
3909 #endif
3910 frm_nxt = frm + (_frm_nxt - _frm);
3911 to_nxt = to + (_to_nxt - _to);
3912 return r;
3915 __codecvt_utf16<wchar_t, true>::result
3916 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3917 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3918 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3920 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3921 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3922 const uint8_t* _frm_nxt = _frm;
3923 #if defined(_LIBCPP_SHORT_WCHAR)
3924 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3925 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3926 uint16_t* _to_nxt = _to;
3927 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3928 _Maxcode_, _Mode_);
3929 #else
3930 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3931 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3932 uint32_t* _to_nxt = _to;
3933 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3934 _Maxcode_, _Mode_);
3935 #endif
3936 frm_nxt = frm + (_frm_nxt - _frm);
3937 to_nxt = to + (_to_nxt - _to);
3938 return r;
3941 __codecvt_utf16<wchar_t, true>::result
3942 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3943 extern_type* to, extern_type*, extern_type*& to_nxt) const
3945 to_nxt = to;
3946 return noconv;
3950 __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
3952 return 0;
3955 bool
3956 __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
3958 return false;
3962 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3963 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3965 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3966 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3967 #if defined(_LIBCPP_SHORT_WCHAR)
3968 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3969 #else
3970 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3971 #endif
3975 __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
3977 #if defined(_LIBCPP_SHORT_WCHAR)
3978 if (_Mode_ & consume_header)
3979 return 4;
3980 return 2;
3981 #else
3982 if (_Mode_ & consume_header)
3983 return 6;
3984 return 4;
3985 #endif
3987 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3989 // __codecvt_utf16<char16_t, false>
3991 __codecvt_utf16<char16_t, false>::result
3992 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3993 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3994 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3996 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3997 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3998 const uint16_t* _frm_nxt = _frm;
3999 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4000 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4001 uint8_t* _to_nxt = _to;
4002 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4003 _Maxcode_, _Mode_);
4004 frm_nxt = frm + (_frm_nxt - _frm);
4005 to_nxt = to + (_to_nxt - _to);
4006 return r;
4009 __codecvt_utf16<char16_t, false>::result
4010 __codecvt_utf16<char16_t, false>::do_in(state_type&,
4011 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4012 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4014 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4015 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4016 const uint8_t* _frm_nxt = _frm;
4017 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4018 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4019 uint16_t* _to_nxt = _to;
4020 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4021 _Maxcode_, _Mode_);
4022 frm_nxt = frm + (_frm_nxt - _frm);
4023 to_nxt = to + (_to_nxt - _to);
4024 return r;
4027 __codecvt_utf16<char16_t, false>::result
4028 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
4029 extern_type* to, extern_type*, extern_type*& to_nxt) const
4031 to_nxt = to;
4032 return noconv;
4036 __codecvt_utf16<char16_t, false>::do_encoding() const noexcept
4038 return 0;
4041 bool
4042 __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
4044 return false;
4048 __codecvt_utf16<char16_t, false>::do_length(state_type&,
4049 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4051 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4052 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4053 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4057 __codecvt_utf16<char16_t, false>::do_max_length() const noexcept
4059 if (_Mode_ & consume_header)
4060 return 4;
4061 return 2;
4064 // __codecvt_utf16<char16_t, true>
4066 __codecvt_utf16<char16_t, true>::result
4067 __codecvt_utf16<char16_t, true>::do_out(state_type&,
4068 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4069 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4071 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4072 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4073 const uint16_t* _frm_nxt = _frm;
4074 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4075 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4076 uint8_t* _to_nxt = _to;
4077 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4078 _Maxcode_, _Mode_);
4079 frm_nxt = frm + (_frm_nxt - _frm);
4080 to_nxt = to + (_to_nxt - _to);
4081 return r;
4084 __codecvt_utf16<char16_t, true>::result
4085 __codecvt_utf16<char16_t, true>::do_in(state_type&,
4086 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4087 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4089 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4090 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4091 const uint8_t* _frm_nxt = _frm;
4092 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4093 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4094 uint16_t* _to_nxt = _to;
4095 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4096 _Maxcode_, _Mode_);
4097 frm_nxt = frm + (_frm_nxt - _frm);
4098 to_nxt = to + (_to_nxt - _to);
4099 return r;
4102 __codecvt_utf16<char16_t, true>::result
4103 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
4104 extern_type* to, extern_type*, extern_type*& to_nxt) const
4106 to_nxt = to;
4107 return noconv;
4111 __codecvt_utf16<char16_t, true>::do_encoding() const noexcept
4113 return 0;
4116 bool
4117 __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
4119 return false;
4123 __codecvt_utf16<char16_t, true>::do_length(state_type&,
4124 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4126 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4127 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4128 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4132 __codecvt_utf16<char16_t, true>::do_max_length() const noexcept
4134 if (_Mode_ & consume_header)
4135 return 4;
4136 return 2;
4139 // __codecvt_utf16<char32_t, false>
4141 __codecvt_utf16<char32_t, false>::result
4142 __codecvt_utf16<char32_t, false>::do_out(state_type&,
4143 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4144 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4146 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4147 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4148 const uint32_t* _frm_nxt = _frm;
4149 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4150 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4151 uint8_t* _to_nxt = _to;
4152 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4153 _Maxcode_, _Mode_);
4154 frm_nxt = frm + (_frm_nxt - _frm);
4155 to_nxt = to + (_to_nxt - _to);
4156 return r;
4159 __codecvt_utf16<char32_t, false>::result
4160 __codecvt_utf16<char32_t, false>::do_in(state_type&,
4161 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4162 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4164 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4165 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4166 const uint8_t* _frm_nxt = _frm;
4167 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4168 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4169 uint32_t* _to_nxt = _to;
4170 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4171 _Maxcode_, _Mode_);
4172 frm_nxt = frm + (_frm_nxt - _frm);
4173 to_nxt = to + (_to_nxt - _to);
4174 return r;
4177 __codecvt_utf16<char32_t, false>::result
4178 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
4179 extern_type* to, extern_type*, extern_type*& to_nxt) const
4181 to_nxt = to;
4182 return noconv;
4186 __codecvt_utf16<char32_t, false>::do_encoding() const noexcept
4188 return 0;
4191 bool
4192 __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
4194 return false;
4198 __codecvt_utf16<char32_t, false>::do_length(state_type&,
4199 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4201 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4202 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4203 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4207 __codecvt_utf16<char32_t, false>::do_max_length() const noexcept
4209 if (_Mode_ & consume_header)
4210 return 6;
4211 return 4;
4214 // __codecvt_utf16<char32_t, true>
4216 __codecvt_utf16<char32_t, true>::result
4217 __codecvt_utf16<char32_t, true>::do_out(state_type&,
4218 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4219 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4221 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4222 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4223 const uint32_t* _frm_nxt = _frm;
4224 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4225 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4226 uint8_t* _to_nxt = _to;
4227 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4228 _Maxcode_, _Mode_);
4229 frm_nxt = frm + (_frm_nxt - _frm);
4230 to_nxt = to + (_to_nxt - _to);
4231 return r;
4234 __codecvt_utf16<char32_t, true>::result
4235 __codecvt_utf16<char32_t, true>::do_in(state_type&,
4236 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4237 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4239 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4240 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4241 const uint8_t* _frm_nxt = _frm;
4242 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4243 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4244 uint32_t* _to_nxt = _to;
4245 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4246 _Maxcode_, _Mode_);
4247 frm_nxt = frm + (_frm_nxt - _frm);
4248 to_nxt = to + (_to_nxt - _to);
4249 return r;
4252 __codecvt_utf16<char32_t, true>::result
4253 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
4254 extern_type* to, extern_type*, extern_type*& to_nxt) const
4256 to_nxt = to;
4257 return noconv;
4261 __codecvt_utf16<char32_t, true>::do_encoding() const noexcept
4263 return 0;
4266 bool
4267 __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
4269 return false;
4273 __codecvt_utf16<char32_t, true>::do_length(state_type&,
4274 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4276 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4277 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4278 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4282 __codecvt_utf16<char32_t, true>::do_max_length() const noexcept
4284 if (_Mode_ & consume_header)
4285 return 6;
4286 return 4;
4289 // __codecvt_utf8_utf16<wchar_t>
4291 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4292 __codecvt_utf8_utf16<wchar_t>::result
4293 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4294 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4295 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4297 #if defined(_LIBCPP_SHORT_WCHAR)
4298 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4299 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4300 const uint16_t* _frm_nxt = _frm;
4301 #else
4302 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4303 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4304 const uint32_t* _frm_nxt = _frm;
4305 #endif
4306 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4307 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4308 uint8_t* _to_nxt = _to;
4309 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4310 _Maxcode_, _Mode_);
4311 frm_nxt = frm + (_frm_nxt - _frm);
4312 to_nxt = to + (_to_nxt - _to);
4313 return r;
4316 __codecvt_utf8_utf16<wchar_t>::result
4317 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4318 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4319 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4321 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4322 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4323 const uint8_t* _frm_nxt = _frm;
4324 #if defined(_LIBCPP_SHORT_WCHAR)
4325 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4326 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4327 uint16_t* _to_nxt = _to;
4328 #else
4329 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4330 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4331 uint32_t* _to_nxt = _to;
4332 #endif
4333 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4334 _Maxcode_, _Mode_);
4335 frm_nxt = frm + (_frm_nxt - _frm);
4336 to_nxt = to + (_to_nxt - _to);
4337 return r;
4340 __codecvt_utf8_utf16<wchar_t>::result
4341 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4342 extern_type* to, extern_type*, extern_type*& to_nxt) const
4344 to_nxt = to;
4345 return noconv;
4349 __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
4351 return 0;
4354 bool
4355 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
4357 return false;
4361 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4362 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4364 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4365 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4366 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4370 __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
4372 if (_Mode_ & consume_header)
4373 return 7;
4374 return 4;
4376 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4378 // __codecvt_utf8_utf16<char16_t>
4380 __codecvt_utf8_utf16<char16_t>::result
4381 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4382 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4383 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4385 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4386 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4387 const uint16_t* _frm_nxt = _frm;
4388 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4389 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4390 uint8_t* _to_nxt = _to;
4391 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4392 _Maxcode_, _Mode_);
4393 frm_nxt = frm + (_frm_nxt - _frm);
4394 to_nxt = to + (_to_nxt - _to);
4395 return r;
4398 __codecvt_utf8_utf16<char16_t>::result
4399 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4400 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4401 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4403 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4404 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4405 const uint8_t* _frm_nxt = _frm;
4406 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4407 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4408 uint16_t* _to_nxt = _to;
4409 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4410 _Maxcode_, _Mode_);
4411 frm_nxt = frm + (_frm_nxt - _frm);
4412 to_nxt = to + (_to_nxt - _to);
4413 return r;
4416 __codecvt_utf8_utf16<char16_t>::result
4417 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4418 extern_type* to, extern_type*, extern_type*& to_nxt) const
4420 to_nxt = to;
4421 return noconv;
4425 __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
4427 return 0;
4430 bool
4431 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
4433 return false;
4437 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4438 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4440 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4441 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4442 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4446 __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
4448 if (_Mode_ & consume_header)
4449 return 7;
4450 return 4;
4453 // __codecvt_utf8_utf16<char32_t>
4455 __codecvt_utf8_utf16<char32_t>::result
4456 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4457 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4458 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4460 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4461 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4462 const uint32_t* _frm_nxt = _frm;
4463 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4464 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4465 uint8_t* _to_nxt = _to;
4466 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4467 _Maxcode_, _Mode_);
4468 frm_nxt = frm + (_frm_nxt - _frm);
4469 to_nxt = to + (_to_nxt - _to);
4470 return r;
4473 __codecvt_utf8_utf16<char32_t>::result
4474 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4475 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4476 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4478 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4479 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4480 const uint8_t* _frm_nxt = _frm;
4481 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4482 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4483 uint32_t* _to_nxt = _to;
4484 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4485 _Maxcode_, _Mode_);
4486 frm_nxt = frm + (_frm_nxt - _frm);
4487 to_nxt = to + (_to_nxt - _to);
4488 return r;
4491 __codecvt_utf8_utf16<char32_t>::result
4492 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4493 extern_type* to, extern_type*, extern_type*& to_nxt) const
4495 to_nxt = to;
4496 return noconv;
4500 __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
4502 return 0;
4505 bool
4506 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
4508 return false;
4512 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4513 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4515 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4516 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4517 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4521 __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
4523 if (_Mode_ & consume_header)
4524 return 7;
4525 return 4;
4528 // __narrow_to_utf8<16>
4530 __narrow_to_utf8<16>::~__narrow_to_utf8()
4534 // __narrow_to_utf8<32>
4536 __narrow_to_utf8<32>::~__narrow_to_utf8()
4540 // __widen_from_utf8<16>
4542 __widen_from_utf8<16>::~__widen_from_utf8()
4546 // __widen_from_utf8<32>
4548 __widen_from_utf8<32>::~__widen_from_utf8()
4552 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4553 static bool checked_string_to_wchar_convert(wchar_t& dest,
4554 const char* ptr,
4555 locale_t loc) {
4556 if (*ptr == '\0')
4557 return false;
4558 mbstate_t mb = {};
4559 wchar_t out;
4560 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4561 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4562 return false;
4564 dest = out;
4565 return true;
4567 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4569 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4570 static bool is_narrow_non_breaking_space(const char* ptr) {
4571 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4572 return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
4575 static bool is_non_breaking_space(const char* ptr) {
4576 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4577 return ptr[0] == '\xc2' && ptr[1] == '\xa0';
4579 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4581 static bool checked_string_to_char_convert(char& dest,
4582 const char* ptr,
4583 locale_t __loc) {
4584 if (*ptr == '\0')
4585 return false;
4586 if (!ptr[1]) {
4587 dest = *ptr;
4588 return true;
4591 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4592 // First convert the MBS into a wide char then attempt to narrow it using
4593 // wctob_l.
4594 wchar_t wout;
4595 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4596 return false;
4597 int res;
4598 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4599 dest = res;
4600 return true;
4602 // FIXME: Work around specific multibyte sequences that we can reasonably
4603 // translate into a different single byte.
4604 switch (wout) {
4605 case L'\u202F': // narrow non-breaking space
4606 case L'\u00A0': // non-breaking space
4607 dest = ' ';
4608 return true;
4609 default:
4610 return false;
4612 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4613 // FIXME: Work around specific multibyte sequences that we can reasonably
4614 // translate into a different single byte.
4615 if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
4616 dest = ' ';
4617 return true;
4620 return false;
4621 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4622 __libcpp_unreachable();
4626 // numpunct<char> && numpunct<wchar_t>
4628 locale::id numpunct< char >::id;
4629 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4630 locale::id numpunct<wchar_t>::id;
4631 #endif
4633 numpunct<char>::numpunct(size_t refs)
4634 : locale::facet(refs),
4635 __decimal_point_('.'),
4636 __thousands_sep_(',')
4640 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4641 numpunct<wchar_t>::numpunct(size_t refs)
4642 : locale::facet(refs),
4643 __decimal_point_(L'.'),
4644 __thousands_sep_(L',')
4647 #endif
4649 numpunct<char>::~numpunct()
4653 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4654 numpunct<wchar_t>::~numpunct()
4657 #endif
4659 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4660 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4661 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4662 #endif
4664 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4665 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4666 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4667 #endif
4669 string numpunct< char >::do_grouping() const {return __grouping_;}
4670 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4671 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4672 #endif
4674 string numpunct< char >::do_truename() const {return "true";}
4675 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4676 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4677 #endif
4679 string numpunct< char >::do_falsename() const {return "false";}
4680 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4681 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4682 #endif
4684 // numpunct_byname<char>
4686 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4687 : numpunct<char>(refs)
4689 __init(nm);
4692 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4693 : numpunct<char>(refs)
4695 __init(nm.c_str());
4698 numpunct_byname<char>::~numpunct_byname()
4702 void
4703 numpunct_byname<char>::__init(const char* nm)
4705 typedef numpunct<char> base;
4706 if (strcmp(nm, "C") != 0)
4708 __libcpp_unique_locale loc(nm);
4709 if (!loc)
4710 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4711 " failed to construct for " + string(nm));
4713 lconv* lc = __libcpp_localeconv_l(loc.get());
4714 if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4715 loc.get()))
4716 __decimal_point_ = base::do_decimal_point();
4717 if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4718 loc.get()))
4719 __thousands_sep_ = base::do_thousands_sep();
4720 __grouping_ = lc->grouping;
4721 // localization for truename and falsename is not available
4725 // numpunct_byname<wchar_t>
4727 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4728 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4729 : numpunct<wchar_t>(refs)
4731 __init(nm);
4734 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4735 : numpunct<wchar_t>(refs)
4737 __init(nm.c_str());
4740 numpunct_byname<wchar_t>::~numpunct_byname()
4744 void
4745 numpunct_byname<wchar_t>::__init(const char* nm)
4747 if (strcmp(nm, "C") != 0)
4749 __libcpp_unique_locale loc(nm);
4750 if (!loc)
4751 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4752 " failed to construct for " + string(nm));
4754 lconv* lc = __libcpp_localeconv_l(loc.get());
4755 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4756 loc.get());
4757 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4758 loc.get());
4759 __grouping_ = lc->grouping;
4760 // localization for truename and falsename is not available
4763 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4765 // num_get helpers
4768 __num_get_base::__get_base(ios_base& iob)
4770 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4771 if (__basefield == ios_base::oct)
4772 return 8;
4773 else if (__basefield == ios_base::hex)
4774 return 16;
4775 else if (__basefield == 0)
4776 return 0;
4777 return 10;
4780 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4782 void
4783 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4784 ios_base::iostate& __err)
4786 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4787 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4788 if (__grouping.size() != 0 && __g_end - __g > 1)
4790 reverse(__g, __g_end);
4791 const char* __ig = __grouping.data();
4792 const char* __eg = __ig + __grouping.size();
4793 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4795 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4797 if (static_cast<unsigned>(*__ig) != *__r)
4799 __err = ios_base::failbit;
4800 return;
4803 if (__eg - __ig > 1)
4804 ++__ig;
4806 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4808 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4809 __err = ios_base::failbit;
4814 void
4815 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4816 ios_base::fmtflags __flags)
4818 if ((__flags & ios_base::showpos) &&
4819 (__flags & ios_base::basefield) != ios_base::oct &&
4820 (__flags & ios_base::basefield) != ios_base::hex &&
4821 __signd)
4822 *__fmtp++ = '+';
4823 if (__flags & ios_base::showbase)
4824 *__fmtp++ = '#';
4825 while(*__len)
4826 *__fmtp++ = *__len++;
4827 if ((__flags & ios_base::basefield) == ios_base::oct)
4828 *__fmtp = 'o';
4829 else if ((__flags & ios_base::basefield) == ios_base::hex)
4831 if (__flags & ios_base::uppercase)
4832 *__fmtp = 'X';
4833 else
4834 *__fmtp = 'x';
4836 else if (__signd)
4837 *__fmtp = 'd';
4838 else
4839 *__fmtp = 'u';
4842 bool
4843 __num_put_base::__format_float(char* __fmtp, const char* __len,
4844 ios_base::fmtflags __flags)
4846 bool specify_precision = true;
4847 if (__flags & ios_base::showpos)
4848 *__fmtp++ = '+';
4849 if (__flags & ios_base::showpoint)
4850 *__fmtp++ = '#';
4851 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4852 bool uppercase = (__flags & ios_base::uppercase) != 0;
4853 if (floatfield == (ios_base::fixed | ios_base::scientific))
4854 specify_precision = false;
4855 else
4857 *__fmtp++ = '.';
4858 *__fmtp++ = '*';
4860 while(*__len)
4861 *__fmtp++ = *__len++;
4862 if (floatfield == ios_base::fixed)
4864 if (uppercase)
4865 *__fmtp = 'F';
4866 else
4867 *__fmtp = 'f';
4869 else if (floatfield == ios_base::scientific)
4871 if (uppercase)
4872 *__fmtp = 'E';
4873 else
4874 *__fmtp = 'e';
4876 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4878 if (uppercase)
4879 *__fmtp = 'A';
4880 else
4881 *__fmtp = 'a';
4883 else
4885 if (uppercase)
4886 *__fmtp = 'G';
4887 else
4888 *__fmtp = 'g';
4890 return specify_precision;
4893 char*
4894 __num_put_base::__identify_padding(char* __nb, char* __ne,
4895 const ios_base& __iob)
4897 switch (__iob.flags() & ios_base::adjustfield)
4899 case ios_base::internal:
4900 if (__nb[0] == '-' || __nb[0] == '+')
4901 return __nb+1;
4902 if (__ne - __nb >= 2 && __nb[0] == '0'
4903 && (__nb[1] == 'x' || __nb[1] == 'X'))
4904 return __nb+2;
4905 break;
4906 case ios_base::left:
4907 return __ne;
4908 case ios_base::right:
4909 default:
4910 break;
4912 return __nb;
4915 // time_get
4917 static
4918 string*
4919 init_weeks()
4921 static string weeks[14];
4922 weeks[0] = "Sunday";
4923 weeks[1] = "Monday";
4924 weeks[2] = "Tuesday";
4925 weeks[3] = "Wednesday";
4926 weeks[4] = "Thursday";
4927 weeks[5] = "Friday";
4928 weeks[6] = "Saturday";
4929 weeks[7] = "Sun";
4930 weeks[8] = "Mon";
4931 weeks[9] = "Tue";
4932 weeks[10] = "Wed";
4933 weeks[11] = "Thu";
4934 weeks[12] = "Fri";
4935 weeks[13] = "Sat";
4936 return weeks;
4939 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4940 static
4941 wstring*
4942 init_wweeks()
4944 static wstring weeks[14];
4945 weeks[0] = L"Sunday";
4946 weeks[1] = L"Monday";
4947 weeks[2] = L"Tuesday";
4948 weeks[3] = L"Wednesday";
4949 weeks[4] = L"Thursday";
4950 weeks[5] = L"Friday";
4951 weeks[6] = L"Saturday";
4952 weeks[7] = L"Sun";
4953 weeks[8] = L"Mon";
4954 weeks[9] = L"Tue";
4955 weeks[10] = L"Wed";
4956 weeks[11] = L"Thu";
4957 weeks[12] = L"Fri";
4958 weeks[13] = L"Sat";
4959 return weeks;
4961 #endif
4963 template <>
4964 const string*
4965 __time_get_c_storage<char>::__weeks() const
4967 static const string* weeks = init_weeks();
4968 return weeks;
4971 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4972 template <>
4973 const wstring*
4974 __time_get_c_storage<wchar_t>::__weeks() const
4976 static const wstring* weeks = init_wweeks();
4977 return weeks;
4979 #endif
4981 static
4982 string*
4983 init_months()
4985 static string months[24];
4986 months[0] = "January";
4987 months[1] = "February";
4988 months[2] = "March";
4989 months[3] = "April";
4990 months[4] = "May";
4991 months[5] = "June";
4992 months[6] = "July";
4993 months[7] = "August";
4994 months[8] = "September";
4995 months[9] = "October";
4996 months[10] = "November";
4997 months[11] = "December";
4998 months[12] = "Jan";
4999 months[13] = "Feb";
5000 months[14] = "Mar";
5001 months[15] = "Apr";
5002 months[16] = "May";
5003 months[17] = "Jun";
5004 months[18] = "Jul";
5005 months[19] = "Aug";
5006 months[20] = "Sep";
5007 months[21] = "Oct";
5008 months[22] = "Nov";
5009 months[23] = "Dec";
5010 return months;
5013 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5014 static
5015 wstring*
5016 init_wmonths()
5018 static wstring months[24];
5019 months[0] = L"January";
5020 months[1] = L"February";
5021 months[2] = L"March";
5022 months[3] = L"April";
5023 months[4] = L"May";
5024 months[5] = L"June";
5025 months[6] = L"July";
5026 months[7] = L"August";
5027 months[8] = L"September";
5028 months[9] = L"October";
5029 months[10] = L"November";
5030 months[11] = L"December";
5031 months[12] = L"Jan";
5032 months[13] = L"Feb";
5033 months[14] = L"Mar";
5034 months[15] = L"Apr";
5035 months[16] = L"May";
5036 months[17] = L"Jun";
5037 months[18] = L"Jul";
5038 months[19] = L"Aug";
5039 months[20] = L"Sep";
5040 months[21] = L"Oct";
5041 months[22] = L"Nov";
5042 months[23] = L"Dec";
5043 return months;
5045 #endif
5047 template <>
5048 const string*
5049 __time_get_c_storage<char>::__months() const
5051 static const string* months = init_months();
5052 return months;
5055 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5056 template <>
5057 const wstring*
5058 __time_get_c_storage<wchar_t>::__months() const
5060 static const wstring* months = init_wmonths();
5061 return months;
5063 #endif
5065 static
5066 string*
5067 init_am_pm()
5069 static string am_pm[2];
5070 am_pm[0] = "AM";
5071 am_pm[1] = "PM";
5072 return am_pm;
5075 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5076 static
5077 wstring*
5078 init_wam_pm()
5080 static wstring am_pm[2];
5081 am_pm[0] = L"AM";
5082 am_pm[1] = L"PM";
5083 return am_pm;
5085 #endif
5087 template <>
5088 const string*
5089 __time_get_c_storage<char>::__am_pm() const
5091 static const string* am_pm = init_am_pm();
5092 return am_pm;
5095 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5096 template <>
5097 const wstring*
5098 __time_get_c_storage<wchar_t>::__am_pm() const
5100 static const wstring* am_pm = init_wam_pm();
5101 return am_pm;
5103 #endif
5105 template <>
5106 const string&
5107 __time_get_c_storage<char>::__x() const
5109 static string s("%m/%d/%y");
5110 return s;
5113 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5114 template <>
5115 const wstring&
5116 __time_get_c_storage<wchar_t>::__x() const
5118 static wstring s(L"%m/%d/%y");
5119 return s;
5121 #endif
5123 template <>
5124 const string&
5125 __time_get_c_storage<char>::__X() const
5127 static string s("%H:%M:%S");
5128 return s;
5131 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5132 template <>
5133 const wstring&
5134 __time_get_c_storage<wchar_t>::__X() const
5136 static wstring s(L"%H:%M:%S");
5137 return s;
5139 #endif
5141 template <>
5142 const string&
5143 __time_get_c_storage<char>::__c() const
5145 static string s("%a %b %d %H:%M:%S %Y");
5146 return s;
5149 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5150 template <>
5151 const wstring&
5152 __time_get_c_storage<wchar_t>::__c() const
5154 static wstring s(L"%a %b %d %H:%M:%S %Y");
5155 return s;
5157 #endif
5159 template <>
5160 const string&
5161 __time_get_c_storage<char>::__r() const
5163 static string s("%I:%M:%S %p");
5164 return s;
5167 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5168 template <>
5169 const wstring&
5170 __time_get_c_storage<wchar_t>::__r() const
5172 static wstring s(L"%I:%M:%S %p");
5173 return s;
5175 #endif
5177 // time_get_byname
5179 __time_get::__time_get(const char* nm)
5180 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5182 if (__loc_ == 0)
5183 __throw_runtime_error("time_get_byname"
5184 " failed to construct for " + string(nm));
5187 __time_get::__time_get(const string& nm)
5188 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5190 if (__loc_ == 0)
5191 __throw_runtime_error("time_get_byname"
5192 " failed to construct for " + nm);
5195 __time_get::~__time_get()
5197 freelocale(__loc_);
5200 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5202 template <>
5203 string
5204 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
5206 tm t = {0};
5207 t.tm_sec = 59;
5208 t.tm_min = 55;
5209 t.tm_hour = 23;
5210 t.tm_mday = 31;
5211 t.tm_mon = 11;
5212 t.tm_year = 161;
5213 t.tm_wday = 6;
5214 t.tm_yday = 364;
5215 t.tm_isdst = -1;
5216 char buf[100];
5217 char f[3] = {0};
5218 f[0] = '%';
5219 f[1] = fmt;
5220 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
5221 char* bb = buf;
5222 char* be = buf + n;
5223 string result;
5224 while (bb != be)
5226 if (ct.is(ctype_base::space, *bb))
5228 result.push_back(' ');
5229 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
5231 continue;
5233 char* w = bb;
5234 ios_base::iostate err = ios_base::goodbit;
5235 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
5236 ct, err, false)
5237 - this->__weeks_;
5238 if (i < 14)
5240 result.push_back('%');
5241 if (i < 7)
5242 result.push_back('A');
5243 else
5244 result.push_back('a');
5245 bb = w;
5246 continue;
5248 w = bb;
5249 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
5250 ct, err, false)
5251 - this->__months_;
5252 if (i < 24)
5254 result.push_back('%');
5255 if (i < 12)
5256 result.push_back('B');
5257 else
5258 result.push_back('b');
5259 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5260 result.back() = 'm';
5261 bb = w;
5262 continue;
5264 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5266 w = bb;
5267 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
5268 ct, err, false) - this->__am_pm_;
5269 if (i < 2)
5271 result.push_back('%');
5272 result.push_back('p');
5273 bb = w;
5274 continue;
5277 w = bb;
5278 if (ct.is(ctype_base::digit, *bb))
5280 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
5282 case 6:
5283 result.push_back('%');
5284 result.push_back('w');
5285 break;
5286 case 7:
5287 result.push_back('%');
5288 result.push_back('u');
5289 break;
5290 case 11:
5291 result.push_back('%');
5292 result.push_back('I');
5293 break;
5294 case 12:
5295 result.push_back('%');
5296 result.push_back('m');
5297 break;
5298 case 23:
5299 result.push_back('%');
5300 result.push_back('H');
5301 break;
5302 case 31:
5303 result.push_back('%');
5304 result.push_back('d');
5305 break;
5306 case 55:
5307 result.push_back('%');
5308 result.push_back('M');
5309 break;
5310 case 59:
5311 result.push_back('%');
5312 result.push_back('S');
5313 break;
5314 case 61:
5315 result.push_back('%');
5316 result.push_back('y');
5317 break;
5318 case 364:
5319 result.push_back('%');
5320 result.push_back('j');
5321 break;
5322 case 2061:
5323 result.push_back('%');
5324 result.push_back('Y');
5325 break;
5326 default:
5327 for (; w != bb; ++w)
5328 result.push_back(*w);
5329 break;
5331 continue;
5333 if (*bb == '%')
5335 result.push_back('%');
5336 result.push_back('%');
5337 ++bb;
5338 continue;
5340 result.push_back(*bb);
5341 ++bb;
5343 return result;
5346 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5348 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5349 template <>
5350 wstring
5351 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
5353 tm t = {0};
5354 t.tm_sec = 59;
5355 t.tm_min = 55;
5356 t.tm_hour = 23;
5357 t.tm_mday = 31;
5358 t.tm_mon = 11;
5359 t.tm_year = 161;
5360 t.tm_wday = 6;
5361 t.tm_yday = 364;
5362 t.tm_isdst = -1;
5363 char buf[100];
5364 char f[3] = {0};
5365 f[0] = '%';
5366 f[1] = fmt;
5367 strftime_l(buf, countof(buf), f, &t, __loc_);
5368 wchar_t wbuf[100];
5369 wchar_t* wbb = wbuf;
5370 mbstate_t mb = {0};
5371 const char* bb = buf;
5372 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
5373 if (j == size_t(-1))
5374 __throw_runtime_error("locale not supported");
5375 wchar_t* wbe = wbb + j;
5376 wstring result;
5377 while (wbb != wbe)
5379 if (ct.is(ctype_base::space, *wbb))
5381 result.push_back(L' ');
5382 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
5384 continue;
5386 wchar_t* w = wbb;
5387 ios_base::iostate err = ios_base::goodbit;
5388 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
5389 ct, err, false)
5390 - this->__weeks_;
5391 if (i < 14)
5393 result.push_back(L'%');
5394 if (i < 7)
5395 result.push_back(L'A');
5396 else
5397 result.push_back(L'a');
5398 wbb = w;
5399 continue;
5401 w = wbb;
5402 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5403 ct, err, false)
5404 - this->__months_;
5405 if (i < 24)
5407 result.push_back(L'%');
5408 if (i < 12)
5409 result.push_back(L'B');
5410 else
5411 result.push_back(L'b');
5412 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5413 result.back() = L'm';
5414 wbb = w;
5415 continue;
5417 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5419 w = wbb;
5420 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5421 ct, err, false) - this->__am_pm_;
5422 if (i < 2)
5424 result.push_back(L'%');
5425 result.push_back(L'p');
5426 wbb = w;
5427 continue;
5430 w = wbb;
5431 if (ct.is(ctype_base::digit, *wbb))
5433 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5435 case 6:
5436 result.push_back(L'%');
5437 result.push_back(L'w');
5438 break;
5439 case 7:
5440 result.push_back(L'%');
5441 result.push_back(L'u');
5442 break;
5443 case 11:
5444 result.push_back(L'%');
5445 result.push_back(L'I');
5446 break;
5447 case 12:
5448 result.push_back(L'%');
5449 result.push_back(L'm');
5450 break;
5451 case 23:
5452 result.push_back(L'%');
5453 result.push_back(L'H');
5454 break;
5455 case 31:
5456 result.push_back(L'%');
5457 result.push_back(L'd');
5458 break;
5459 case 55:
5460 result.push_back(L'%');
5461 result.push_back(L'M');
5462 break;
5463 case 59:
5464 result.push_back(L'%');
5465 result.push_back(L'S');
5466 break;
5467 case 61:
5468 result.push_back(L'%');
5469 result.push_back(L'y');
5470 break;
5471 case 364:
5472 result.push_back(L'%');
5473 result.push_back(L'j');
5474 break;
5475 case 2061:
5476 result.push_back(L'%');
5477 result.push_back(L'Y');
5478 break;
5479 default:
5480 for (; w != wbb; ++w)
5481 result.push_back(*w);
5482 break;
5484 continue;
5486 if (ct.narrow(*wbb, 0) == '%')
5488 result.push_back(L'%');
5489 result.push_back(L'%');
5490 ++wbb;
5491 continue;
5493 result.push_back(*wbb);
5494 ++wbb;
5496 return result;
5498 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5500 template <>
5501 void
5502 __time_get_storage<char>::init(const ctype<char>& ct)
5504 tm t = {0};
5505 char buf[100];
5506 // __weeks_
5507 for (int i = 0; i < 7; ++i)
5509 t.tm_wday = i;
5510 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5511 __weeks_[i] = buf;
5512 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5513 __weeks_[i+7] = buf;
5515 // __months_
5516 for (int i = 0; i < 12; ++i)
5518 t.tm_mon = i;
5519 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5520 __months_[i] = buf;
5521 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5522 __months_[i+12] = buf;
5524 // __am_pm_
5525 t.tm_hour = 1;
5526 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5527 __am_pm_[0] = buf;
5528 t.tm_hour = 13;
5529 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5530 __am_pm_[1] = buf;
5531 __c_ = __analyze('c', ct);
5532 __r_ = __analyze('r', ct);
5533 __x_ = __analyze('x', ct);
5534 __X_ = __analyze('X', ct);
5537 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5538 template <>
5539 void
5540 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5542 tm t = {0};
5543 char buf[100];
5544 wchar_t wbuf[100];
5545 wchar_t* wbe;
5546 mbstate_t mb = {0};
5547 // __weeks_
5548 for (int i = 0; i < 7; ++i)
5550 t.tm_wday = i;
5551 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5552 mb = mbstate_t();
5553 const char* bb = buf;
5554 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5555 if (j == size_t(-1) || j == 0)
5556 __throw_runtime_error("locale not supported");
5557 wbe = wbuf + j;
5558 __weeks_[i].assign(wbuf, wbe);
5559 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5560 mb = mbstate_t();
5561 bb = buf;
5562 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5563 if (j == size_t(-1) || j == 0)
5564 __throw_runtime_error("locale not supported");
5565 wbe = wbuf + j;
5566 __weeks_[i+7].assign(wbuf, wbe);
5568 // __months_
5569 for (int i = 0; i < 12; ++i)
5571 t.tm_mon = i;
5572 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5573 mb = mbstate_t();
5574 const char* bb = buf;
5575 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5576 if (j == size_t(-1) || j == 0)
5577 __throw_runtime_error("locale not supported");
5578 wbe = wbuf + j;
5579 __months_[i].assign(wbuf, wbe);
5580 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5581 mb = mbstate_t();
5582 bb = buf;
5583 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5584 if (j == size_t(-1) || j == 0)
5585 __throw_runtime_error("locale not supported");
5586 wbe = wbuf + j;
5587 __months_[i+12].assign(wbuf, wbe);
5589 // __am_pm_
5590 t.tm_hour = 1;
5591 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5592 mb = mbstate_t();
5593 const char* bb = buf;
5594 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5595 if (j == size_t(-1))
5596 __throw_runtime_error("locale not supported");
5597 wbe = wbuf + j;
5598 __am_pm_[0].assign(wbuf, wbe);
5599 t.tm_hour = 13;
5600 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5601 mb = mbstate_t();
5602 bb = buf;
5603 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5604 if (j == size_t(-1))
5605 __throw_runtime_error("locale not supported");
5606 wbe = wbuf + j;
5607 __am_pm_[1].assign(wbuf, wbe);
5608 __c_ = __analyze('c', ct);
5609 __r_ = __analyze('r', ct);
5610 __x_ = __analyze('x', ct);
5611 __X_ = __analyze('X', ct);
5613 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5615 template <class CharT>
5616 struct _LIBCPP_HIDDEN __time_get_temp
5617 : public ctype_byname<CharT>
5619 explicit __time_get_temp(const char* nm)
5620 : ctype_byname<CharT>(nm, 1) {}
5621 explicit __time_get_temp(const string& nm)
5622 : ctype_byname<CharT>(nm, 1) {}
5625 template <>
5626 __time_get_storage<char>::__time_get_storage(const char* __nm)
5627 : __time_get(__nm)
5629 const __time_get_temp<char> ct(__nm);
5630 init(ct);
5633 template <>
5634 __time_get_storage<char>::__time_get_storage(const string& __nm)
5635 : __time_get(__nm)
5637 const __time_get_temp<char> ct(__nm);
5638 init(ct);
5641 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5642 template <>
5643 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5644 : __time_get(__nm)
5646 const __time_get_temp<wchar_t> ct(__nm);
5647 init(ct);
5650 template <>
5651 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5652 : __time_get(__nm)
5654 const __time_get_temp<wchar_t> ct(__nm);
5655 init(ct);
5657 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5659 template <>
5660 time_base::dateorder
5661 __time_get_storage<char>::__do_date_order() const
5663 unsigned i;
5664 for (i = 0; i < __x_.size(); ++i)
5665 if (__x_[i] == '%')
5666 break;
5667 ++i;
5668 switch (__x_[i])
5670 case 'y':
5671 case 'Y':
5672 for (++i; i < __x_.size(); ++i)
5673 if (__x_[i] == '%')
5674 break;
5675 if (i == __x_.size())
5676 break;
5677 ++i;
5678 switch (__x_[i])
5680 case 'm':
5681 for (++i; i < __x_.size(); ++i)
5682 if (__x_[i] == '%')
5683 break;
5684 if (i == __x_.size())
5685 break;
5686 ++i;
5687 if (__x_[i] == 'd')
5688 return time_base::ymd;
5689 break;
5690 case 'd':
5691 for (++i; i < __x_.size(); ++i)
5692 if (__x_[i] == '%')
5693 break;
5694 if (i == __x_.size())
5695 break;
5696 ++i;
5697 if (__x_[i] == 'm')
5698 return time_base::ydm;
5699 break;
5701 break;
5702 case 'm':
5703 for (++i; i < __x_.size(); ++i)
5704 if (__x_[i] == '%')
5705 break;
5706 if (i == __x_.size())
5707 break;
5708 ++i;
5709 if (__x_[i] == 'd')
5711 for (++i; i < __x_.size(); ++i)
5712 if (__x_[i] == '%')
5713 break;
5714 if (i == __x_.size())
5715 break;
5716 ++i;
5717 if (__x_[i] == 'y' || __x_[i] == 'Y')
5718 return time_base::mdy;
5719 break;
5721 break;
5722 case 'd':
5723 for (++i; i < __x_.size(); ++i)
5724 if (__x_[i] == '%')
5725 break;
5726 if (i == __x_.size())
5727 break;
5728 ++i;
5729 if (__x_[i] == 'm')
5731 for (++i; i < __x_.size(); ++i)
5732 if (__x_[i] == '%')
5733 break;
5734 if (i == __x_.size())
5735 break;
5736 ++i;
5737 if (__x_[i] == 'y' || __x_[i] == 'Y')
5738 return time_base::dmy;
5739 break;
5741 break;
5743 return time_base::no_order;
5746 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5747 template <>
5748 time_base::dateorder
5749 __time_get_storage<wchar_t>::__do_date_order() const
5751 unsigned i;
5752 for (i = 0; i < __x_.size(); ++i)
5753 if (__x_[i] == L'%')
5754 break;
5755 ++i;
5756 switch (__x_[i])
5758 case L'y':
5759 case L'Y':
5760 for (++i; i < __x_.size(); ++i)
5761 if (__x_[i] == L'%')
5762 break;
5763 if (i == __x_.size())
5764 break;
5765 ++i;
5766 switch (__x_[i])
5768 case L'm':
5769 for (++i; i < __x_.size(); ++i)
5770 if (__x_[i] == L'%')
5771 break;
5772 if (i == __x_.size())
5773 break;
5774 ++i;
5775 if (__x_[i] == L'd')
5776 return time_base::ymd;
5777 break;
5778 case L'd':
5779 for (++i; i < __x_.size(); ++i)
5780 if (__x_[i] == L'%')
5781 break;
5782 if (i == __x_.size())
5783 break;
5784 ++i;
5785 if (__x_[i] == L'm')
5786 return time_base::ydm;
5787 break;
5789 break;
5790 case L'm':
5791 for (++i; i < __x_.size(); ++i)
5792 if (__x_[i] == L'%')
5793 break;
5794 if (i == __x_.size())
5795 break;
5796 ++i;
5797 if (__x_[i] == L'd')
5799 for (++i; i < __x_.size(); ++i)
5800 if (__x_[i] == L'%')
5801 break;
5802 if (i == __x_.size())
5803 break;
5804 ++i;
5805 if (__x_[i] == L'y' || __x_[i] == L'Y')
5806 return time_base::mdy;
5807 break;
5809 break;
5810 case L'd':
5811 for (++i; i < __x_.size(); ++i)
5812 if (__x_[i] == L'%')
5813 break;
5814 if (i == __x_.size())
5815 break;
5816 ++i;
5817 if (__x_[i] == L'm')
5819 for (++i; i < __x_.size(); ++i)
5820 if (__x_[i] == L'%')
5821 break;
5822 if (i == __x_.size())
5823 break;
5824 ++i;
5825 if (__x_[i] == L'y' || __x_[i] == L'Y')
5826 return time_base::dmy;
5827 break;
5829 break;
5831 return time_base::no_order;
5833 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5835 // time_put
5837 __time_put::__time_put(const char* nm)
5838 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5840 if (__loc_ == 0)
5841 __throw_runtime_error("time_put_byname"
5842 " failed to construct for " + string(nm));
5845 __time_put::__time_put(const string& nm)
5846 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5848 if (__loc_ == 0)
5849 __throw_runtime_error("time_put_byname"
5850 " failed to construct for " + nm);
5853 __time_put::~__time_put()
5855 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5856 freelocale(__loc_);
5859 void
5860 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5861 char __fmt, char __mod) const
5863 char fmt[] = {'%', __fmt, __mod, 0};
5864 if (__mod != 0)
5865 swap(fmt[1], fmt[2]);
5866 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5867 __ne = __nb + n;
5870 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5871 void
5872 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5873 char __fmt, char __mod) const
5875 char __nar[100];
5876 char* __ne = __nar + 100;
5877 __do_put(__nar, __ne, __tm, __fmt, __mod);
5878 mbstate_t mb = {0};
5879 const char* __nb = __nar;
5880 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5881 if (j == size_t(-1))
5882 __throw_runtime_error("locale not supported");
5883 __we = __wb + j;
5885 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5887 // moneypunct_byname
5889 template <class charT>
5890 static
5891 void
5892 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5893 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5894 charT space_char)
5896 const char sign = static_cast<char>(money_base::sign);
5897 const char space = static_cast<char>(money_base::space);
5898 const char none = static_cast<char>(money_base::none);
5899 const char symbol = static_cast<char>(money_base::symbol);
5900 const char value = static_cast<char>(money_base::value);
5901 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5903 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5904 // function'. "Space between sign and symbol or value" means that
5905 // if the sign is adjacent to the symbol, there's a space between
5906 // them, and otherwise there's a space between the sign and value.
5908 // C11's localeconv specifies that the fourth character of an
5909 // international curr_symbol is used to separate the sign and
5910 // value when sep_by_space says to do so. C++ can't represent
5911 // that, so we just use a space. When sep_by_space says to
5912 // separate the symbol and value-or-sign with a space, we rearrange the
5913 // curr_symbol to put its spacing character on the correct side of
5914 // the symbol.
5916 // We also need to avoid adding an extra space between the sign
5917 // and value when the currency symbol is suppressed (by not
5918 // setting showbase). We match glibc's strfmon by interpreting
5919 // sep_by_space==1 as "omit the space when the currency symbol is
5920 // absent".
5922 // Users who want to get this right should use ICU instead.
5924 switch (cs_precedes)
5926 case 0: // value before curr_symbol
5927 if (symbol_contains_sep) {
5928 // Move the separator to before the symbol, to place it
5929 // between the value and symbol.
5930 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5931 __curr_symbol_.end());
5933 switch (sign_posn)
5935 case 0: // Parentheses surround the quantity and currency symbol.
5936 pat.field[0] = sign;
5937 pat.field[1] = value;
5938 pat.field[2] = none; // Any space appears in the symbol.
5939 pat.field[3] = symbol;
5940 switch (sep_by_space)
5942 case 0: // No space separates the currency symbol and value.
5943 // This case may have changed between C99 and C11;
5944 // assume the currency symbol matches the intention.
5945 case 2: // Space between sign and currency or value.
5946 // The "sign" is two parentheses, so no space here either.
5947 return;
5948 case 1: // Space between currency-and-sign or currency and value.
5949 if (!symbol_contains_sep) {
5950 // We insert the space into the symbol instead of
5951 // setting pat.field[2]=space so that when
5952 // showbase is not set, the space goes away too.
5953 __curr_symbol_.insert(0, 1, space_char);
5955 return;
5956 default:
5957 break;
5959 break;
5960 case 1: // The sign string precedes the quantity and currency symbol.
5961 pat.field[0] = sign;
5962 pat.field[3] = symbol;
5963 switch (sep_by_space)
5965 case 0: // No space separates the currency symbol and value.
5966 pat.field[1] = value;
5967 pat.field[2] = none;
5968 return;
5969 case 1: // Space between currency-and-sign or currency and value.
5970 pat.field[1] = value;
5971 pat.field[2] = none;
5972 if (!symbol_contains_sep) {
5973 // We insert the space into the symbol instead of
5974 // setting pat.field[2]=space so that when
5975 // showbase is not set, the space goes away too.
5976 __curr_symbol_.insert(0, 1, space_char);
5978 return;
5979 case 2: // Space between sign and currency or value.
5980 pat.field[1] = space;
5981 pat.field[2] = value;
5982 if (symbol_contains_sep) {
5983 // Remove the separator from the symbol, since it
5984 // has already appeared after the sign.
5985 __curr_symbol_.erase(__curr_symbol_.begin());
5987 return;
5988 default:
5989 break;
5991 break;
5992 case 2: // The sign string succeeds the quantity and currency symbol.
5993 pat.field[0] = value;
5994 pat.field[3] = sign;
5995 switch (sep_by_space)
5997 case 0: // No space separates the currency symbol and value.
5998 pat.field[1] = none;
5999 pat.field[2] = symbol;
6000 return;
6001 case 1: // Space between currency-and-sign or currency and value.
6002 if (!symbol_contains_sep) {
6003 // We insert the space into the symbol instead of
6004 // setting pat.field[1]=space so that when
6005 // showbase is not set, the space goes away too.
6006 __curr_symbol_.insert(0, 1, space_char);
6008 pat.field[1] = none;
6009 pat.field[2] = symbol;
6010 return;
6011 case 2: // Space between sign and currency or value.
6012 pat.field[1] = symbol;
6013 pat.field[2] = space;
6014 if (symbol_contains_sep) {
6015 // Remove the separator from the symbol, since it
6016 // should not be removed if showbase is absent.
6017 __curr_symbol_.erase(__curr_symbol_.begin());
6019 return;
6020 default:
6021 break;
6023 break;
6024 case 3: // The sign string immediately precedes the currency symbol.
6025 pat.field[0] = value;
6026 pat.field[3] = symbol;
6027 switch (sep_by_space)
6029 case 0: // No space separates the currency symbol and value.
6030 pat.field[1] = none;
6031 pat.field[2] = sign;
6032 return;
6033 case 1: // Space between currency-and-sign or currency and value.
6034 pat.field[1] = space;
6035 pat.field[2] = sign;
6036 if (symbol_contains_sep) {
6037 // Remove the separator from the symbol, since it
6038 // has already appeared before the sign.
6039 __curr_symbol_.erase(__curr_symbol_.begin());
6041 return;
6042 case 2: // Space between sign and currency or value.
6043 pat.field[1] = sign;
6044 pat.field[2] = none;
6045 if (!symbol_contains_sep) {
6046 // We insert the space into the symbol instead of
6047 // setting pat.field[2]=space so that when
6048 // showbase is not set, the space goes away too.
6049 __curr_symbol_.insert(0, 1, space_char);
6051 return;
6052 default:
6053 break;
6055 break;
6056 case 4: // The sign string immediately succeeds the currency symbol.
6057 pat.field[0] = value;
6058 pat.field[3] = sign;
6059 switch (sep_by_space)
6061 case 0: // No space separates the currency symbol and value.
6062 pat.field[1] = none;
6063 pat.field[2] = symbol;
6064 return;
6065 case 1: // Space between currency-and-sign or currency and value.
6066 pat.field[1] = none;
6067 pat.field[2] = symbol;
6068 if (!symbol_contains_sep) {
6069 // We insert the space into the symbol instead of
6070 // setting pat.field[1]=space so that when
6071 // showbase is not set, the space goes away too.
6072 __curr_symbol_.insert(0, 1, space_char);
6074 return;
6075 case 2: // Space between sign and currency or value.
6076 pat.field[1] = symbol;
6077 pat.field[2] = space;
6078 if (symbol_contains_sep) {
6079 // Remove the separator from the symbol, since it
6080 // should not disappear when showbase is absent.
6081 __curr_symbol_.erase(__curr_symbol_.begin());
6083 return;
6084 default:
6085 break;
6087 break;
6088 default:
6089 break;
6091 break;
6092 case 1: // curr_symbol before value
6093 switch (sign_posn)
6095 case 0: // Parentheses surround the quantity and currency symbol.
6096 pat.field[0] = sign;
6097 pat.field[1] = symbol;
6098 pat.field[2] = none; // Any space appears in the symbol.
6099 pat.field[3] = value;
6100 switch (sep_by_space)
6102 case 0: // No space separates the currency symbol and value.
6103 // This case may have changed between C99 and C11;
6104 // assume the currency symbol matches the intention.
6105 case 2: // Space between sign and currency or value.
6106 // The "sign" is two parentheses, so no space here either.
6107 return;
6108 case 1: // Space between currency-and-sign or currency and value.
6109 if (!symbol_contains_sep) {
6110 // We insert the space into the symbol instead of
6111 // setting pat.field[2]=space so that when
6112 // showbase is not set, the space goes away too.
6113 __curr_symbol_.insert(0, 1, space_char);
6115 return;
6116 default:
6117 break;
6119 break;
6120 case 1: // The sign string precedes the quantity and currency symbol.
6121 pat.field[0] = sign;
6122 pat.field[3] = value;
6123 switch (sep_by_space)
6125 case 0: // No space separates the currency symbol and value.
6126 pat.field[1] = symbol;
6127 pat.field[2] = none;
6128 return;
6129 case 1: // Space between currency-and-sign or currency and value.
6130 pat.field[1] = symbol;
6131 pat.field[2] = none;
6132 if (!symbol_contains_sep) {
6133 // We insert the space into the symbol instead of
6134 // setting pat.field[2]=space so that when
6135 // showbase is not set, the space goes away too.
6136 __curr_symbol_.push_back(space_char);
6138 return;
6139 case 2: // Space between sign and currency or value.
6140 pat.field[1] = space;
6141 pat.field[2] = symbol;
6142 if (symbol_contains_sep) {
6143 // Remove the separator from the symbol, since it
6144 // has already appeared after the sign.
6145 __curr_symbol_.pop_back();
6147 return;
6148 default:
6149 break;
6151 break;
6152 case 2: // The sign string succeeds the quantity and currency symbol.
6153 pat.field[0] = symbol;
6154 pat.field[3] = sign;
6155 switch (sep_by_space)
6157 case 0: // No space separates the currency symbol and value.
6158 pat.field[1] = none;
6159 pat.field[2] = value;
6160 return;
6161 case 1: // Space between currency-and-sign or currency and value.
6162 pat.field[1] = none;
6163 pat.field[2] = value;
6164 if (!symbol_contains_sep) {
6165 // We insert the space into the symbol instead of
6166 // setting pat.field[1]=space so that when
6167 // showbase is not set, the space goes away too.
6168 __curr_symbol_.push_back(space_char);
6170 return;
6171 case 2: // Space between sign and currency or value.
6172 pat.field[1] = value;
6173 pat.field[2] = space;
6174 if (symbol_contains_sep) {
6175 // Remove the separator from the symbol, since it
6176 // will appear before the sign.
6177 __curr_symbol_.pop_back();
6179 return;
6180 default:
6181 break;
6183 break;
6184 case 3: // The sign string immediately precedes the currency symbol.
6185 pat.field[0] = sign;
6186 pat.field[3] = value;
6187 switch (sep_by_space)
6189 case 0: // No space separates the currency symbol and value.
6190 pat.field[1] = symbol;
6191 pat.field[2] = none;
6192 return;
6193 case 1: // Space between currency-and-sign or currency and value.
6194 pat.field[1] = symbol;
6195 pat.field[2] = none;
6196 if (!symbol_contains_sep) {
6197 // We insert the space into the symbol instead of
6198 // setting pat.field[2]=space so that when
6199 // showbase is not set, the space goes away too.
6200 __curr_symbol_.push_back(space_char);
6202 return;
6203 case 2: // Space between sign and currency or value.
6204 pat.field[1] = space;
6205 pat.field[2] = symbol;
6206 if (symbol_contains_sep) {
6207 // Remove the separator from the symbol, since it
6208 // has already appeared after the sign.
6209 __curr_symbol_.pop_back();
6211 return;
6212 default:
6213 break;
6215 break;
6216 case 4: // The sign string immediately succeeds the currency symbol.
6217 pat.field[0] = symbol;
6218 pat.field[3] = value;
6219 switch (sep_by_space)
6221 case 0: // No space separates the currency symbol and value.
6222 pat.field[1] = sign;
6223 pat.field[2] = none;
6224 return;
6225 case 1: // Space between currency-and-sign or currency and value.
6226 pat.field[1] = sign;
6227 pat.field[2] = space;
6228 if (symbol_contains_sep) {
6229 // Remove the separator from the symbol, since it
6230 // should not disappear when showbase is absent.
6231 __curr_symbol_.pop_back();
6233 return;
6234 case 2: // Space between sign and currency or value.
6235 pat.field[1] = none;
6236 pat.field[2] = sign;
6237 if (!symbol_contains_sep) {
6238 // We insert the space into the symbol instead of
6239 // setting pat.field[1]=space so that when
6240 // showbase is not set, the space goes away too.
6241 __curr_symbol_.push_back(space_char);
6243 return;
6244 default:
6245 break;
6247 break;
6248 default:
6249 break;
6251 break;
6252 default:
6253 break;
6255 pat.field[0] = symbol;
6256 pat.field[1] = sign;
6257 pat.field[2] = none;
6258 pat.field[3] = value;
6261 template<>
6262 void
6263 moneypunct_byname<char, false>::init(const char* nm)
6265 typedef moneypunct<char, false> base;
6266 __libcpp_unique_locale loc(nm);
6267 if (!loc)
6268 __throw_runtime_error("moneypunct_byname"
6269 " failed to construct for " + string(nm));
6271 lconv* lc = __libcpp_localeconv_l(loc.get());
6272 if (!checked_string_to_char_convert(__decimal_point_,
6273 lc->mon_decimal_point,
6274 loc.get()))
6275 __decimal_point_ = base::do_decimal_point();
6276 if (!checked_string_to_char_convert(__thousands_sep_,
6277 lc->mon_thousands_sep,
6278 loc.get()))
6279 __thousands_sep_ = base::do_thousands_sep();
6281 __grouping_ = lc->mon_grouping;
6282 __curr_symbol_ = lc->currency_symbol;
6283 if (lc->frac_digits != CHAR_MAX)
6284 __frac_digits_ = lc->frac_digits;
6285 else
6286 __frac_digits_ = base::do_frac_digits();
6287 if (lc->p_sign_posn == 0)
6288 __positive_sign_ = "()";
6289 else
6290 __positive_sign_ = lc->positive_sign;
6291 if (lc->n_sign_posn == 0)
6292 __negative_sign_ = "()";
6293 else
6294 __negative_sign_ = lc->negative_sign;
6295 // Assume the positive and negative formats will want spaces in
6296 // the same places in curr_symbol since there's no way to
6297 // represent anything else.
6298 string_type __dummy_curr_symbol = __curr_symbol_;
6299 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6300 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6301 __init_pat(__neg_format_, __curr_symbol_, false,
6302 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6305 template<>
6306 void
6307 moneypunct_byname<char, true>::init(const char* nm)
6309 typedef moneypunct<char, true> base;
6310 __libcpp_unique_locale loc(nm);
6311 if (!loc)
6312 __throw_runtime_error("moneypunct_byname"
6313 " failed to construct for " + string(nm));
6315 lconv* lc = __libcpp_localeconv_l(loc.get());
6316 if (!checked_string_to_char_convert(__decimal_point_,
6317 lc->mon_decimal_point,
6318 loc.get()))
6319 __decimal_point_ = base::do_decimal_point();
6320 if (!checked_string_to_char_convert(__thousands_sep_,
6321 lc->mon_thousands_sep,
6322 loc.get()))
6323 __thousands_sep_ = base::do_thousands_sep();
6324 __grouping_ = lc->mon_grouping;
6325 __curr_symbol_ = lc->int_curr_symbol;
6326 if (lc->int_frac_digits != CHAR_MAX)
6327 __frac_digits_ = lc->int_frac_digits;
6328 else
6329 __frac_digits_ = base::do_frac_digits();
6330 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6331 if (lc->p_sign_posn == 0)
6332 #else // _LIBCPP_MSVCRT
6333 if (lc->int_p_sign_posn == 0)
6334 #endif // !_LIBCPP_MSVCRT
6335 __positive_sign_ = "()";
6336 else
6337 __positive_sign_ = lc->positive_sign;
6338 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6339 if(lc->n_sign_posn == 0)
6340 #else // _LIBCPP_MSVCRT
6341 if (lc->int_n_sign_posn == 0)
6342 #endif // !_LIBCPP_MSVCRT
6343 __negative_sign_ = "()";
6344 else
6345 __negative_sign_ = lc->negative_sign;
6346 // Assume the positive and negative formats will want spaces in
6347 // the same places in curr_symbol since there's no way to
6348 // represent anything else.
6349 string_type __dummy_curr_symbol = __curr_symbol_;
6350 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6351 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6352 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6353 __init_pat(__neg_format_, __curr_symbol_, true,
6354 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6355 #else // _LIBCPP_MSVCRT
6356 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6357 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6358 lc->int_p_sign_posn, ' ');
6359 __init_pat(__neg_format_, __curr_symbol_, true,
6360 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6361 lc->int_n_sign_posn, ' ');
6362 #endif // !_LIBCPP_MSVCRT
6365 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6366 template<>
6367 void
6368 moneypunct_byname<wchar_t, false>::init(const char* nm)
6370 typedef moneypunct<wchar_t, false> base;
6371 __libcpp_unique_locale loc(nm);
6372 if (!loc)
6373 __throw_runtime_error("moneypunct_byname"
6374 " failed to construct for " + string(nm));
6375 lconv* lc = __libcpp_localeconv_l(loc.get());
6376 if (!checked_string_to_wchar_convert(__decimal_point_,
6377 lc->mon_decimal_point,
6378 loc.get()))
6379 __decimal_point_ = base::do_decimal_point();
6380 if (!checked_string_to_wchar_convert(__thousands_sep_,
6381 lc->mon_thousands_sep,
6382 loc.get()))
6383 __thousands_sep_ = base::do_thousands_sep();
6384 __grouping_ = lc->mon_grouping;
6385 wchar_t wbuf[100];
6386 mbstate_t mb = {0};
6387 const char* bb = lc->currency_symbol;
6388 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6389 if (j == size_t(-1))
6390 __throw_runtime_error("locale not supported");
6391 wchar_t* wbe = wbuf + j;
6392 __curr_symbol_.assign(wbuf, wbe);
6393 if (lc->frac_digits != CHAR_MAX)
6394 __frac_digits_ = lc->frac_digits;
6395 else
6396 __frac_digits_ = base::do_frac_digits();
6397 if (lc->p_sign_posn == 0)
6398 __positive_sign_ = L"()";
6399 else
6401 mb = mbstate_t();
6402 bb = lc->positive_sign;
6403 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6404 if (j == size_t(-1))
6405 __throw_runtime_error("locale not supported");
6406 wbe = wbuf + j;
6407 __positive_sign_.assign(wbuf, wbe);
6409 if (lc->n_sign_posn == 0)
6410 __negative_sign_ = L"()";
6411 else
6413 mb = mbstate_t();
6414 bb = lc->negative_sign;
6415 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6416 if (j == size_t(-1))
6417 __throw_runtime_error("locale not supported");
6418 wbe = wbuf + j;
6419 __negative_sign_.assign(wbuf, wbe);
6421 // Assume the positive and negative formats will want spaces in
6422 // the same places in curr_symbol since there's no way to
6423 // represent anything else.
6424 string_type __dummy_curr_symbol = __curr_symbol_;
6425 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6426 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6427 __init_pat(__neg_format_, __curr_symbol_, false,
6428 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6431 template<>
6432 void
6433 moneypunct_byname<wchar_t, true>::init(const char* nm)
6435 typedef moneypunct<wchar_t, true> base;
6436 __libcpp_unique_locale loc(nm);
6437 if (!loc)
6438 __throw_runtime_error("moneypunct_byname"
6439 " failed to construct for " + string(nm));
6441 lconv* lc = __libcpp_localeconv_l(loc.get());
6442 if (!checked_string_to_wchar_convert(__decimal_point_,
6443 lc->mon_decimal_point,
6444 loc.get()))
6445 __decimal_point_ = base::do_decimal_point();
6446 if (!checked_string_to_wchar_convert(__thousands_sep_,
6447 lc->mon_thousands_sep,
6448 loc.get()))
6449 __thousands_sep_ = base::do_thousands_sep();
6450 __grouping_ = lc->mon_grouping;
6451 wchar_t wbuf[100];
6452 mbstate_t mb = {0};
6453 const char* bb = lc->int_curr_symbol;
6454 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6455 if (j == size_t(-1))
6456 __throw_runtime_error("locale not supported");
6457 wchar_t* wbe = wbuf + j;
6458 __curr_symbol_.assign(wbuf, wbe);
6459 if (lc->int_frac_digits != CHAR_MAX)
6460 __frac_digits_ = lc->int_frac_digits;
6461 else
6462 __frac_digits_ = base::do_frac_digits();
6463 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6464 if (lc->p_sign_posn == 0)
6465 #else // _LIBCPP_MSVCRT
6466 if (lc->int_p_sign_posn == 0)
6467 #endif // !_LIBCPP_MSVCRT
6468 __positive_sign_ = L"()";
6469 else
6471 mb = mbstate_t();
6472 bb = lc->positive_sign;
6473 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6474 if (j == size_t(-1))
6475 __throw_runtime_error("locale not supported");
6476 wbe = wbuf + j;
6477 __positive_sign_.assign(wbuf, wbe);
6479 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6480 if (lc->n_sign_posn == 0)
6481 #else // _LIBCPP_MSVCRT
6482 if (lc->int_n_sign_posn == 0)
6483 #endif // !_LIBCPP_MSVCRT
6484 __negative_sign_ = L"()";
6485 else
6487 mb = mbstate_t();
6488 bb = lc->negative_sign;
6489 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6490 if (j == size_t(-1))
6491 __throw_runtime_error("locale not supported");
6492 wbe = wbuf + j;
6493 __negative_sign_.assign(wbuf, wbe);
6495 // Assume the positive and negative formats will want spaces in
6496 // the same places in curr_symbol since there's no way to
6497 // represent anything else.
6498 string_type __dummy_curr_symbol = __curr_symbol_;
6499 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6500 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6501 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6502 __init_pat(__neg_format_, __curr_symbol_, true,
6503 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6504 #else // _LIBCPP_MSVCRT
6505 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6506 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6507 lc->int_p_sign_posn, L' ');
6508 __init_pat(__neg_format_, __curr_symbol_, true,
6509 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6510 lc->int_n_sign_posn, L' ');
6511 #endif // !_LIBCPP_MSVCRT
6513 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6515 void __do_nothing(void*) {}
6517 void __throw_runtime_error(const char* msg)
6519 #ifndef _LIBCPP_NO_EXCEPTIONS
6520 throw runtime_error(msg);
6521 #else
6522 (void)msg;
6523 _VSTD::abort();
6524 #endif
6527 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6528 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
6530 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6531 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
6533 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6534 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
6536 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6537 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
6539 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6540 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
6542 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6543 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
6545 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6546 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
6548 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6549 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
6551 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6552 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
6554 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6555 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6556 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
6557 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
6559 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6560 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6561 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
6562 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
6564 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6565 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
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_put<char>;
6571 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<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 messages<char>;
6577 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
6579 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6580 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
6582 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6583 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
6584 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6585 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6586 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6587 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
6588 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
6589 #endif
6591 _LIBCPP_END_NAMESPACE_STD
6593 _LIBCPP_POP_MACROS