xref: /freebsd/contrib/llvm-project/libcxx/src/locale.cpp (revision 4d3fc8b0570b29fb0d6ee9525f104d52176ff0d4)
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 //===----------------------------------------------------------------------===//
8 
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
14 
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>
27 
28 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
29 #   include <cwctype>
30 #endif
31 
32 #if defined(_AIX)
33 #   include <sys/localedef.h> // for __lc_ctype_ptr
34 #endif
35 
36 #if defined(_LIBCPP_MSVCRT)
37 #   define _CTYPE_DISABLE_MACROS
38 #endif
39 
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
45 
46 #include "include/atomic_support.h"
47 #include "include/sso_allocator.h"
48 
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")
52 
53 _LIBCPP_PUSH_MACROS
54 #include <__undef_macros>
55 
56 _LIBCPP_BEGIN_NAMESPACE_STD
57 
58 struct __libcpp_unique_locale {
59   __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
60 
61   ~__libcpp_unique_locale() {
62     if (__loc_)
63       freelocale(__loc_);
64   }
65 
66   explicit operator bool() const { return __loc_; }
67 
68   locale_t& get() { return __loc_; }
69 
70   locale_t __loc_;
71 private:
72   __libcpp_unique_locale(__libcpp_unique_locale const&);
73   __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
74 };
75 
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;
83 }
84 #endif // __cloc_defined
85 
86 namespace {
87 
88 struct release
89 {
90     void operator()(locale::facet* p) {p->__release_shared();}
91 };
92 
93 template <class T, class ...Args>
94 T& make(Args ...args)
95 {
96     static typename aligned_storage<sizeof(T)>::type buf;
97     auto *obj = ::new (&buf) T(args...);
98     return *obj;
99 }
100 
101 template <typename T, size_t N>
102 inline
103 _LIBCPP_CONSTEXPR
104 size_t
105 countof(const T (&)[N])
106 {
107     return N;
108 }
109 
110 template <typename T>
111 inline
112 _LIBCPP_CONSTEXPR
113 size_t
114 countof(const T * const begin, const T * const end)
115 {
116     return static_cast<size_t>(end - begin);
117 }
118 
119 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
120 {
121 #ifndef _LIBCPP_NO_EXCEPTIONS
122     throw runtime_error(msg);
123 #else
124     (void)msg;
125     _VSTD::abort();
126 #endif
127 }
128 
129 }
130 
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;
139 
140 class _LIBCPP_HIDDEN locale::__imp
141     : public facet
142 {
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();
161 
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;
166 
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);
173 };
174 
175 locale::__imp::__imp(size_t refs)
176     : facet(refs),
177       facets_(N),
178       name_("C")
179 {
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
239 }
240 
241 locale::__imp::__imp(const string& name, size_t refs)
242     : facet(refs),
243       facets_(N),
244       name_(name)
245 {
246 #ifndef _LIBCPP_NO_EXCEPTIONS
247     try
248     {
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
297     }
298     catch (...)
299     {
300         for (unsigned i = 0; i < facets_.size(); ++i)
301             if (facets_[i])
302                 facets_[i]->__release_shared();
303         throw;
304     }
305 #endif // _LIBCPP_NO_EXCEPTIONS
306 }
307 
308 locale::__imp::__imp(const __imp& other)
309     : facets_(max<size_t>(N, other.facets_.size())),
310       name_(other.name_)
311 {
312     facets_ = other.facets_;
313     for (unsigned i = 0; i < facets_.size(); ++i)
314         if (facets_[i])
315             facets_[i]->__add_shared();
316 }
317 
318 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
319     : facets_(N),
320       name_("*")
321 {
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
327     try
328     {
329 #endif // _LIBCPP_NO_EXCEPTIONS
330         if (c & locale::collate)
331         {
332             install(new collate_byname<char>(name));
333 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
334             install(new collate_byname<wchar_t>(name));
335 #endif
336         }
337         if (c & locale::ctype)
338         {
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
355         }
356         if (c & locale::monetary)
357         {
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
364         }
365         if (c & locale::numeric)
366         {
367             install(new numpunct_byname<char>(name));
368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
369             install(new numpunct_byname<wchar_t>(name));
370 #endif
371         }
372         if (c & locale::time)
373         {
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
382         }
383         if (c & locale::messages)
384         {
385             install(new messages_byname<char>(name));
386 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
387             install(new messages_byname<wchar_t>(name));
388 #endif
389         }
390 #ifndef _LIBCPP_NO_EXCEPTIONS
391     }
392     catch (...)
393     {
394         for (unsigned i = 0; i < facets_.size(); ++i)
395             if (facets_[i])
396                 facets_[i]->__release_shared();
397         throw;
398     }
399 #endif // _LIBCPP_NO_EXCEPTIONS
400 }
401 
402 template<class F>
403 inline
404 void
405 locale::__imp::install_from(const locale::__imp& one)
406 {
407     long id = F::id.__get();
408     install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
409 }
410 
411 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
412     : facets_(N),
413       name_("*")
414 {
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
420     try
421     {
422 #endif // _LIBCPP_NO_EXCEPTIONS
423         if (c & locale::collate)
424         {
425             install_from<_VSTD::collate<char> >(one);
426 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
427             install_from<_VSTD::collate<wchar_t> >(one);
428 #endif
429         }
430         if (c & locale::ctype)
431         {
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
448         }
449         if (c & locale::monetary)
450         {
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
465         }
466         if (c & locale::numeric)
467         {
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
480         }
481         if (c & locale::time)
482         {
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
491         }
492         if (c & locale::messages)
493         {
494             install_from<_VSTD::messages<char> >(one);
495 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
496             install_from<_VSTD::messages<wchar_t> >(one);
497 #endif
498         }
499 #ifndef _LIBCPP_NO_EXCEPTIONS
500     }
501     catch (...)
502     {
503         for (unsigned i = 0; i < facets_.size(); ++i)
504             if (facets_[i])
505                 facets_[i]->__release_shared();
506         throw;
507     }
508 #endif // _LIBCPP_NO_EXCEPTIONS
509 }
510 
511 locale::__imp::__imp(const __imp& other, facet* f, long id)
512     : facets_(max<size_t>(N, other.facets_.size()+1)),
513       name_("*")
514 {
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);
522 }
523 
524 locale::__imp::~__imp()
525 {
526     for (unsigned i = 0; i < facets_.size(); ++i)
527         if (facets_[i])
528             facets_[i]->__release_shared();
529 }
530 
531 void
532 locale::__imp::install(facet* f, long id)
533 {
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();
541 }
542 
543 const locale::facet*
544 locale::__imp::use_facet(long id) const
545 {
546     if (!has_facet(id))
547         __throw_bad_cast();
548     return facets_[static_cast<size_t>(id)];
549 }
550 
551 // locale
552 
553 const locale&
554 locale::__imp::make_classic()
555 {
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;
561 }
562 
563 const locale&
564 locale::classic()
565 {
566     static const locale& c = __imp::make_classic();
567     return c;
568 }
569 
570 locale&
571 locale::__imp::make_global()
572 {
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;
577 }
578 
579 locale&
580 locale::__global()
581 {
582     static locale& g = __imp::make_global();
583     return g;
584 }
585 
586 locale::locale() noexcept
587     : __locale_(__global().__locale_)
588 {
589     __locale_->__add_shared();
590 }
591 
592 locale::locale(const locale& l) noexcept
593     : __locale_(l.__locale_)
594 {
595     __locale_->__add_shared();
596 }
597 
598 locale::~locale()
599 {
600     __locale_->__release_shared();
601 }
602 
603 const locale&
604 locale::operator=(const locale& other) noexcept
605 {
606     other.__locale_->__add_shared();
607     __locale_->__release_shared();
608     __locale_ = other.__locale_;
609     return *this;
610 }
611 
612 locale::locale(const char* name)
613     : __locale_(name ? new __imp(name)
614                      : (__throw_runtime_error("locale constructed with null"), nullptr))
615 {
616     __locale_->__add_shared();
617 }
618 
619 locale::locale(const string& name)
620     : __locale_(new __imp(name))
621 {
622     __locale_->__add_shared();
623 }
624 
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))
628 {
629     __locale_->__add_shared();
630 }
631 
632 locale::locale(const locale& other, const string& name, category c)
633     : __locale_(new __imp(*other.__locale_, name, c))
634 {
635     __locale_->__add_shared();
636 }
637 
638 locale::locale(const locale& other, const locale& one, category c)
639     : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
640 {
641     __locale_->__add_shared();
642 }
643 
644 string
645 locale::name() const
646 {
647     return __locale_->name();
648 }
649 
650 void
651 locale::__install_ctor(const locale& other, facet* f, long id)
652 {
653     if (f)
654         __locale_ = new __imp(*other.__locale_, f, id);
655     else
656         __locale_ = other.__locale_;
657     __locale_->__add_shared();
658 }
659 
660 locale
661 locale::global(const locale& loc)
662 {
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;
669 }
670 
671 bool
672 locale::has_facet(id& x) const
673 {
674     return __locale_->has_facet(x.__get());
675 }
676 
677 const locale::facet*
678 locale::use_facet(id& x) const
679 {
680     return __locale_->use_facet(x.__get());
681 }
682 
683 bool
684 locale::operator==(const locale& y) const
685 {
686     return (__locale_ == y.__locale_)
687         || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
688 }
689 
690 // locale::facet
691 
692 locale::facet::~facet()
693 {
694 }
695 
696 void
697 locale::facet::__on_zero_shared() noexcept
698 {
699     delete this;
700 }
701 
702 // locale::id
703 
704 int32_t locale::id::__next_id = 0;
705 
706 namespace
707 {
708 
709 class __fake_bind
710 {
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) {}
716 
717     void operator()() const
718     {
719         (id_->*pmf_)();
720     }
721 };
722 
723 }
724 
725 long
726 locale::id::__get()
727 {
728     call_once(__flag_, __fake_bind(&locale::id::__init, this));
729     return __id_ - 1;
730 }
731 
732 void
733 locale::id::__init()
734 {
735     __id_ = __libcpp_atomic_add(&__next_id, 1);
736 }
737 
738 // template <> class collate_byname<char>
739 
740 collate_byname<char>::collate_byname(const char* n, size_t refs)
741     : collate<char>(refs),
742       __l(newlocale(LC_ALL_MASK, n, 0))
743 {
744     if (__l == 0)
745         __throw_runtime_error("collate_byname<char>::collate_byname"
746                             " failed to construct for " + string(n));
747 }
748 
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))
752 {
753     if (__l == 0)
754         __throw_runtime_error("collate_byname<char>::collate_byname"
755                             " failed to construct for " + name);
756 }
757 
758 collate_byname<char>::~collate_byname()
759 {
760     freelocale(__l);
761 }
762 
763 int
764 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
765                                  const char_type* __lo2, const char_type* __hi2) const
766 {
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;
775 }
776 
777 collate_byname<char>::string_type
778 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
779 {
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;
784 }
785 
786 // template <> class collate_byname<wchar_t>
787 
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))
792 {
793     if (__l == 0)
794         __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
795                             " failed to construct for " + string(n));
796 }
797 
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))
801 {
802     if (__l == 0)
803         __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
804                             " failed to construct for " + name);
805 }
806 
807 collate_byname<wchar_t>::~collate_byname()
808 {
809     freelocale(__l);
810 }
811 
812 int
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
815 {
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;
824 }
825 
826 collate_byname<wchar_t>::string_type
827 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
828 {
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;
833 }
834 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
835 
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;
848 
849 // template <> class ctype<wchar_t>;
850 
851 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
852 locale::id ctype<wchar_t>::id;
853 
854 ctype<wchar_t>::~ctype()
855 {
856 }
857 
858 bool
859 ctype<wchar_t>::do_is(mask m, char_type c) const
860 {
861     return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
862 }
863 
864 const wchar_t*
865 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
866 {
867     for (; low != high; ++low, ++vec)
868         *vec = static_cast<mask>(isascii(*low) ?
869                                    ctype<char>::classic_table()[*low] : 0);
870     return low;
871 }
872 
873 const wchar_t*
874 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
875 {
876     for (; low != high; ++low)
877         if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
878             break;
879     return low;
880 }
881 
882 const wchar_t*
883 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
884 {
885     for (; low != high; ++low)
886         if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
887             break;
888     return low;
889 }
890 
891 wchar_t
892 ctype<wchar_t>::do_toupper(char_type c) const
893 {
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
902 }
903 
904 const wchar_t*
905 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
906 {
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;
918 }
919 
920 wchar_t
921 ctype<wchar_t>::do_tolower(char_type c) const
922 {
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
931 }
932 
933 const wchar_t*
934 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
935 {
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;
947 }
948 
949 wchar_t
950 ctype<wchar_t>::do_widen(char c) const
951 {
952     return c;
953 }
954 
955 const char*
956 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
957 {
958     for (; low != high; ++low, ++dest)
959         *dest = *low;
960     return low;
961 }
962 
963 char
964 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
965 {
966     if (isascii(c))
967         return static_cast<char>(c);
968     return dfault;
969 }
970 
971 const wchar_t*
972 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
973 {
974     for (; low != high; ++low, ++dest)
975         if (isascii(*low))
976             *dest = static_cast<char>(*low);
977         else
978             *dest = dfault;
979     return low;
980 }
981 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
982 
983 // template <> class ctype<char>;
984 
985 locale::id ctype<char>::id;
986 
987 const size_t ctype<char>::table_size;
988 
989 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
990     : locale::facet(refs),
991       __tab_(tab),
992       __del_(del)
993 {
994   if (__tab_ == 0)
995       __tab_ = classic_table();
996 }
997 
998 ctype<char>::~ctype()
999 {
1000     if (__tab_ && __del_)
1001         delete [] __tab_;
1002 }
1003 
1004 char
1005 ctype<char>::do_toupper(char_type c) const
1006 {
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
1018 }
1019 
1020 const char*
1021 ctype<char>::do_toupper(char_type* low, const char_type* high) const
1022 {
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;
1036 }
1037 
1038 char
1039 ctype<char>::do_tolower(char_type c) const
1040 {
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
1052 }
1053 
1054 const char*
1055 ctype<char>::do_tolower(char_type* low, const char_type* high) const
1056 {
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;
1068 }
1069 
1070 char
1071 ctype<char>::do_widen(char c) const
1072 {
1073     return c;
1074 }
1075 
1076 const char*
1077 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1078 {
1079     for (; low != high; ++low, ++dest)
1080         *dest = *low;
1081     return low;
1082 }
1083 
1084 char
1085 ctype<char>::do_narrow(char_type c, char dfault) const
1086 {
1087     if (isascii(c))
1088         return static_cast<char>(c);
1089     return dfault;
1090 }
1091 
1092 const char*
1093 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1094 {
1095     for (; low != high; ++low, ++dest)
1096         if (isascii(*low))
1097             *dest = *low;
1098         else
1099             *dest = dfault;
1100     return low;
1101 }
1102 
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
1108 
1109 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1110 const ctype<char>::mask*
1111 ctype<char>::classic_table() noexcept
1112 {
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
1186     };
1187     return builtin_table;
1188 }
1189 #else
1190 const ctype<char>::mask*
1191 ctype<char>::classic_table() noexcept
1192 {
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
1224 }
1225 #endif
1226 
1227 #if defined(__GLIBC__)
1228 const int*
1229 ctype<char>::__classic_lower_table() noexcept
1230 {
1231     return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1232 }
1233 
1234 const int*
1235 ctype<char>::__classic_upper_table() noexcept
1236 {
1237     return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1238 }
1239 #elif defined(__NetBSD__)
1240 const short*
1241 ctype<char>::__classic_lower_table() noexcept
1242 {
1243     return _C_tolower_tab_ + 1;
1244 }
1245 
1246 const short*
1247 ctype<char>::__classic_upper_table() noexcept
1248 {
1249     return _C_toupper_tab_ + 1;
1250 }
1251 
1252 #elif defined(__EMSCRIPTEN__)
1253 const int*
1254 ctype<char>::__classic_lower_table() noexcept
1255 {
1256     return *__ctype_tolower_loc();
1257 }
1258 
1259 const int*
1260 ctype<char>::__classic_upper_table() noexcept
1261 {
1262     return *__ctype_toupper_loc();
1263 }
1264 #elif defined(__MVS__)
1265 const unsigned short*
1266 ctype<char>::__classic_lower_table() _NOEXCEPT
1267 {
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
1273 }
1274 const unsigned short *
1275 ctype<char>::__classic_upper_table() _NOEXCEPT
1276 {
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
1282 }
1283 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1284 
1285 // template <> class ctype_byname<char>
1286 
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))
1290 {
1291     if (__l == 0)
1292         __throw_runtime_error("ctype_byname<char>::ctype_byname"
1293                             " failed to construct for " + string(name));
1294 }
1295 
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))
1299 {
1300     if (__l == 0)
1301         __throw_runtime_error("ctype_byname<char>::ctype_byname"
1302                             " failed to construct for " + name);
1303 }
1304 
1305 ctype_byname<char>::~ctype_byname()
1306 {
1307     freelocale(__l);
1308 }
1309 
1310 char
1311 ctype_byname<char>::do_toupper(char_type c) const
1312 {
1313     return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1314 }
1315 
1316 const char*
1317 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1318 {
1319     for (; low != high; ++low)
1320         *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1321     return low;
1322 }
1323 
1324 char
1325 ctype_byname<char>::do_tolower(char_type c) const
1326 {
1327     return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1328 }
1329 
1330 const char*
1331 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1332 {
1333     for (; low != high; ++low)
1334         *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1335     return low;
1336 }
1337 
1338 // template <> class ctype_byname<wchar_t>
1339 
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))
1344 {
1345     if (__l == 0)
1346         __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1347                             " failed to construct for " + string(name));
1348 }
1349 
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))
1353 {
1354     if (__l == 0)
1355         __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1356                             " failed to construct for " + name);
1357 }
1358 
1359 ctype_byname<wchar_t>::~ctype_byname()
1360 {
1361     freelocale(__l);
1362 }
1363 
1364 bool
1365 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1366 {
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
1384 }
1385 
1386 const wchar_t*
1387 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1388 {
1389     for (; low != high; ++low, ++vec)
1390     {
1391         if (isascii(*low))
1392             *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1393         else
1394         {
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
1425         }
1426     }
1427     return low;
1428 }
1429 
1430 const wchar_t*
1431 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1432 {
1433     for (; low != high; ++low)
1434     {
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
1451     }
1452     return low;
1453 }
1454 
1455 const wchar_t*
1456 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1457 {
1458     for (; low != high; ++low)
1459     {
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
1477     }
1478     return low;
1479 }
1480 
1481 wchar_t
1482 ctype_byname<wchar_t>::do_toupper(char_type c) const
1483 {
1484     return towupper_l(c, __l);
1485 }
1486 
1487 const wchar_t*
1488 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1489 {
1490     for (; low != high; ++low)
1491         *low = towupper_l(*low, __l);
1492     return low;
1493 }
1494 
1495 wchar_t
1496 ctype_byname<wchar_t>::do_tolower(char_type c) const
1497 {
1498     return towlower_l(c, __l);
1499 }
1500 
1501 const wchar_t*
1502 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1503 {
1504     for (; low != high; ++low)
1505         *low = towlower_l(*low, __l);
1506     return low;
1507 }
1508 
1509 wchar_t
1510 ctype_byname<wchar_t>::do_widen(char c) const
1511 {
1512     return __libcpp_btowc_l(c, __l);
1513 }
1514 
1515 const char*
1516 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1517 {
1518     for (; low != high; ++low, ++dest)
1519         *dest = __libcpp_btowc_l(*low, __l);
1520     return low;
1521 }
1522 
1523 char
1524 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1525 {
1526     int r = __libcpp_wctob_l(c, __l);
1527     return (r != EOF) ? static_cast<char>(r) : dfault;
1528 }
1529 
1530 const wchar_t*
1531 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1532 {
1533     for (; low != high; ++low, ++dest)
1534     {
1535         int r = __libcpp_wctob_l(*low, __l);
1536         *dest = (r != EOF) ? static_cast<char>(r) : dfault;
1537     }
1538     return low;
1539 }
1540 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1541 
1542 // template <> class codecvt<char, char, mbstate_t>
1543 
1544 locale::id codecvt<char, char, mbstate_t>::id;
1545 
1546 codecvt<char, char, mbstate_t>::~codecvt()
1547 {
1548 }
1549 
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
1554 {
1555     frm_nxt = frm;
1556     to_nxt = to;
1557     return noconv;
1558 }
1559 
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
1564 {
1565     frm_nxt = frm;
1566     to_nxt = to;
1567     return noconv;
1568 }
1569 
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
1573 {
1574     to_nxt = to;
1575     return noconv;
1576 }
1577 
1578 int
1579 codecvt<char, char, mbstate_t>::do_encoding() const noexcept
1580 {
1581     return 1;
1582 }
1583 
1584 bool
1585 codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
1586 {
1587     return true;
1588 }
1589 
1590 int
1591 codecvt<char, char, mbstate_t>::do_length(state_type&,
1592     const extern_type* frm, const extern_type* end, size_t mx) const
1593 {
1594     return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1595 }
1596 
1597 int
1598 codecvt<char, char, mbstate_t>::do_max_length() const noexcept
1599 {
1600     return 1;
1601 }
1602 
1603 // template <> class codecvt<wchar_t, char, mbstate_t>
1604 
1605 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1606 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1607 
1608 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1609     : locale::facet(refs),
1610       __l(_LIBCPP_GET_C_LOCALE)
1611 {
1612 }
1613 
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))
1617 {
1618     if (__l == 0)
1619         __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1620                             " failed to construct for " + string(nm));
1621 }
1622 
1623 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1624 {
1625     if (__l != _LIBCPP_GET_C_LOCALE)
1626         freelocale(__l);
1627 }
1628 
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
1633 {
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)
1642     {
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))
1648         {
1649             // need to recover to_nxt
1650             for (to_nxt = to; frm != frm_nxt; ++frm)
1651             {
1652                 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1653                 if (n == size_t(-1))
1654                     break;
1655                 to_nxt += n;
1656             }
1657             frm_nxt = frm;
1658             return error;
1659         }
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
1666         {
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;
1681         }
1682     }
1683     return frm_nxt == frm_end ? ok : partial;
1684 }
1685 
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
1690 {
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)
1699     {
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))
1705         {
1706             // need to recover to_nxt
1707             for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1708             {
1709                 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1710                                    &save_state, __l);
1711                 switch (n)
1712                 {
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;
1725                 }
1726             }
1727             frm_nxt = frm;
1728             return frm_nxt == frm_end ? ok : partial;
1729         }
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
1736         {
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;
1747         }
1748     }
1749     return frm_nxt == frm_end ? ok : partial;
1750 }
1751 
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
1755 {
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;
1767 }
1768 
1769 int
1770 codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1771 {
1772     if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1773         return -1;
1774 
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;
1779 }
1780 
1781 bool
1782 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1783 {
1784     return false;
1785 }
1786 
1787 int
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
1790 {
1791     int nbytes = 0;
1792     for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1793     {
1794         size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1795         switch (n)
1796         {
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;
1808         }
1809     }
1810     return nbytes;
1811 }
1812 
1813 int
1814 codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1815 {
1816     return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1817 }
1818 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1819 
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
1833 
1834 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1835 static
1836 codecvt_base::result
1837 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1838               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1839               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1840 {
1841     frm_nxt = frm;
1842     to_nxt = to;
1843     if (mode & generate_header)
1844     {
1845         if (to_end-to_nxt < 3)
1846             return codecvt_base::partial;
1847         *to_nxt++ = static_cast<uint8_t>(0xEF);
1848         *to_nxt++ = static_cast<uint8_t>(0xBB);
1849         *to_nxt++ = static_cast<uint8_t>(0xBF);
1850     }
1851     for (; frm_nxt < frm_end; ++frm_nxt)
1852     {
1853         uint16_t wc1 = *frm_nxt;
1854         if (wc1 > Maxcode)
1855             return codecvt_base::error;
1856         if (wc1 < 0x0080)
1857         {
1858             if (to_end-to_nxt < 1)
1859                 return codecvt_base::partial;
1860             *to_nxt++ = static_cast<uint8_t>(wc1);
1861         }
1862         else if (wc1 < 0x0800)
1863         {
1864             if (to_end-to_nxt < 2)
1865                 return codecvt_base::partial;
1866             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1867             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1868         }
1869         else if (wc1 < 0xD800)
1870         {
1871             if (to_end-to_nxt < 3)
1872                 return codecvt_base::partial;
1873             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1874             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1875             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1876         }
1877         else if (wc1 < 0xDC00)
1878         {
1879             if (frm_end-frm_nxt < 2)
1880                 return codecvt_base::partial;
1881             uint16_t wc2 = frm_nxt[1];
1882             if ((wc2 & 0xFC00) != 0xDC00)
1883                 return codecvt_base::error;
1884             if (to_end-to_nxt < 4)
1885                 return codecvt_base::partial;
1886             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1887                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1888                 return codecvt_base::error;
1889             ++frm_nxt;
1890             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1891             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1892             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1893             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1894             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1895         }
1896         else if (wc1 < 0xE000)
1897         {
1898             return codecvt_base::error;
1899         }
1900         else
1901         {
1902             if (to_end-to_nxt < 3)
1903                 return codecvt_base::partial;
1904             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1905             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1906             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1907         }
1908     }
1909     return codecvt_base::ok;
1910 }
1911 
1912 static
1913 codecvt_base::result
1914 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1915               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1916               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1917 {
1918     frm_nxt = frm;
1919     to_nxt = to;
1920     if (mode & generate_header)
1921     {
1922         if (to_end-to_nxt < 3)
1923             return codecvt_base::partial;
1924         *to_nxt++ = static_cast<uint8_t>(0xEF);
1925         *to_nxt++ = static_cast<uint8_t>(0xBB);
1926         *to_nxt++ = static_cast<uint8_t>(0xBF);
1927     }
1928     for (; frm_nxt < frm_end; ++frm_nxt)
1929     {
1930         uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1931         if (wc1 > Maxcode)
1932             return codecvt_base::error;
1933         if (wc1 < 0x0080)
1934         {
1935             if (to_end-to_nxt < 1)
1936                 return codecvt_base::partial;
1937             *to_nxt++ = static_cast<uint8_t>(wc1);
1938         }
1939         else if (wc1 < 0x0800)
1940         {
1941             if (to_end-to_nxt < 2)
1942                 return codecvt_base::partial;
1943             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1944             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1945         }
1946         else if (wc1 < 0xD800)
1947         {
1948             if (to_end-to_nxt < 3)
1949                 return codecvt_base::partial;
1950             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1951             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1952             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1953         }
1954         else if (wc1 < 0xDC00)
1955         {
1956             if (frm_end-frm_nxt < 2)
1957                 return codecvt_base::partial;
1958             uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1959             if ((wc2 & 0xFC00) != 0xDC00)
1960                 return codecvt_base::error;
1961             if (to_end-to_nxt < 4)
1962                 return codecvt_base::partial;
1963             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1964                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1965                 return codecvt_base::error;
1966             ++frm_nxt;
1967             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1968             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1969             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1970             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1971             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1972         }
1973         else if (wc1 < 0xE000)
1974         {
1975             return codecvt_base::error;
1976         }
1977         else
1978         {
1979             if (to_end-to_nxt < 3)
1980                 return codecvt_base::partial;
1981             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1982             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1983             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1984         }
1985     }
1986     return codecvt_base::ok;
1987 }
1988 
1989 static
1990 codecvt_base::result
1991 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1992               uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1993               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1994 {
1995     frm_nxt = frm;
1996     to_nxt = to;
1997     if (mode & consume_header)
1998     {
1999         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2000                                                           frm_nxt[2] == 0xBF)
2001             frm_nxt += 3;
2002     }
2003     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2004     {
2005         uint8_t c1 = *frm_nxt;
2006         if (c1 > Maxcode)
2007             return codecvt_base::error;
2008         if (c1 < 0x80)
2009         {
2010             *to_nxt = static_cast<uint16_t>(c1);
2011             ++frm_nxt;
2012         }
2013         else if (c1 < 0xC2)
2014         {
2015             return codecvt_base::error;
2016         }
2017         else if (c1 < 0xE0)
2018         {
2019             if (frm_end-frm_nxt < 2)
2020                 return codecvt_base::partial;
2021             uint8_t c2 = frm_nxt[1];
2022             if ((c2 & 0xC0) != 0x80)
2023                 return codecvt_base::error;
2024             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2025             if (t > Maxcode)
2026                 return codecvt_base::error;
2027             *to_nxt = t;
2028             frm_nxt += 2;
2029         }
2030         else if (c1 < 0xF0)
2031         {
2032             if (frm_end-frm_nxt < 3)
2033                 return codecvt_base::partial;
2034             uint8_t c2 = frm_nxt[1];
2035             uint8_t c3 = frm_nxt[2];
2036             switch (c1)
2037             {
2038             case 0xE0:
2039                 if ((c2 & 0xE0) != 0xA0)
2040                     return codecvt_base::error;
2041                  break;
2042             case 0xED:
2043                 if ((c2 & 0xE0) != 0x80)
2044                     return codecvt_base::error;
2045                  break;
2046             default:
2047                 if ((c2 & 0xC0) != 0x80)
2048                     return codecvt_base::error;
2049                  break;
2050             }
2051             if ((c3 & 0xC0) != 0x80)
2052                 return codecvt_base::error;
2053             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2054                                              | ((c2 & 0x3F) << 6)
2055                                              |  (c3 & 0x3F));
2056             if (t > Maxcode)
2057                 return codecvt_base::error;
2058             *to_nxt = t;
2059             frm_nxt += 3;
2060         }
2061         else if (c1 < 0xF5)
2062         {
2063             if (frm_end-frm_nxt < 4)
2064                 return codecvt_base::partial;
2065             uint8_t c2 = frm_nxt[1];
2066             uint8_t c3 = frm_nxt[2];
2067             uint8_t c4 = frm_nxt[3];
2068             switch (c1)
2069             {
2070             case 0xF0:
2071                 if (!(0x90 <= c2 && c2 <= 0xBF))
2072                     return codecvt_base::error;
2073                  break;
2074             case 0xF4:
2075                 if ((c2 & 0xF0) != 0x80)
2076                     return codecvt_base::error;
2077                  break;
2078             default:
2079                 if ((c2 & 0xC0) != 0x80)
2080                     return codecvt_base::error;
2081                  break;
2082             }
2083             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2084                 return codecvt_base::error;
2085             if (to_end-to_nxt < 2)
2086                 return codecvt_base::partial;
2087             if ((((c1 & 7UL) << 18) +
2088                 ((c2 & 0x3FUL) << 12) +
2089                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2090                 return codecvt_base::error;
2091             *to_nxt = static_cast<uint16_t>(
2092                     0xD800
2093                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2094                   | ((c2 & 0x0F) << 2)
2095                   | ((c3 & 0x30) >> 4));
2096             *++to_nxt = static_cast<uint16_t>(
2097                     0xDC00
2098                   | ((c3 & 0x0F) << 6)
2099                   |  (c4 & 0x3F));
2100             frm_nxt += 4;
2101         }
2102         else
2103         {
2104             return codecvt_base::error;
2105         }
2106     }
2107     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2108 }
2109 
2110 static
2111 codecvt_base::result
2112 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2113               uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2114               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2115 {
2116     frm_nxt = frm;
2117     to_nxt = to;
2118     if (mode & consume_header)
2119     {
2120         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2121                                                           frm_nxt[2] == 0xBF)
2122             frm_nxt += 3;
2123     }
2124     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2125     {
2126         uint8_t c1 = *frm_nxt;
2127         if (c1 > Maxcode)
2128             return codecvt_base::error;
2129         if (c1 < 0x80)
2130         {
2131             *to_nxt = static_cast<uint32_t>(c1);
2132             ++frm_nxt;
2133         }
2134         else if (c1 < 0xC2)
2135         {
2136             return codecvt_base::error;
2137         }
2138         else if (c1 < 0xE0)
2139         {
2140             if (frm_end-frm_nxt < 2)
2141                 return codecvt_base::partial;
2142             uint8_t c2 = frm_nxt[1];
2143             if ((c2 & 0xC0) != 0x80)
2144                 return codecvt_base::error;
2145             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2146             if (t > Maxcode)
2147                 return codecvt_base::error;
2148             *to_nxt = static_cast<uint32_t>(t);
2149             frm_nxt += 2;
2150         }
2151         else if (c1 < 0xF0)
2152         {
2153             if (frm_end-frm_nxt < 3)
2154                 return codecvt_base::partial;
2155             uint8_t c2 = frm_nxt[1];
2156             uint8_t c3 = frm_nxt[2];
2157             switch (c1)
2158             {
2159             case 0xE0:
2160                 if ((c2 & 0xE0) != 0xA0)
2161                     return codecvt_base::error;
2162                  break;
2163             case 0xED:
2164                 if ((c2 & 0xE0) != 0x80)
2165                     return codecvt_base::error;
2166                  break;
2167             default:
2168                 if ((c2 & 0xC0) != 0x80)
2169                     return codecvt_base::error;
2170                  break;
2171             }
2172             if ((c3 & 0xC0) != 0x80)
2173                 return codecvt_base::error;
2174             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2175                                              | ((c2 & 0x3F) << 6)
2176                                              |  (c3 & 0x3F));
2177             if (t > Maxcode)
2178                 return codecvt_base::error;
2179             *to_nxt = static_cast<uint32_t>(t);
2180             frm_nxt += 3;
2181         }
2182         else if (c1 < 0xF5)
2183         {
2184             if (frm_end-frm_nxt < 4)
2185                 return codecvt_base::partial;
2186             uint8_t c2 = frm_nxt[1];
2187             uint8_t c3 = frm_nxt[2];
2188             uint8_t c4 = frm_nxt[3];
2189             switch (c1)
2190             {
2191             case 0xF0:
2192                 if (!(0x90 <= c2 && c2 <= 0xBF))
2193                     return codecvt_base::error;
2194                  break;
2195             case 0xF4:
2196                 if ((c2 & 0xF0) != 0x80)
2197                     return codecvt_base::error;
2198                  break;
2199             default:
2200                 if ((c2 & 0xC0) != 0x80)
2201                     return codecvt_base::error;
2202                  break;
2203             }
2204             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2205                 return codecvt_base::error;
2206             if (to_end-to_nxt < 2)
2207                 return codecvt_base::partial;
2208             if ((((c1 & 7UL) << 18) +
2209                 ((c2 & 0x3FUL) << 12) +
2210                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2211                 return codecvt_base::error;
2212             *to_nxt = static_cast<uint32_t>(
2213                     0xD800
2214                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2215                   | ((c2 & 0x0F) << 2)
2216                   | ((c3 & 0x30) >> 4));
2217             *++to_nxt = static_cast<uint32_t>(
2218                     0xDC00
2219                   | ((c3 & 0x0F) << 6)
2220                   |  (c4 & 0x3F));
2221             frm_nxt += 4;
2222         }
2223         else
2224         {
2225             return codecvt_base::error;
2226         }
2227     }
2228     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2229 }
2230 
2231 static
2232 int
2233 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2234                      size_t mx, unsigned long Maxcode = 0x10FFFF,
2235                      codecvt_mode mode = codecvt_mode(0))
2236 {
2237     const uint8_t* frm_nxt = frm;
2238     if (mode & consume_header)
2239     {
2240         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2241                                                           frm_nxt[2] == 0xBF)
2242             frm_nxt += 3;
2243     }
2244     for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2245     {
2246         uint8_t c1 = *frm_nxt;
2247         if (c1 > Maxcode)
2248             break;
2249         if (c1 < 0x80)
2250         {
2251             ++frm_nxt;
2252         }
2253         else if (c1 < 0xC2)
2254         {
2255             break;
2256         }
2257         else if (c1 < 0xE0)
2258         {
2259             if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2260                 break;
2261             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2262             if (t > Maxcode)
2263                 break;
2264             frm_nxt += 2;
2265         }
2266         else if (c1 < 0xF0)
2267         {
2268             if (frm_end-frm_nxt < 3)
2269                 break;
2270             uint8_t c2 = frm_nxt[1];
2271             uint8_t c3 = frm_nxt[2];
2272             switch (c1)
2273             {
2274             case 0xE0:
2275                 if ((c2 & 0xE0) != 0xA0)
2276                     return static_cast<int>(frm_nxt - frm);
2277                 break;
2278             case 0xED:
2279                 if ((c2 & 0xE0) != 0x80)
2280                     return static_cast<int>(frm_nxt - frm);
2281                  break;
2282             default:
2283                 if ((c2 & 0xC0) != 0x80)
2284                     return static_cast<int>(frm_nxt - frm);
2285                  break;
2286             }
2287             if ((c3 & 0xC0) != 0x80)
2288                 break;
2289             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2290                 break;
2291             frm_nxt += 3;
2292         }
2293         else if (c1 < 0xF5)
2294         {
2295             if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2296                 break;
2297             uint8_t c2 = frm_nxt[1];
2298             uint8_t c3 = frm_nxt[2];
2299             uint8_t c4 = frm_nxt[3];
2300             switch (c1)
2301             {
2302             case 0xF0:
2303                 if (!(0x90 <= c2 && c2 <= 0xBF))
2304                     return static_cast<int>(frm_nxt - frm);
2305                  break;
2306             case 0xF4:
2307                 if ((c2 & 0xF0) != 0x80)
2308                     return static_cast<int>(frm_nxt - frm);
2309                  break;
2310             default:
2311                 if ((c2 & 0xC0) != 0x80)
2312                     return static_cast<int>(frm_nxt - frm);
2313                  break;
2314             }
2315             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2316                 break;
2317             if ((((c1 & 7UL) << 18) +
2318                 ((c2 & 0x3FUL) << 12) +
2319                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2320                 break;
2321             ++nchar16_t;
2322             frm_nxt += 4;
2323         }
2324         else
2325         {
2326             break;
2327         }
2328     }
2329     return static_cast<int>(frm_nxt - frm);
2330 }
2331 
2332 static
2333 codecvt_base::result
2334 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2335              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2336              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2337 {
2338     frm_nxt = frm;
2339     to_nxt = to;
2340     if (mode & generate_header)
2341     {
2342         if (to_end-to_nxt < 3)
2343             return codecvt_base::partial;
2344         *to_nxt++ = static_cast<uint8_t>(0xEF);
2345         *to_nxt++ = static_cast<uint8_t>(0xBB);
2346         *to_nxt++ = static_cast<uint8_t>(0xBF);
2347     }
2348     for (; frm_nxt < frm_end; ++frm_nxt)
2349     {
2350         uint32_t wc = *frm_nxt;
2351         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2352             return codecvt_base::error;
2353         if (wc < 0x000080)
2354         {
2355             if (to_end-to_nxt < 1)
2356                 return codecvt_base::partial;
2357             *to_nxt++ = static_cast<uint8_t>(wc);
2358         }
2359         else if (wc < 0x000800)
2360         {
2361             if (to_end-to_nxt < 2)
2362                 return codecvt_base::partial;
2363             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2364             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2365         }
2366         else if (wc < 0x010000)
2367         {
2368             if (to_end-to_nxt < 3)
2369                 return codecvt_base::partial;
2370             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2371             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2372             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2373         }
2374         else // if (wc < 0x110000)
2375         {
2376             if (to_end-to_nxt < 4)
2377                 return codecvt_base::partial;
2378             *to_nxt++ = static_cast<uint8_t>(0xF0 |  (wc >> 18));
2379             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2380             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2381             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x00003F));
2382         }
2383     }
2384     return codecvt_base::ok;
2385 }
2386 
2387 static
2388 codecvt_base::result
2389 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2390              uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2391              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2392 {
2393     frm_nxt = frm;
2394     to_nxt = to;
2395     if (mode & consume_header)
2396     {
2397         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2398                                                           frm_nxt[2] == 0xBF)
2399             frm_nxt += 3;
2400     }
2401     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2402     {
2403         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2404         if (c1 < 0x80)
2405         {
2406             if (c1 > Maxcode)
2407                 return codecvt_base::error;
2408             *to_nxt = static_cast<uint32_t>(c1);
2409             ++frm_nxt;
2410         }
2411         else if (c1 < 0xC2)
2412         {
2413             return codecvt_base::error;
2414         }
2415         else if (c1 < 0xE0)
2416         {
2417             if (frm_end-frm_nxt < 2)
2418                 return codecvt_base::partial;
2419             uint8_t c2 = frm_nxt[1];
2420             if ((c2 & 0xC0) != 0x80)
2421                 return codecvt_base::error;
2422             uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2423                                               | (c2 & 0x3F));
2424             if (t > Maxcode)
2425                 return codecvt_base::error;
2426             *to_nxt = t;
2427             frm_nxt += 2;
2428         }
2429         else if (c1 < 0xF0)
2430         {
2431             if (frm_end-frm_nxt < 3)
2432                 return codecvt_base::partial;
2433             uint8_t c2 = frm_nxt[1];
2434             uint8_t c3 = frm_nxt[2];
2435             switch (c1)
2436             {
2437             case 0xE0:
2438                 if ((c2 & 0xE0) != 0xA0)
2439                     return codecvt_base::error;
2440                  break;
2441             case 0xED:
2442                 if ((c2 & 0xE0) != 0x80)
2443                     return codecvt_base::error;
2444                  break;
2445             default:
2446                 if ((c2 & 0xC0) != 0x80)
2447                     return codecvt_base::error;
2448                  break;
2449             }
2450             if ((c3 & 0xC0) != 0x80)
2451                 return codecvt_base::error;
2452             uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2453                                              | ((c2 & 0x3F) << 6)
2454                                              |  (c3 & 0x3F));
2455             if (t > Maxcode)
2456                 return codecvt_base::error;
2457             *to_nxt = t;
2458             frm_nxt += 3;
2459         }
2460         else if (c1 < 0xF5)
2461         {
2462             if (frm_end-frm_nxt < 4)
2463                 return codecvt_base::partial;
2464             uint8_t c2 = frm_nxt[1];
2465             uint8_t c3 = frm_nxt[2];
2466             uint8_t c4 = frm_nxt[3];
2467             switch (c1)
2468             {
2469             case 0xF0:
2470                 if (!(0x90 <= c2 && c2 <= 0xBF))
2471                     return codecvt_base::error;
2472                  break;
2473             case 0xF4:
2474                 if ((c2 & 0xF0) != 0x80)
2475                     return codecvt_base::error;
2476                  break;
2477             default:
2478                 if ((c2 & 0xC0) != 0x80)
2479                     return codecvt_base::error;
2480                  break;
2481             }
2482             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2483                 return codecvt_base::error;
2484             uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2485                                              | ((c2 & 0x3F) << 12)
2486                                              | ((c3 & 0x3F) << 6)
2487                                              |  (c4 & 0x3F));
2488             if (t > Maxcode)
2489                 return codecvt_base::error;
2490             *to_nxt = t;
2491             frm_nxt += 4;
2492         }
2493         else
2494         {
2495             return codecvt_base::error;
2496         }
2497     }
2498     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2499 }
2500 
2501 static
2502 int
2503 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2504                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2505                     codecvt_mode mode = codecvt_mode(0))
2506 {
2507     const uint8_t* frm_nxt = frm;
2508     if (mode & consume_header)
2509     {
2510         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2511                                                           frm_nxt[2] == 0xBF)
2512             frm_nxt += 3;
2513     }
2514     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2515     {
2516         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2517         if (c1 < 0x80)
2518         {
2519             if (c1 > Maxcode)
2520                 break;
2521             ++frm_nxt;
2522         }
2523         else if (c1 < 0xC2)
2524         {
2525             break;
2526         }
2527         else if (c1 < 0xE0)
2528         {
2529             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2530                 break;
2531             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2532                 break;
2533             frm_nxt += 2;
2534         }
2535         else if (c1 < 0xF0)
2536         {
2537             if (frm_end-frm_nxt < 3)
2538                 break;
2539             uint8_t c2 = frm_nxt[1];
2540             uint8_t c3 = frm_nxt[2];
2541             switch (c1)
2542             {
2543             case 0xE0:
2544                 if ((c2 & 0xE0) != 0xA0)
2545                     return static_cast<int>(frm_nxt - frm);
2546                 break;
2547             case 0xED:
2548                 if ((c2 & 0xE0) != 0x80)
2549                     return static_cast<int>(frm_nxt - frm);
2550                  break;
2551             default:
2552                 if ((c2 & 0xC0) != 0x80)
2553                     return static_cast<int>(frm_nxt - frm);
2554                  break;
2555             }
2556             if ((c3 & 0xC0) != 0x80)
2557                 break;
2558             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2559                 break;
2560             frm_nxt += 3;
2561         }
2562         else if (c1 < 0xF5)
2563         {
2564             if (frm_end-frm_nxt < 4)
2565                 break;
2566             uint8_t c2 = frm_nxt[1];
2567             uint8_t c3 = frm_nxt[2];
2568             uint8_t c4 = frm_nxt[3];
2569             switch (c1)
2570             {
2571             case 0xF0:
2572                 if (!(0x90 <= c2 && c2 <= 0xBF))
2573                     return static_cast<int>(frm_nxt - frm);
2574                  break;
2575             case 0xF4:
2576                 if ((c2 & 0xF0) != 0x80)
2577                     return static_cast<int>(frm_nxt - frm);
2578                  break;
2579             default:
2580                 if ((c2 & 0xC0) != 0x80)
2581                     return static_cast<int>(frm_nxt - frm);
2582                  break;
2583             }
2584             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2585                 break;
2586             if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2587                  ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)
2588                 break;
2589             frm_nxt += 4;
2590         }
2591         else
2592         {
2593             break;
2594         }
2595     }
2596     return static_cast<int>(frm_nxt - frm);
2597 }
2598 
2599 static
2600 codecvt_base::result
2601 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2602              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2603              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2604 {
2605     frm_nxt = frm;
2606     to_nxt = to;
2607     if (mode & generate_header)
2608     {
2609         if (to_end-to_nxt < 3)
2610             return codecvt_base::partial;
2611         *to_nxt++ = static_cast<uint8_t>(0xEF);
2612         *to_nxt++ = static_cast<uint8_t>(0xBB);
2613         *to_nxt++ = static_cast<uint8_t>(0xBF);
2614     }
2615     for (; frm_nxt < frm_end; ++frm_nxt)
2616     {
2617         uint16_t wc = *frm_nxt;
2618         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2619             return codecvt_base::error;
2620         if (wc < 0x0080)
2621         {
2622             if (to_end-to_nxt < 1)
2623                 return codecvt_base::partial;
2624             *to_nxt++ = static_cast<uint8_t>(wc);
2625         }
2626         else if (wc < 0x0800)
2627         {
2628             if (to_end-to_nxt < 2)
2629                 return codecvt_base::partial;
2630             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2631             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2632         }
2633         else // if (wc <= 0xFFFF)
2634         {
2635             if (to_end-to_nxt < 3)
2636                 return codecvt_base::partial;
2637             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2638             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2639             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2640         }
2641     }
2642     return codecvt_base::ok;
2643 }
2644 
2645 static
2646 codecvt_base::result
2647 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2648              uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2649              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2650 {
2651     frm_nxt = frm;
2652     to_nxt = to;
2653     if (mode & consume_header)
2654     {
2655         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2656                                                           frm_nxt[2] == 0xBF)
2657             frm_nxt += 3;
2658     }
2659     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2660     {
2661         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2662         if (c1 < 0x80)
2663         {
2664             if (c1 > Maxcode)
2665                 return codecvt_base::error;
2666             *to_nxt = static_cast<uint16_t>(c1);
2667             ++frm_nxt;
2668         }
2669         else if (c1 < 0xC2)
2670         {
2671             return codecvt_base::error;
2672         }
2673         else if (c1 < 0xE0)
2674         {
2675             if (frm_end-frm_nxt < 2)
2676                 return codecvt_base::partial;
2677             uint8_t c2 = frm_nxt[1];
2678             if ((c2 & 0xC0) != 0x80)
2679                 return codecvt_base::error;
2680             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2681                                               | (c2 & 0x3F));
2682             if (t > Maxcode)
2683                 return codecvt_base::error;
2684             *to_nxt = t;
2685             frm_nxt += 2;
2686         }
2687         else if (c1 < 0xF0)
2688         {
2689             if (frm_end-frm_nxt < 3)
2690                 return codecvt_base::partial;
2691             uint8_t c2 = frm_nxt[1];
2692             uint8_t c3 = frm_nxt[2];
2693             switch (c1)
2694             {
2695             case 0xE0:
2696                 if ((c2 & 0xE0) != 0xA0)
2697                     return codecvt_base::error;
2698                  break;
2699             case 0xED:
2700                 if ((c2 & 0xE0) != 0x80)
2701                     return codecvt_base::error;
2702                  break;
2703             default:
2704                 if ((c2 & 0xC0) != 0x80)
2705                     return codecvt_base::error;
2706                  break;
2707             }
2708             if ((c3 & 0xC0) != 0x80)
2709                 return codecvt_base::error;
2710             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2711                                              | ((c2 & 0x3F) << 6)
2712                                              |  (c3 & 0x3F));
2713             if (t > Maxcode)
2714                 return codecvt_base::error;
2715             *to_nxt = t;
2716             frm_nxt += 3;
2717         }
2718         else
2719         {
2720             return codecvt_base::error;
2721         }
2722     }
2723     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2724 }
2725 
2726 static
2727 int
2728 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2729                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2730                     codecvt_mode mode = codecvt_mode(0))
2731 {
2732     const uint8_t* frm_nxt = frm;
2733     if (mode & consume_header)
2734     {
2735         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2736                                                           frm_nxt[2] == 0xBF)
2737             frm_nxt += 3;
2738     }
2739     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2740     {
2741         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2742         if (c1 < 0x80)
2743         {
2744             if (c1 > Maxcode)
2745                 break;
2746             ++frm_nxt;
2747         }
2748         else if (c1 < 0xC2)
2749         {
2750             break;
2751         }
2752         else if (c1 < 0xE0)
2753         {
2754             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2755                 break;
2756             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2757                 break;
2758             frm_nxt += 2;
2759         }
2760         else if (c1 < 0xF0)
2761         {
2762             if (frm_end-frm_nxt < 3)
2763                 break;
2764             uint8_t c2 = frm_nxt[1];
2765             uint8_t c3 = frm_nxt[2];
2766             switch (c1)
2767             {
2768             case 0xE0:
2769                 if ((c2 & 0xE0) != 0xA0)
2770                     return static_cast<int>(frm_nxt - frm);
2771                 break;
2772             case 0xED:
2773                 if ((c2 & 0xE0) != 0x80)
2774                     return static_cast<int>(frm_nxt - frm);
2775                  break;
2776             default:
2777                 if ((c2 & 0xC0) != 0x80)
2778                     return static_cast<int>(frm_nxt - frm);
2779                  break;
2780             }
2781             if ((c3 & 0xC0) != 0x80)
2782                 break;
2783             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2784                 break;
2785             frm_nxt += 3;
2786         }
2787         else
2788         {
2789             break;
2790         }
2791     }
2792     return static_cast<int>(frm_nxt - frm);
2793 }
2794 
2795 static
2796 codecvt_base::result
2797 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2798                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2799                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2800 {
2801     frm_nxt = frm;
2802     to_nxt = to;
2803     if (mode & generate_header)
2804     {
2805         if (to_end-to_nxt < 2)
2806             return codecvt_base::partial;
2807         *to_nxt++ = static_cast<uint8_t>(0xFE);
2808         *to_nxt++ = static_cast<uint8_t>(0xFF);
2809     }
2810     for (; frm_nxt < frm_end; ++frm_nxt)
2811     {
2812         uint32_t wc = *frm_nxt;
2813         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2814             return codecvt_base::error;
2815         if (wc < 0x010000)
2816         {
2817             if (to_end-to_nxt < 2)
2818                 return codecvt_base::partial;
2819             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2820             *to_nxt++ = static_cast<uint8_t>(wc);
2821         }
2822         else
2823         {
2824             if (to_end-to_nxt < 4)
2825                 return codecvt_base::partial;
2826             uint16_t t = static_cast<uint16_t>(
2827                     0xD800
2828                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2829                   |   ((wc & 0x00FC00) >> 10));
2830             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2831             *to_nxt++ = static_cast<uint8_t>(t);
2832             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2833             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2834             *to_nxt++ = static_cast<uint8_t>(t);
2835         }
2836     }
2837     return codecvt_base::ok;
2838 }
2839 
2840 static
2841 codecvt_base::result
2842 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2843                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2844                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2845 {
2846     frm_nxt = frm;
2847     to_nxt = to;
2848     if (mode & consume_header)
2849     {
2850         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2851             frm_nxt += 2;
2852     }
2853     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2854     {
2855         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2856         if ((c1 & 0xFC00) == 0xDC00)
2857             return codecvt_base::error;
2858         if ((c1 & 0xFC00) != 0xD800)
2859         {
2860             if (c1 > Maxcode)
2861                 return codecvt_base::error;
2862             *to_nxt = static_cast<uint32_t>(c1);
2863             frm_nxt += 2;
2864         }
2865         else
2866         {
2867             if (frm_end-frm_nxt < 4)
2868                 return codecvt_base::partial;
2869             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2870             if ((c2 & 0xFC00) != 0xDC00)
2871                 return codecvt_base::error;
2872             uint32_t t = static_cast<uint32_t>(
2873                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2874                   |   ((c1 & 0x003F) << 10)
2875                   |    (c2 & 0x03FF));
2876             if (t > Maxcode)
2877                 return codecvt_base::error;
2878             *to_nxt = t;
2879             frm_nxt += 4;
2880         }
2881     }
2882     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2883 }
2884 
2885 static
2886 int
2887 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2888                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2889                        codecvt_mode mode = codecvt_mode(0))
2890 {
2891     const uint8_t* frm_nxt = frm;
2892     if (mode & consume_header)
2893     {
2894         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2895             frm_nxt += 2;
2896     }
2897     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2898     {
2899         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2900         if ((c1 & 0xFC00) == 0xDC00)
2901             break;
2902         if ((c1 & 0xFC00) != 0xD800)
2903         {
2904             if (c1 > Maxcode)
2905                 break;
2906             frm_nxt += 2;
2907         }
2908         else
2909         {
2910             if (frm_end-frm_nxt < 4)
2911                 break;
2912             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2913             if ((c2 & 0xFC00) != 0xDC00)
2914                 break;
2915             uint32_t t = static_cast<uint32_t>(
2916                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2917                   |   ((c1 & 0x003F) << 10)
2918                   |    (c2 & 0x03FF));
2919             if (t > Maxcode)
2920                 break;
2921             frm_nxt += 4;
2922         }
2923     }
2924     return static_cast<int>(frm_nxt - frm);
2925 }
2926 
2927 static
2928 codecvt_base::result
2929 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2930                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2931                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2932 {
2933     frm_nxt = frm;
2934     to_nxt = to;
2935     if (mode & generate_header)
2936     {
2937         if (to_end - to_nxt < 2)
2938             return codecvt_base::partial;
2939         *to_nxt++ = static_cast<uint8_t>(0xFF);
2940         *to_nxt++ = static_cast<uint8_t>(0xFE);
2941     }
2942     for (; frm_nxt < frm_end; ++frm_nxt)
2943     {
2944         uint32_t wc = *frm_nxt;
2945         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2946             return codecvt_base::error;
2947         if (wc < 0x010000)
2948         {
2949             if (to_end-to_nxt < 2)
2950                 return codecvt_base::partial;
2951             *to_nxt++ = static_cast<uint8_t>(wc);
2952             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2953         }
2954         else
2955         {
2956             if (to_end-to_nxt < 4)
2957                 return codecvt_base::partial;
2958             uint16_t t = static_cast<uint16_t>(
2959                     0xD800
2960                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2961                   |   ((wc & 0x00FC00) >> 10));
2962             *to_nxt++ = static_cast<uint8_t>(t);
2963             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2964             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2965             *to_nxt++ = static_cast<uint8_t>(t);
2966             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2967         }
2968     }
2969     return codecvt_base::ok;
2970 }
2971 
2972 static
2973 codecvt_base::result
2974 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2975                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2976                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2977 {
2978     frm_nxt = frm;
2979     to_nxt = to;
2980     if (mode & consume_header)
2981     {
2982         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2983             frm_nxt += 2;
2984     }
2985     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2986     {
2987         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2988         if ((c1 & 0xFC00) == 0xDC00)
2989             return codecvt_base::error;
2990         if ((c1 & 0xFC00) != 0xD800)
2991         {
2992             if (c1 > Maxcode)
2993                 return codecvt_base::error;
2994             *to_nxt = static_cast<uint32_t>(c1);
2995             frm_nxt += 2;
2996         }
2997         else
2998         {
2999             if (frm_end-frm_nxt < 4)
3000                 return codecvt_base::partial;
3001             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3002             if ((c2 & 0xFC00) != 0xDC00)
3003                 return codecvt_base::error;
3004             uint32_t t = static_cast<uint32_t>(
3005                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
3006                   |   ((c1 & 0x003F) << 10)
3007                   |    (c2 & 0x03FF));
3008             if (t > Maxcode)
3009                 return codecvt_base::error;
3010             *to_nxt = t;
3011             frm_nxt += 4;
3012         }
3013     }
3014     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3015 }
3016 
3017 static
3018 int
3019 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
3020                        size_t mx, unsigned long Maxcode = 0x10FFFF,
3021                        codecvt_mode mode = codecvt_mode(0))
3022 {
3023     const uint8_t* frm_nxt = frm;
3024     if (mode & consume_header)
3025     {
3026         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3027             frm_nxt += 2;
3028     }
3029     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
3030     {
3031         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3032         if ((c1 & 0xFC00) == 0xDC00)
3033             break;
3034         if ((c1 & 0xFC00) != 0xD800)
3035         {
3036             if (c1 > Maxcode)
3037                 break;
3038             frm_nxt += 2;
3039         }
3040         else
3041         {
3042             if (frm_end-frm_nxt < 4)
3043                 break;
3044             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3045             if ((c2 & 0xFC00) != 0xDC00)
3046                 break;
3047             uint32_t t = static_cast<uint32_t>(
3048                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
3049                   |   ((c1 & 0x003F) << 10)
3050                   |    (c2 & 0x03FF));
3051             if (t > Maxcode)
3052                 break;
3053             frm_nxt += 4;
3054         }
3055     }
3056     return static_cast<int>(frm_nxt - frm);
3057 }
3058 
3059 static
3060 codecvt_base::result
3061 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3062                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3063                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3064 {
3065     frm_nxt = frm;
3066     to_nxt = to;
3067     if (mode & generate_header)
3068     {
3069         if (to_end-to_nxt < 2)
3070             return codecvt_base::partial;
3071         *to_nxt++ = static_cast<uint8_t>(0xFE);
3072         *to_nxt++ = static_cast<uint8_t>(0xFF);
3073     }
3074     for (; frm_nxt < frm_end; ++frm_nxt)
3075     {
3076         uint16_t wc = *frm_nxt;
3077         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3078             return codecvt_base::error;
3079         if (to_end-to_nxt < 2)
3080             return codecvt_base::partial;
3081         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3082         *to_nxt++ = static_cast<uint8_t>(wc);
3083     }
3084     return codecvt_base::ok;
3085 }
3086 
3087 static
3088 codecvt_base::result
3089 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3090                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3091                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3092 {
3093     frm_nxt = frm;
3094     to_nxt = to;
3095     if (mode & consume_header)
3096     {
3097         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3098             frm_nxt += 2;
3099     }
3100     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3101     {
3102         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3103         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3104             return codecvt_base::error;
3105         *to_nxt = c1;
3106         frm_nxt += 2;
3107     }
3108     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3109 }
3110 
3111 static
3112 int
3113 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3114                        size_t mx, unsigned long Maxcode = 0x10FFFF,
3115                        codecvt_mode mode = codecvt_mode(0))
3116 {
3117     const uint8_t* frm_nxt = frm;
3118     if (mode & consume_header)
3119     {
3120         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3121             frm_nxt += 2;
3122     }
3123     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3124     {
3125         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3126         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3127             break;
3128         frm_nxt += 2;
3129     }
3130     return static_cast<int>(frm_nxt - frm);
3131 }
3132 
3133 static
3134 codecvt_base::result
3135 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3136                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3137                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3138 {
3139     frm_nxt = frm;
3140     to_nxt = to;
3141     if (mode & generate_header)
3142     {
3143         if (to_end-to_nxt < 2)
3144             return codecvt_base::partial;
3145         *to_nxt++ = static_cast<uint8_t>(0xFF);
3146         *to_nxt++ = static_cast<uint8_t>(0xFE);
3147     }
3148     for (; frm_nxt < frm_end; ++frm_nxt)
3149     {
3150         uint16_t wc = *frm_nxt;
3151         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3152             return codecvt_base::error;
3153         if (to_end-to_nxt < 2)
3154             return codecvt_base::partial;
3155         *to_nxt++ = static_cast<uint8_t>(wc);
3156         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3157     }
3158     return codecvt_base::ok;
3159 }
3160 
3161 static
3162 codecvt_base::result
3163 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3164                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3165                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3166 {
3167     frm_nxt = frm;
3168     to_nxt = to;
3169     if (mode & consume_header)
3170     {
3171         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3172             frm_nxt += 2;
3173     }
3174     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3175     {
3176         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3177         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3178             return codecvt_base::error;
3179         *to_nxt = c1;
3180         frm_nxt += 2;
3181     }
3182     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3183 }
3184 
3185 static
3186 int
3187 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3188                        size_t mx, unsigned long Maxcode = 0x10FFFF,
3189                        codecvt_mode mode = codecvt_mode(0))
3190 {
3191     const uint8_t* frm_nxt = frm;
3192     frm_nxt = frm;
3193     if (mode & consume_header)
3194     {
3195         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3196             frm_nxt += 2;
3197     }
3198     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3199     {
3200         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3201         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3202             break;
3203         frm_nxt += 2;
3204     }
3205     return static_cast<int>(frm_nxt - frm);
3206 }
3207 
3208 _LIBCPP_SUPPRESS_DEPRECATED_POP
3209 
3210 // template <> class codecvt<char16_t, char, mbstate_t>
3211 
3212 locale::id codecvt<char16_t, char, mbstate_t>::id;
3213 
3214 codecvt<char16_t, char, mbstate_t>::~codecvt()
3215 {
3216 }
3217 
3218 codecvt<char16_t, char, mbstate_t>::result
3219 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3220     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3221     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3222 {
3223     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3224     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3225     const uint16_t* _frm_nxt = _frm;
3226     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3227     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3228     uint8_t* _to_nxt = _to;
3229     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3230     frm_nxt = frm + (_frm_nxt - _frm);
3231     to_nxt = to + (_to_nxt - _to);
3232     return r;
3233 }
3234 
3235 codecvt<char16_t, char, mbstate_t>::result
3236 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3237     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3238     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3239 {
3240     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3241     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3242     const uint8_t* _frm_nxt = _frm;
3243     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3244     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3245     uint16_t* _to_nxt = _to;
3246     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3247     frm_nxt = frm + (_frm_nxt - _frm);
3248     to_nxt = to + (_to_nxt - _to);
3249     return r;
3250 }
3251 
3252 codecvt<char16_t, char, mbstate_t>::result
3253 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3254     extern_type* to, extern_type*, extern_type*& to_nxt) const
3255 {
3256     to_nxt = to;
3257     return noconv;
3258 }
3259 
3260 int
3261 codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
3262 {
3263     return 0;
3264 }
3265 
3266 bool
3267 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
3268 {
3269     return false;
3270 }
3271 
3272 int
3273 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3274     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3275 {
3276     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3277     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3278     return utf8_to_utf16_length(_frm, _frm_end, mx);
3279 }
3280 
3281 int
3282 codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
3283 {
3284     return 4;
3285 }
3286 
3287 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3288 
3289 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3290 
3291 locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
3292 
3293 codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
3294 {
3295 }
3296 
3297 codecvt<char16_t, char8_t, mbstate_t>::result
3298 codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
3299     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3300     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3301 {
3302     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3303     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3304     const uint16_t* _frm_nxt = _frm;
3305     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3306     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3307     uint8_t* _to_nxt = _to;
3308     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3309     frm_nxt = frm + (_frm_nxt - _frm);
3310     to_nxt = to + (_to_nxt - _to);
3311     return r;
3312 }
3313 
3314 codecvt<char16_t, char8_t, mbstate_t>::result
3315 codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
3316     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3317     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3318 {
3319     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3320     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3321     const uint8_t* _frm_nxt = _frm;
3322     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3323     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3324     uint16_t* _to_nxt = _to;
3325     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3326     frm_nxt = frm + (_frm_nxt - _frm);
3327     to_nxt = to + (_to_nxt - _to);
3328     return r;
3329 }
3330 
3331 codecvt<char16_t, char8_t, mbstate_t>::result
3332 codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
3333     extern_type* to, extern_type*, extern_type*& to_nxt) const
3334 {
3335     to_nxt = to;
3336     return noconv;
3337 }
3338 
3339 int
3340 codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
3341 {
3342     return 0;
3343 }
3344 
3345 bool
3346 codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3347 {
3348     return false;
3349 }
3350 
3351 int
3352 codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
3353     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3354 {
3355     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3356     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3357     return utf8_to_utf16_length(_frm, _frm_end, mx);
3358 }
3359 
3360 int
3361 codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
3362 {
3363     return 4;
3364 }
3365 
3366 #endif
3367 
3368 // template <> class codecvt<char32_t, char, mbstate_t>
3369 
3370 locale::id codecvt<char32_t, char, mbstate_t>::id;
3371 
3372 codecvt<char32_t, char, mbstate_t>::~codecvt()
3373 {
3374 }
3375 
3376 codecvt<char32_t, char, mbstate_t>::result
3377 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3378     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3379     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3380 {
3381     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3382     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3383     const uint32_t* _frm_nxt = _frm;
3384     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3385     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3386     uint8_t* _to_nxt = _to;
3387     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3388     frm_nxt = frm + (_frm_nxt - _frm);
3389     to_nxt = to + (_to_nxt - _to);
3390     return r;
3391 }
3392 
3393 codecvt<char32_t, char, mbstate_t>::result
3394 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3395     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3396     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3397 {
3398     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3399     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3400     const uint8_t* _frm_nxt = _frm;
3401     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3402     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3403     uint32_t* _to_nxt = _to;
3404     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3405     frm_nxt = frm + (_frm_nxt - _frm);
3406     to_nxt = to + (_to_nxt - _to);
3407     return r;
3408 }
3409 
3410 codecvt<char32_t, char, mbstate_t>::result
3411 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3412     extern_type* to, extern_type*, extern_type*& to_nxt) const
3413 {
3414     to_nxt = to;
3415     return noconv;
3416 }
3417 
3418 int
3419 codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
3420 {
3421     return 0;
3422 }
3423 
3424 bool
3425 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
3426 {
3427     return false;
3428 }
3429 
3430 int
3431 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3432     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3433 {
3434     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3435     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3436     return utf8_to_ucs4_length(_frm, _frm_end, mx);
3437 }
3438 
3439 int
3440 codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
3441 {
3442     return 4;
3443 }
3444 
3445 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3446 
3447 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3448 
3449 locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
3450 
3451 codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
3452 {
3453 }
3454 
3455 codecvt<char32_t, char8_t, mbstate_t>::result
3456 codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
3457     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3458     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3459 {
3460     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3461     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3462     const uint32_t* _frm_nxt = _frm;
3463     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3464     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3465     uint8_t* _to_nxt = _to;
3466     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3467     frm_nxt = frm + (_frm_nxt - _frm);
3468     to_nxt = to + (_to_nxt - _to);
3469     return r;
3470 }
3471 
3472 codecvt<char32_t, char8_t, mbstate_t>::result
3473 codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
3474     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3475     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3476 {
3477     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3478     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3479     const uint8_t* _frm_nxt = _frm;
3480     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3481     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3482     uint32_t* _to_nxt = _to;
3483     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3484     frm_nxt = frm + (_frm_nxt - _frm);
3485     to_nxt = to + (_to_nxt - _to);
3486     return r;
3487 }
3488 
3489 codecvt<char32_t, char8_t, mbstate_t>::result
3490 codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
3491     extern_type* to, extern_type*, extern_type*& to_nxt) const
3492 {
3493     to_nxt = to;
3494     return noconv;
3495 }
3496 
3497 int
3498 codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
3499 {
3500     return 0;
3501 }
3502 
3503 bool
3504 codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3505 {
3506     return false;
3507 }
3508 
3509 int
3510 codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
3511     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3512 {
3513     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3514     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3515     return utf8_to_ucs4_length(_frm, _frm_end, mx);
3516 }
3517 
3518 int
3519 codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
3520 {
3521     return 4;
3522 }
3523 
3524 #endif
3525 
3526 // __codecvt_utf8<wchar_t>
3527 
3528 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3529 __codecvt_utf8<wchar_t>::result
3530 __codecvt_utf8<wchar_t>::do_out(state_type&,
3531     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3532     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3533 {
3534 #if defined(_LIBCPP_SHORT_WCHAR)
3535     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3536     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3537     const uint16_t* _frm_nxt = _frm;
3538 #else
3539     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3540     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3541     const uint32_t* _frm_nxt = _frm;
3542 #endif
3543     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3544     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3545     uint8_t* _to_nxt = _to;
3546 #if defined(_LIBCPP_SHORT_WCHAR)
3547     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3548                             _Maxcode_, _Mode_);
3549 #else
3550     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3551                             _Maxcode_, _Mode_);
3552 #endif
3553     frm_nxt = frm + (_frm_nxt - _frm);
3554     to_nxt = to + (_to_nxt - _to);
3555     return r;
3556 }
3557 
3558 __codecvt_utf8<wchar_t>::result
3559 __codecvt_utf8<wchar_t>::do_in(state_type&,
3560     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3561     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3562 {
3563     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3564     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3565     const uint8_t* _frm_nxt = _frm;
3566 #if defined(_LIBCPP_SHORT_WCHAR)
3567     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3568     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3569     uint16_t* _to_nxt = _to;
3570     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3571                             _Maxcode_, _Mode_);
3572 #else
3573     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3574     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3575     uint32_t* _to_nxt = _to;
3576     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3577                             _Maxcode_, _Mode_);
3578 #endif
3579     frm_nxt = frm + (_frm_nxt - _frm);
3580     to_nxt = to + (_to_nxt - _to);
3581     return r;
3582 }
3583 
3584 __codecvt_utf8<wchar_t>::result
3585 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3586     extern_type* to, extern_type*, extern_type*& to_nxt) const
3587 {
3588     to_nxt = to;
3589     return noconv;
3590 }
3591 
3592 int
3593 __codecvt_utf8<wchar_t>::do_encoding() const noexcept
3594 {
3595     return 0;
3596 }
3597 
3598 bool
3599 __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
3600 {
3601     return false;
3602 }
3603 
3604 int
3605 __codecvt_utf8<wchar_t>::do_length(state_type&,
3606     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3607 {
3608     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3609     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3610 #if defined(_LIBCPP_SHORT_WCHAR)
3611     return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3612 #else
3613     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3614 #endif
3615 }
3616 
3617 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3618 int
3619 __codecvt_utf8<wchar_t>::do_max_length() const noexcept
3620 {
3621 #if defined(_LIBCPP_SHORT_WCHAR)
3622     if (_Mode_ & consume_header)
3623         return 6;
3624     return 3;
3625 #else
3626     if (_Mode_ & consume_header)
3627         return 7;
3628     return 4;
3629 #endif
3630 }
3631 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3632 
3633 // __codecvt_utf8<char16_t>
3634 
3635 __codecvt_utf8<char16_t>::result
3636 __codecvt_utf8<char16_t>::do_out(state_type&,
3637     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3638     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3639 {
3640     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3641     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3642     const uint16_t* _frm_nxt = _frm;
3643     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3644     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3645     uint8_t* _to_nxt = _to;
3646     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3647                             _Maxcode_, _Mode_);
3648     frm_nxt = frm + (_frm_nxt - _frm);
3649     to_nxt = to + (_to_nxt - _to);
3650     return r;
3651 }
3652 
3653 __codecvt_utf8<char16_t>::result
3654 __codecvt_utf8<char16_t>::do_in(state_type&,
3655     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3656     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3657 {
3658     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3659     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3660     const uint8_t* _frm_nxt = _frm;
3661     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3662     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3663     uint16_t* _to_nxt = _to;
3664     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3665                             _Maxcode_, _Mode_);
3666     frm_nxt = frm + (_frm_nxt - _frm);
3667     to_nxt = to + (_to_nxt - _to);
3668     return r;
3669 }
3670 
3671 __codecvt_utf8<char16_t>::result
3672 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3673     extern_type* to, extern_type*, extern_type*& to_nxt) const
3674 {
3675     to_nxt = to;
3676     return noconv;
3677 }
3678 
3679 int
3680 __codecvt_utf8<char16_t>::do_encoding() const noexcept
3681 {
3682     return 0;
3683 }
3684 
3685 bool
3686 __codecvt_utf8<char16_t>::do_always_noconv() const noexcept
3687 {
3688     return false;
3689 }
3690 
3691 int
3692 __codecvt_utf8<char16_t>::do_length(state_type&,
3693     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3694 {
3695     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3696     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3697     return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3698 }
3699 
3700 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3701 int
3702 __codecvt_utf8<char16_t>::do_max_length() const noexcept
3703 {
3704     if (_Mode_ & consume_header)
3705         return 6;
3706     return 3;
3707 }
3708 _LIBCPP_SUPPRESS_DEPRECATED_POP
3709 
3710 // __codecvt_utf8<char32_t>
3711 
3712 __codecvt_utf8<char32_t>::result
3713 __codecvt_utf8<char32_t>::do_out(state_type&,
3714     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3715     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3716 {
3717     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3718     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3719     const uint32_t* _frm_nxt = _frm;
3720     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3721     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3722     uint8_t* _to_nxt = _to;
3723     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3724                             _Maxcode_, _Mode_);
3725     frm_nxt = frm + (_frm_nxt - _frm);
3726     to_nxt = to + (_to_nxt - _to);
3727     return r;
3728 }
3729 
3730 __codecvt_utf8<char32_t>::result
3731 __codecvt_utf8<char32_t>::do_in(state_type&,
3732     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3733     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3734 {
3735     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3736     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3737     const uint8_t* _frm_nxt = _frm;
3738     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3739     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3740     uint32_t* _to_nxt = _to;
3741     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3742                             _Maxcode_, _Mode_);
3743     frm_nxt = frm + (_frm_nxt - _frm);
3744     to_nxt = to + (_to_nxt - _to);
3745     return r;
3746 }
3747 
3748 __codecvt_utf8<char32_t>::result
3749 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3750     extern_type* to, extern_type*, extern_type*& to_nxt) const
3751 {
3752     to_nxt = to;
3753     return noconv;
3754 }
3755 
3756 int
3757 __codecvt_utf8<char32_t>::do_encoding() const noexcept
3758 {
3759     return 0;
3760 }
3761 
3762 bool
3763 __codecvt_utf8<char32_t>::do_always_noconv() const noexcept
3764 {
3765     return false;
3766 }
3767 
3768 int
3769 __codecvt_utf8<char32_t>::do_length(state_type&,
3770     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3771 {
3772     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3773     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3774     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3775 }
3776 
3777 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3778 int
3779 __codecvt_utf8<char32_t>::do_max_length() const noexcept
3780 {
3781     if (_Mode_ & consume_header)
3782         return 7;
3783     return 4;
3784 }
3785 _LIBCPP_SUPPRESS_DEPRECATED_POP
3786 
3787 // __codecvt_utf16<wchar_t, false>
3788 
3789 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3790 __codecvt_utf16<wchar_t, false>::result
3791 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3792     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3793     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3794 {
3795 #if defined(_LIBCPP_SHORT_WCHAR)
3796     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3797     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3798     const uint16_t* _frm_nxt = _frm;
3799 #else
3800     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3801     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3802     const uint32_t* _frm_nxt = _frm;
3803 #endif
3804     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3805     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3806     uint8_t* _to_nxt = _to;
3807 #if defined(_LIBCPP_SHORT_WCHAR)
3808     result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3809                                _Maxcode_, _Mode_);
3810 #else
3811     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3812                                _Maxcode_, _Mode_);
3813 #endif
3814     frm_nxt = frm + (_frm_nxt - _frm);
3815     to_nxt = to + (_to_nxt - _to);
3816     return r;
3817 }
3818 
3819 __codecvt_utf16<wchar_t, false>::result
3820 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3821     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3822     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3823 {
3824     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3825     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3826     const uint8_t* _frm_nxt = _frm;
3827 #if defined(_LIBCPP_SHORT_WCHAR)
3828     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3829     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3830     uint16_t* _to_nxt = _to;
3831     result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3832                                _Maxcode_, _Mode_);
3833 #else
3834     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3835     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3836     uint32_t* _to_nxt = _to;
3837     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3838                                _Maxcode_, _Mode_);
3839 #endif
3840     frm_nxt = frm + (_frm_nxt - _frm);
3841     to_nxt = to + (_to_nxt - _to);
3842     return r;
3843 }
3844 
3845 __codecvt_utf16<wchar_t, false>::result
3846 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3847     extern_type* to, extern_type*, extern_type*& to_nxt) const
3848 {
3849     to_nxt = to;
3850     return noconv;
3851 }
3852 
3853 int
3854 __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
3855 {
3856     return 0;
3857 }
3858 
3859 bool
3860 __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
3861 {
3862     return false;
3863 }
3864 
3865 int
3866 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3867     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3868 {
3869     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3870     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3871 #if defined(_LIBCPP_SHORT_WCHAR)
3872     return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3873 #else
3874     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3875 #endif
3876 }
3877 
3878 int
3879 __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
3880 {
3881 #if defined(_LIBCPP_SHORT_WCHAR)
3882     if (_Mode_ & consume_header)
3883         return 4;
3884     return 2;
3885 #else
3886     if (_Mode_ & consume_header)
3887         return 6;
3888     return 4;
3889 #endif
3890 }
3891 
3892 // __codecvt_utf16<wchar_t, true>
3893 
3894 __codecvt_utf16<wchar_t, true>::result
3895 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3896     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3897     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3898 {
3899 #if defined(_LIBCPP_SHORT_WCHAR)
3900     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3901     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3902     const uint16_t* _frm_nxt = _frm;
3903 #else
3904     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3905     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3906     const uint32_t* _frm_nxt = _frm;
3907 #endif
3908     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3909     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3910     uint8_t* _to_nxt = _to;
3911 #if defined(_LIBCPP_SHORT_WCHAR)
3912     result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3913                                _Maxcode_, _Mode_);
3914 #else
3915     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3916                                _Maxcode_, _Mode_);
3917 #endif
3918     frm_nxt = frm + (_frm_nxt - _frm);
3919     to_nxt = to + (_to_nxt - _to);
3920     return r;
3921 }
3922 
3923 __codecvt_utf16<wchar_t, true>::result
3924 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3925     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3926     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3927 {
3928     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3929     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3930     const uint8_t* _frm_nxt = _frm;
3931 #if defined(_LIBCPP_SHORT_WCHAR)
3932     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3933     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3934     uint16_t* _to_nxt = _to;
3935     result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3936                                _Maxcode_, _Mode_);
3937 #else
3938     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3939     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3940     uint32_t* _to_nxt = _to;
3941     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3942                                _Maxcode_, _Mode_);
3943 #endif
3944     frm_nxt = frm + (_frm_nxt - _frm);
3945     to_nxt = to + (_to_nxt - _to);
3946     return r;
3947 }
3948 
3949 __codecvt_utf16<wchar_t, true>::result
3950 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3951     extern_type* to, extern_type*, extern_type*& to_nxt) const
3952 {
3953     to_nxt = to;
3954     return noconv;
3955 }
3956 
3957 int
3958 __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
3959 {
3960     return 0;
3961 }
3962 
3963 bool
3964 __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
3965 {
3966     return false;
3967 }
3968 
3969 int
3970 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3971     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3972 {
3973     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3974     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3975 #if defined(_LIBCPP_SHORT_WCHAR)
3976     return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3977 #else
3978     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3979 #endif
3980 }
3981 
3982 int
3983 __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
3984 {
3985 #if defined(_LIBCPP_SHORT_WCHAR)
3986     if (_Mode_ & consume_header)
3987         return 4;
3988     return 2;
3989 #else
3990     if (_Mode_ & consume_header)
3991         return 6;
3992     return 4;
3993 #endif
3994 }
3995 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3996 
3997 // __codecvt_utf16<char16_t, false>
3998 
3999 __codecvt_utf16<char16_t, false>::result
4000 __codecvt_utf16<char16_t, false>::do_out(state_type&,
4001     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4002     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4003 {
4004     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4005     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4006     const uint16_t* _frm_nxt = _frm;
4007     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4008     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4009     uint8_t* _to_nxt = _to;
4010     result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4011                                _Maxcode_, _Mode_);
4012     frm_nxt = frm + (_frm_nxt - _frm);
4013     to_nxt = to + (_to_nxt - _to);
4014     return r;
4015 }
4016 
4017 __codecvt_utf16<char16_t, false>::result
4018 __codecvt_utf16<char16_t, false>::do_in(state_type&,
4019     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4020     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4021 {
4022     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4023     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4024     const uint8_t* _frm_nxt = _frm;
4025     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4026     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4027     uint16_t* _to_nxt = _to;
4028     result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4029                                _Maxcode_, _Mode_);
4030     frm_nxt = frm + (_frm_nxt - _frm);
4031     to_nxt = to + (_to_nxt - _to);
4032     return r;
4033 }
4034 
4035 __codecvt_utf16<char16_t, false>::result
4036 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
4037     extern_type* to, extern_type*, extern_type*& to_nxt) const
4038 {
4039     to_nxt = to;
4040     return noconv;
4041 }
4042 
4043 int
4044 __codecvt_utf16<char16_t, false>::do_encoding() const noexcept
4045 {
4046     return 0;
4047 }
4048 
4049 bool
4050 __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
4051 {
4052     return false;
4053 }
4054 
4055 int
4056 __codecvt_utf16<char16_t, false>::do_length(state_type&,
4057     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4058 {
4059     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4060     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4061     return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4062 }
4063 
4064 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4065 int
4066 __codecvt_utf16<char16_t, false>::do_max_length() const noexcept
4067 {
4068     if (_Mode_ & consume_header)
4069         return 4;
4070     return 2;
4071 }
4072 _LIBCPP_SUPPRESS_DEPRECATED_POP
4073 
4074 // __codecvt_utf16<char16_t, true>
4075 
4076 __codecvt_utf16<char16_t, true>::result
4077 __codecvt_utf16<char16_t, true>::do_out(state_type&,
4078     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4079     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4080 {
4081     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4082     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4083     const uint16_t* _frm_nxt = _frm;
4084     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4085     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4086     uint8_t* _to_nxt = _to;
4087     result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4088                                _Maxcode_, _Mode_);
4089     frm_nxt = frm + (_frm_nxt - _frm);
4090     to_nxt = to + (_to_nxt - _to);
4091     return r;
4092 }
4093 
4094 __codecvt_utf16<char16_t, true>::result
4095 __codecvt_utf16<char16_t, true>::do_in(state_type&,
4096     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4097     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4098 {
4099     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4100     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4101     const uint8_t* _frm_nxt = _frm;
4102     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4103     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4104     uint16_t* _to_nxt = _to;
4105     result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4106                                _Maxcode_, _Mode_);
4107     frm_nxt = frm + (_frm_nxt - _frm);
4108     to_nxt = to + (_to_nxt - _to);
4109     return r;
4110 }
4111 
4112 __codecvt_utf16<char16_t, true>::result
4113 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
4114     extern_type* to, extern_type*, extern_type*& to_nxt) const
4115 {
4116     to_nxt = to;
4117     return noconv;
4118 }
4119 
4120 int
4121 __codecvt_utf16<char16_t, true>::do_encoding() const noexcept
4122 {
4123     return 0;
4124 }
4125 
4126 bool
4127 __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
4128 {
4129     return false;
4130 }
4131 
4132 int
4133 __codecvt_utf16<char16_t, true>::do_length(state_type&,
4134     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4135 {
4136     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4137     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4138     return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4139 }
4140 
4141 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4142 int
4143 __codecvt_utf16<char16_t, true>::do_max_length() const noexcept
4144 {
4145     if (_Mode_ & consume_header)
4146         return 4;
4147     return 2;
4148 }
4149 _LIBCPP_SUPPRESS_DEPRECATED_POP
4150 
4151 // __codecvt_utf16<char32_t, false>
4152 
4153 __codecvt_utf16<char32_t, false>::result
4154 __codecvt_utf16<char32_t, false>::do_out(state_type&,
4155     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4156     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4157 {
4158     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4159     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4160     const uint32_t* _frm_nxt = _frm;
4161     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4162     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4163     uint8_t* _to_nxt = _to;
4164     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4165                                _Maxcode_, _Mode_);
4166     frm_nxt = frm + (_frm_nxt - _frm);
4167     to_nxt = to + (_to_nxt - _to);
4168     return r;
4169 }
4170 
4171 __codecvt_utf16<char32_t, false>::result
4172 __codecvt_utf16<char32_t, false>::do_in(state_type&,
4173     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4174     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4175 {
4176     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4177     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4178     const uint8_t* _frm_nxt = _frm;
4179     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4180     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4181     uint32_t* _to_nxt = _to;
4182     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4183                                _Maxcode_, _Mode_);
4184     frm_nxt = frm + (_frm_nxt - _frm);
4185     to_nxt = to + (_to_nxt - _to);
4186     return r;
4187 }
4188 
4189 __codecvt_utf16<char32_t, false>::result
4190 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
4191     extern_type* to, extern_type*, extern_type*& to_nxt) const
4192 {
4193     to_nxt = to;
4194     return noconv;
4195 }
4196 
4197 int
4198 __codecvt_utf16<char32_t, false>::do_encoding() const noexcept
4199 {
4200     return 0;
4201 }
4202 
4203 bool
4204 __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
4205 {
4206     return false;
4207 }
4208 
4209 int
4210 __codecvt_utf16<char32_t, false>::do_length(state_type&,
4211     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4212 {
4213     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4214     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4215     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4216 }
4217 
4218 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4219 int
4220 __codecvt_utf16<char32_t, false>::do_max_length() const noexcept
4221 {
4222     if (_Mode_ & consume_header)
4223         return 6;
4224     return 4;
4225 }
4226 _LIBCPP_SUPPRESS_DEPRECATED_POP
4227 
4228 // __codecvt_utf16<char32_t, true>
4229 
4230 __codecvt_utf16<char32_t, true>::result
4231 __codecvt_utf16<char32_t, true>::do_out(state_type&,
4232     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4233     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4234 {
4235     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4236     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4237     const uint32_t* _frm_nxt = _frm;
4238     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4239     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4240     uint8_t* _to_nxt = _to;
4241     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4242                                _Maxcode_, _Mode_);
4243     frm_nxt = frm + (_frm_nxt - _frm);
4244     to_nxt = to + (_to_nxt - _to);
4245     return r;
4246 }
4247 
4248 __codecvt_utf16<char32_t, true>::result
4249 __codecvt_utf16<char32_t, true>::do_in(state_type&,
4250     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4251     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4252 {
4253     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4254     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4255     const uint8_t* _frm_nxt = _frm;
4256     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4257     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4258     uint32_t* _to_nxt = _to;
4259     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4260                                _Maxcode_, _Mode_);
4261     frm_nxt = frm + (_frm_nxt - _frm);
4262     to_nxt = to + (_to_nxt - _to);
4263     return r;
4264 }
4265 
4266 __codecvt_utf16<char32_t, true>::result
4267 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
4268     extern_type* to, extern_type*, extern_type*& to_nxt) const
4269 {
4270     to_nxt = to;
4271     return noconv;
4272 }
4273 
4274 int
4275 __codecvt_utf16<char32_t, true>::do_encoding() const noexcept
4276 {
4277     return 0;
4278 }
4279 
4280 bool
4281 __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
4282 {
4283     return false;
4284 }
4285 
4286 int
4287 __codecvt_utf16<char32_t, true>::do_length(state_type&,
4288     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4289 {
4290     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4291     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4292     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4293 }
4294 
4295 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4296 int
4297 __codecvt_utf16<char32_t, true>::do_max_length() const noexcept
4298 {
4299     if (_Mode_ & consume_header)
4300         return 6;
4301     return 4;
4302 }
4303 _LIBCPP_SUPPRESS_DEPRECATED_POP
4304 
4305 // __codecvt_utf8_utf16<wchar_t>
4306 
4307 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4308 __codecvt_utf8_utf16<wchar_t>::result
4309 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4310     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4311     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4312 {
4313 #if defined(_LIBCPP_SHORT_WCHAR)
4314     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4315     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4316     const uint16_t* _frm_nxt = _frm;
4317 #else
4318     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4319     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4320     const uint32_t* _frm_nxt = _frm;
4321 #endif
4322     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4323     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4324     uint8_t* _to_nxt = _to;
4325     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4326                              _Maxcode_, _Mode_);
4327     frm_nxt = frm + (_frm_nxt - _frm);
4328     to_nxt = to + (_to_nxt - _to);
4329     return r;
4330 }
4331 
4332 __codecvt_utf8_utf16<wchar_t>::result
4333 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4334     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4335     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4336 {
4337     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4338     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4339     const uint8_t* _frm_nxt = _frm;
4340 #if defined(_LIBCPP_SHORT_WCHAR)
4341     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4342     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4343     uint16_t* _to_nxt = _to;
4344 #else
4345     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4346     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4347     uint32_t* _to_nxt = _to;
4348 #endif
4349     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4350                              _Maxcode_, _Mode_);
4351     frm_nxt = frm + (_frm_nxt - _frm);
4352     to_nxt = to + (_to_nxt - _to);
4353     return r;
4354 }
4355 
4356 __codecvt_utf8_utf16<wchar_t>::result
4357 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4358     extern_type* to, extern_type*, extern_type*& to_nxt) const
4359 {
4360     to_nxt = to;
4361     return noconv;
4362 }
4363 
4364 int
4365 __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
4366 {
4367     return 0;
4368 }
4369 
4370 bool
4371 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
4372 {
4373     return false;
4374 }
4375 
4376 int
4377 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4378     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4379 {
4380     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4381     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4382     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4383 }
4384 
4385 int
4386 __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
4387 {
4388     if (_Mode_ & consume_header)
4389         return 7;
4390     return 4;
4391 }
4392 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4393 
4394 // __codecvt_utf8_utf16<char16_t>
4395 
4396 __codecvt_utf8_utf16<char16_t>::result
4397 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4398     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4399     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4400 {
4401     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4402     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4403     const uint16_t* _frm_nxt = _frm;
4404     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4405     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4406     uint8_t* _to_nxt = _to;
4407     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4408                              _Maxcode_, _Mode_);
4409     frm_nxt = frm + (_frm_nxt - _frm);
4410     to_nxt = to + (_to_nxt - _to);
4411     return r;
4412 }
4413 
4414 __codecvt_utf8_utf16<char16_t>::result
4415 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4416     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4417     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4418 {
4419     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4420     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4421     const uint8_t* _frm_nxt = _frm;
4422     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4423     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4424     uint16_t* _to_nxt = _to;
4425     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4426                              _Maxcode_, _Mode_);
4427     frm_nxt = frm + (_frm_nxt - _frm);
4428     to_nxt = to + (_to_nxt - _to);
4429     return r;
4430 }
4431 
4432 __codecvt_utf8_utf16<char16_t>::result
4433 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4434     extern_type* to, extern_type*, extern_type*& to_nxt) const
4435 {
4436     to_nxt = to;
4437     return noconv;
4438 }
4439 
4440 int
4441 __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
4442 {
4443     return 0;
4444 }
4445 
4446 bool
4447 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
4448 {
4449     return false;
4450 }
4451 
4452 int
4453 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4454     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4455 {
4456     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4457     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4458     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4459 }
4460 
4461 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4462 int
4463 __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
4464 {
4465     if (_Mode_ & consume_header)
4466         return 7;
4467     return 4;
4468 }
4469 _LIBCPP_SUPPRESS_DEPRECATED_POP
4470 
4471 // __codecvt_utf8_utf16<char32_t>
4472 
4473 __codecvt_utf8_utf16<char32_t>::result
4474 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4475     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4476     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4477 {
4478     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4479     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4480     const uint32_t* _frm_nxt = _frm;
4481     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4482     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4483     uint8_t* _to_nxt = _to;
4484     result r = utf16_to_utf8(_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;
4489 }
4490 
4491 __codecvt_utf8_utf16<char32_t>::result
4492 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4493     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4494     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4495 {
4496     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4497     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4498     const uint8_t* _frm_nxt = _frm;
4499     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4500     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4501     uint32_t* _to_nxt = _to;
4502     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4503                              _Maxcode_, _Mode_);
4504     frm_nxt = frm + (_frm_nxt - _frm);
4505     to_nxt = to + (_to_nxt - _to);
4506     return r;
4507 }
4508 
4509 __codecvt_utf8_utf16<char32_t>::result
4510 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4511     extern_type* to, extern_type*, extern_type*& to_nxt) const
4512 {
4513     to_nxt = to;
4514     return noconv;
4515 }
4516 
4517 int
4518 __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
4519 {
4520     return 0;
4521 }
4522 
4523 bool
4524 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
4525 {
4526     return false;
4527 }
4528 
4529 int
4530 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4531     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4532 {
4533     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4534     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4535     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4536 }
4537 
4538 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4539 int
4540 __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
4541 {
4542     if (_Mode_ & consume_header)
4543         return 7;
4544     return 4;
4545 }
4546 _LIBCPP_SUPPRESS_DEPRECATED_POP
4547 
4548 // __narrow_to_utf8<16>
4549 
4550 __narrow_to_utf8<16>::~__narrow_to_utf8()
4551 {
4552 }
4553 
4554 // __narrow_to_utf8<32>
4555 
4556 __narrow_to_utf8<32>::~__narrow_to_utf8()
4557 {
4558 }
4559 
4560 // __widen_from_utf8<16>
4561 
4562 __widen_from_utf8<16>::~__widen_from_utf8()
4563 {
4564 }
4565 
4566 // __widen_from_utf8<32>
4567 
4568 __widen_from_utf8<32>::~__widen_from_utf8()
4569 {
4570 }
4571 
4572 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4573 static bool checked_string_to_wchar_convert(wchar_t& dest,
4574                                             const char* ptr,
4575                                             locale_t loc) {
4576   if (*ptr == '\0')
4577     return false;
4578   mbstate_t mb = {};
4579   wchar_t out;
4580   size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4581   if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4582     return false;
4583   }
4584   dest = out;
4585   return true;
4586 }
4587 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4588 
4589 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4590 static bool is_narrow_non_breaking_space(const char* ptr) {
4591   // https://www.fileformat.info/info/unicode/char/202f/index.htm
4592   return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
4593 }
4594 
4595 static bool is_non_breaking_space(const char* ptr) {
4596   // https://www.fileformat.info/info/unicode/char/0a/index.htm
4597   return ptr[0] == '\xc2' && ptr[1] == '\xa0';
4598 }
4599 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4600 
4601 static bool checked_string_to_char_convert(char& dest,
4602                                            const char* ptr,
4603                                            locale_t __loc) {
4604   if (*ptr == '\0')
4605     return false;
4606   if (!ptr[1]) {
4607     dest = *ptr;
4608     return true;
4609   }
4610 
4611 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4612   // First convert the MBS into a wide char then attempt to narrow it using
4613   // wctob_l.
4614   wchar_t wout;
4615   if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4616     return false;
4617   int res;
4618   if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4619     dest = res;
4620     return true;
4621   }
4622   // FIXME: Work around specific multibyte sequences that we can reasonably
4623   // translate into a different single byte.
4624   switch (wout) {
4625   case L'\u202F': // narrow non-breaking space
4626   case L'\u00A0': // non-breaking space
4627     dest = ' ';
4628     return true;
4629   default:
4630     return false;
4631   }
4632 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4633   // FIXME: Work around specific multibyte sequences that we can reasonably
4634   // translate into a different single byte.
4635   if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
4636     dest = ' ';
4637     return true;
4638   }
4639 
4640   return false;
4641 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4642   __libcpp_unreachable();
4643 }
4644 
4645 
4646 // numpunct<char> && numpunct<wchar_t>
4647 
4648 locale::id numpunct< char  >::id;
4649 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4650 locale::id numpunct<wchar_t>::id;
4651 #endif
4652 
4653 numpunct<char>::numpunct(size_t refs)
4654     : locale::facet(refs),
4655       __decimal_point_('.'),
4656       __thousands_sep_(',')
4657 {
4658 }
4659 
4660 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4661 numpunct<wchar_t>::numpunct(size_t refs)
4662     : locale::facet(refs),
4663       __decimal_point_(L'.'),
4664       __thousands_sep_(L',')
4665 {
4666 }
4667 #endif
4668 
4669 numpunct<char>::~numpunct()
4670 {
4671 }
4672 
4673 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4674 numpunct<wchar_t>::~numpunct()
4675 {
4676 }
4677 #endif
4678 
4679  char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}
4680 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4681 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4682 #endif
4683 
4684  char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}
4685 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4686 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4687 #endif
4688 
4689 string numpunct< char  >::do_grouping() const {return __grouping_;}
4690 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4691 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4692 #endif
4693 
4694  string numpunct< char  >::do_truename() const {return "true";}
4695 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4696 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4697 #endif
4698 
4699  string numpunct< char  >::do_falsename() const {return "false";}
4700 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4701 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4702 #endif
4703 
4704 // numpunct_byname<char>
4705 
4706 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4707     : numpunct<char>(refs)
4708 {
4709     __init(nm);
4710 }
4711 
4712 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4713     : numpunct<char>(refs)
4714 {
4715     __init(nm.c_str());
4716 }
4717 
4718 numpunct_byname<char>::~numpunct_byname()
4719 {
4720 }
4721 
4722 void
4723 numpunct_byname<char>::__init(const char* nm)
4724 {
4725     typedef numpunct<char> base;
4726     if (strcmp(nm, "C") != 0)
4727     {
4728         __libcpp_unique_locale loc(nm);
4729         if (!loc)
4730             __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4731                                 " failed to construct for " + string(nm));
4732 
4733         lconv* lc = __libcpp_localeconv_l(loc.get());
4734         if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4735                                             loc.get()))
4736             __decimal_point_ = base::do_decimal_point();
4737         if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4738                                             loc.get()))
4739             __thousands_sep_ = base::do_thousands_sep();
4740         __grouping_ = lc->grouping;
4741         // localization for truename and falsename is not available
4742     }
4743 }
4744 
4745 // numpunct_byname<wchar_t>
4746 
4747 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4748 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4749     : numpunct<wchar_t>(refs)
4750 {
4751     __init(nm);
4752 }
4753 
4754 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4755     : numpunct<wchar_t>(refs)
4756 {
4757     __init(nm.c_str());
4758 }
4759 
4760 numpunct_byname<wchar_t>::~numpunct_byname()
4761 {
4762 }
4763 
4764 void
4765 numpunct_byname<wchar_t>::__init(const char* nm)
4766 {
4767     if (strcmp(nm, "C") != 0)
4768     {
4769         __libcpp_unique_locale loc(nm);
4770         if (!loc)
4771             __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4772                                 " failed to construct for " + string(nm));
4773 
4774         lconv* lc = __libcpp_localeconv_l(loc.get());
4775         checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4776                                         loc.get());
4777         checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4778                                         loc.get());
4779         __grouping_ = lc->grouping;
4780         // localization for truename and falsename is not available
4781     }
4782 }
4783 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4784 
4785 // num_get helpers
4786 
4787 int
4788 __num_get_base::__get_base(ios_base& iob)
4789 {
4790     ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4791     if (__basefield == ios_base::oct)
4792         return 8;
4793     else if (__basefield == ios_base::hex)
4794         return 16;
4795     else if (__basefield == 0)
4796         return 0;
4797     return 10;
4798 }
4799 
4800 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4801 
4802 void
4803 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4804                  ios_base::iostate& __err)
4805 {
4806 //  if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4807 //  we always have at least a single entry in [__g, __g_end); the end of the input sequence
4808 	if (__grouping.size() != 0 && __g_end - __g > 1)
4809     {
4810         reverse(__g, __g_end);
4811         const char* __ig = __grouping.data();
4812         const char* __eg = __ig + __grouping.size();
4813         for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4814         {
4815             if (0 < *__ig && *__ig < numeric_limits<char>::max())
4816             {
4817                 if (static_cast<unsigned>(*__ig) != *__r)
4818                 {
4819                     __err = ios_base::failbit;
4820                     return;
4821                 }
4822             }
4823             if (__eg - __ig > 1)
4824                 ++__ig;
4825         }
4826         if (0 < *__ig && *__ig < numeric_limits<char>::max())
4827         {
4828             if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4829                 __err = ios_base::failbit;
4830         }
4831     }
4832 }
4833 
4834 void
4835 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4836                              ios_base::fmtflags __flags)
4837 {
4838     if ((__flags & ios_base::showpos) &&
4839         (__flags & ios_base::basefield) != ios_base::oct &&
4840         (__flags & ios_base::basefield) != ios_base::hex &&
4841 	__signd)
4842         *__fmtp++ = '+';
4843     if (__flags & ios_base::showbase)
4844         *__fmtp++ = '#';
4845     while(*__len)
4846         *__fmtp++ = *__len++;
4847     if ((__flags & ios_base::basefield) == ios_base::oct)
4848         *__fmtp = 'o';
4849     else if ((__flags & ios_base::basefield) == ios_base::hex)
4850     {
4851         if (__flags & ios_base::uppercase)
4852             *__fmtp = 'X';
4853         else
4854             *__fmtp = 'x';
4855     }
4856     else if (__signd)
4857         *__fmtp = 'd';
4858     else
4859         *__fmtp = 'u';
4860 }
4861 
4862 bool
4863 __num_put_base::__format_float(char* __fmtp, const char* __len,
4864                                ios_base::fmtflags __flags)
4865 {
4866     bool specify_precision = true;
4867     if (__flags & ios_base::showpos)
4868         *__fmtp++ = '+';
4869     if (__flags & ios_base::showpoint)
4870         *__fmtp++ = '#';
4871     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4872     bool uppercase = (__flags & ios_base::uppercase) != 0;
4873     if (floatfield == (ios_base::fixed | ios_base::scientific))
4874         specify_precision = false;
4875     else
4876     {
4877         *__fmtp++ = '.';
4878         *__fmtp++ = '*';
4879     }
4880     while(*__len)
4881         *__fmtp++ = *__len++;
4882     if (floatfield == ios_base::fixed)
4883     {
4884         if (uppercase)
4885             *__fmtp = 'F';
4886         else
4887             *__fmtp = 'f';
4888     }
4889     else if (floatfield == ios_base::scientific)
4890     {
4891         if (uppercase)
4892             *__fmtp = 'E';
4893         else
4894             *__fmtp = 'e';
4895     }
4896     else if (floatfield == (ios_base::fixed | ios_base::scientific))
4897     {
4898         if (uppercase)
4899             *__fmtp = 'A';
4900         else
4901             *__fmtp = 'a';
4902     }
4903     else
4904     {
4905         if (uppercase)
4906             *__fmtp = 'G';
4907         else
4908             *__fmtp = 'g';
4909     }
4910     return specify_precision;
4911 }
4912 
4913 char*
4914 __num_put_base::__identify_padding(char* __nb, char* __ne,
4915                                    const ios_base& __iob)
4916 {
4917     switch (__iob.flags() & ios_base::adjustfield)
4918     {
4919     case ios_base::internal:
4920         if (__nb[0] == '-' || __nb[0] == '+')
4921             return __nb+1;
4922         if (__ne - __nb >= 2 && __nb[0] == '0'
4923                             && (__nb[1] == 'x' || __nb[1] == 'X'))
4924             return __nb+2;
4925         break;
4926     case ios_base::left:
4927         return __ne;
4928     case ios_base::right:
4929     default:
4930         break;
4931     }
4932     return __nb;
4933 }
4934 
4935 // time_get
4936 
4937 static
4938 string*
4939 init_weeks()
4940 {
4941     static string weeks[14];
4942     weeks[0]  = "Sunday";
4943     weeks[1]  = "Monday";
4944     weeks[2]  = "Tuesday";
4945     weeks[3]  = "Wednesday";
4946     weeks[4]  = "Thursday";
4947     weeks[5]  = "Friday";
4948     weeks[6]  = "Saturday";
4949     weeks[7]  = "Sun";
4950     weeks[8]  = "Mon";
4951     weeks[9]  = "Tue";
4952     weeks[10] = "Wed";
4953     weeks[11] = "Thu";
4954     weeks[12] = "Fri";
4955     weeks[13] = "Sat";
4956     return weeks;
4957 }
4958 
4959 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4960 static
4961 wstring*
4962 init_wweeks()
4963 {
4964     static wstring weeks[14];
4965     weeks[0]  = L"Sunday";
4966     weeks[1]  = L"Monday";
4967     weeks[2]  = L"Tuesday";
4968     weeks[3]  = L"Wednesday";
4969     weeks[4]  = L"Thursday";
4970     weeks[5]  = L"Friday";
4971     weeks[6]  = L"Saturday";
4972     weeks[7]  = L"Sun";
4973     weeks[8]  = L"Mon";
4974     weeks[9]  = L"Tue";
4975     weeks[10] = L"Wed";
4976     weeks[11] = L"Thu";
4977     weeks[12] = L"Fri";
4978     weeks[13] = L"Sat";
4979     return weeks;
4980 }
4981 #endif
4982 
4983 template <>
4984 const string*
4985 __time_get_c_storage<char>::__weeks() const
4986 {
4987     static const string* weeks = init_weeks();
4988     return weeks;
4989 }
4990 
4991 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4992 template <>
4993 const wstring*
4994 __time_get_c_storage<wchar_t>::__weeks() const
4995 {
4996     static const wstring* weeks = init_wweeks();
4997     return weeks;
4998 }
4999 #endif
5000 
5001 static
5002 string*
5003 init_months()
5004 {
5005     static string months[24];
5006     months[0]  = "January";
5007     months[1]  = "February";
5008     months[2]  = "March";
5009     months[3]  = "April";
5010     months[4]  = "May";
5011     months[5]  = "June";
5012     months[6]  = "July";
5013     months[7]  = "August";
5014     months[8]  = "September";
5015     months[9]  = "October";
5016     months[10] = "November";
5017     months[11] = "December";
5018     months[12] = "Jan";
5019     months[13] = "Feb";
5020     months[14] = "Mar";
5021     months[15] = "Apr";
5022     months[16] = "May";
5023     months[17] = "Jun";
5024     months[18] = "Jul";
5025     months[19] = "Aug";
5026     months[20] = "Sep";
5027     months[21] = "Oct";
5028     months[22] = "Nov";
5029     months[23] = "Dec";
5030     return months;
5031 }
5032 
5033 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5034 static
5035 wstring*
5036 init_wmonths()
5037 {
5038     static wstring months[24];
5039     months[0]  = L"January";
5040     months[1]  = L"February";
5041     months[2]  = L"March";
5042     months[3]  = L"April";
5043     months[4]  = L"May";
5044     months[5]  = L"June";
5045     months[6]  = L"July";
5046     months[7]  = L"August";
5047     months[8]  = L"September";
5048     months[9]  = L"October";
5049     months[10] = L"November";
5050     months[11] = L"December";
5051     months[12] = L"Jan";
5052     months[13] = L"Feb";
5053     months[14] = L"Mar";
5054     months[15] = L"Apr";
5055     months[16] = L"May";
5056     months[17] = L"Jun";
5057     months[18] = L"Jul";
5058     months[19] = L"Aug";
5059     months[20] = L"Sep";
5060     months[21] = L"Oct";
5061     months[22] = L"Nov";
5062     months[23] = L"Dec";
5063     return months;
5064 }
5065 #endif
5066 
5067 template <>
5068 const string*
5069 __time_get_c_storage<char>::__months() const
5070 {
5071     static const string* months = init_months();
5072     return months;
5073 }
5074 
5075 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5076 template <>
5077 const wstring*
5078 __time_get_c_storage<wchar_t>::__months() const
5079 {
5080     static const wstring* months = init_wmonths();
5081     return months;
5082 }
5083 #endif
5084 
5085 static
5086 string*
5087 init_am_pm()
5088 {
5089     static string am_pm[2];
5090     am_pm[0]  = "AM";
5091     am_pm[1]  = "PM";
5092     return am_pm;
5093 }
5094 
5095 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5096 static
5097 wstring*
5098 init_wam_pm()
5099 {
5100     static wstring am_pm[2];
5101     am_pm[0]  = L"AM";
5102     am_pm[1]  = L"PM";
5103     return am_pm;
5104 }
5105 #endif
5106 
5107 template <>
5108 const string*
5109 __time_get_c_storage<char>::__am_pm() const
5110 {
5111     static const string* am_pm = init_am_pm();
5112     return am_pm;
5113 }
5114 
5115 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5116 template <>
5117 const wstring*
5118 __time_get_c_storage<wchar_t>::__am_pm() const
5119 {
5120     static const wstring* am_pm = init_wam_pm();
5121     return am_pm;
5122 }
5123 #endif
5124 
5125 template <>
5126 const string&
5127 __time_get_c_storage<char>::__x() const
5128 {
5129     static string s("%m/%d/%y");
5130     return s;
5131 }
5132 
5133 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5134 template <>
5135 const wstring&
5136 __time_get_c_storage<wchar_t>::__x() const
5137 {
5138     static wstring s(L"%m/%d/%y");
5139     return s;
5140 }
5141 #endif
5142 
5143 template <>
5144 const string&
5145 __time_get_c_storage<char>::__X() const
5146 {
5147     static string s("%H:%M:%S");
5148     return s;
5149 }
5150 
5151 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5152 template <>
5153 const wstring&
5154 __time_get_c_storage<wchar_t>::__X() const
5155 {
5156     static wstring s(L"%H:%M:%S");
5157     return s;
5158 }
5159 #endif
5160 
5161 template <>
5162 const string&
5163 __time_get_c_storage<char>::__c() const
5164 {
5165     static string s("%a %b %d %H:%M:%S %Y");
5166     return s;
5167 }
5168 
5169 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5170 template <>
5171 const wstring&
5172 __time_get_c_storage<wchar_t>::__c() const
5173 {
5174     static wstring s(L"%a %b %d %H:%M:%S %Y");
5175     return s;
5176 }
5177 #endif
5178 
5179 template <>
5180 const string&
5181 __time_get_c_storage<char>::__r() const
5182 {
5183     static string s("%I:%M:%S %p");
5184     return s;
5185 }
5186 
5187 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5188 template <>
5189 const wstring&
5190 __time_get_c_storage<wchar_t>::__r() const
5191 {
5192     static wstring s(L"%I:%M:%S %p");
5193     return s;
5194 }
5195 #endif
5196 
5197 // time_get_byname
5198 
5199 __time_get::__time_get(const char* nm)
5200     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5201 {
5202     if (__loc_ == 0)
5203         __throw_runtime_error("time_get_byname"
5204                             " failed to construct for " + string(nm));
5205 }
5206 
5207 __time_get::__time_get(const string& nm)
5208     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5209 {
5210     if (__loc_ == 0)
5211         __throw_runtime_error("time_get_byname"
5212                             " failed to construct for " + nm);
5213 }
5214 
5215 __time_get::~__time_get()
5216 {
5217     freelocale(__loc_);
5218 }
5219 
5220 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5221 
5222 template <>
5223 string
5224 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
5225 {
5226     tm t = {0};
5227     t.tm_sec = 59;
5228     t.tm_min = 55;
5229     t.tm_hour = 23;
5230     t.tm_mday = 31;
5231     t.tm_mon = 11;
5232     t.tm_year = 161;
5233     t.tm_wday = 6;
5234     t.tm_yday = 364;
5235     t.tm_isdst = -1;
5236     char buf[100];
5237     char f[3] = {0};
5238     f[0] = '%';
5239     f[1] = fmt;
5240     size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
5241     char* bb = buf;
5242     char* be = buf + n;
5243     string result;
5244     while (bb != be)
5245     {
5246         if (ct.is(ctype_base::space, *bb))
5247         {
5248             result.push_back(' ');
5249             for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
5250                 ;
5251             continue;
5252         }
5253         char* w = bb;
5254         ios_base::iostate err = ios_base::goodbit;
5255         ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
5256                                ct, err, false)
5257                                - this->__weeks_;
5258         if (i < 14)
5259         {
5260             result.push_back('%');
5261             if (i < 7)
5262                 result.push_back('A');
5263             else
5264                 result.push_back('a');
5265             bb = w;
5266             continue;
5267         }
5268         w = bb;
5269         i = __scan_keyword(w, be, this->__months_, this->__months_+24,
5270                            ct, err, false)
5271                            - this->__months_;
5272         if (i < 24)
5273         {
5274             result.push_back('%');
5275             if (i < 12)
5276                 result.push_back('B');
5277             else
5278                 result.push_back('b');
5279             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5280                 result.back() = 'm';
5281             bb = w;
5282             continue;
5283         }
5284         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5285         {
5286             w = bb;
5287             i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
5288                                ct, err, false) - this->__am_pm_;
5289             if (i < 2)
5290             {
5291                 result.push_back('%');
5292                 result.push_back('p');
5293                 bb = w;
5294                 continue;
5295             }
5296         }
5297         w = bb;
5298         if (ct.is(ctype_base::digit, *bb))
5299         {
5300             switch(__get_up_to_n_digits(bb, be, err, ct, 4))
5301             {
5302             case 6:
5303                 result.push_back('%');
5304                 result.push_back('w');
5305                 break;
5306             case 7:
5307                 result.push_back('%');
5308                 result.push_back('u');
5309                 break;
5310             case 11:
5311                 result.push_back('%');
5312                 result.push_back('I');
5313                 break;
5314             case 12:
5315                 result.push_back('%');
5316                 result.push_back('m');
5317                 break;
5318             case 23:
5319                 result.push_back('%');
5320                 result.push_back('H');
5321                 break;
5322             case 31:
5323                 result.push_back('%');
5324                 result.push_back('d');
5325                 break;
5326             case 55:
5327                 result.push_back('%');
5328                 result.push_back('M');
5329                 break;
5330             case 59:
5331                 result.push_back('%');
5332                 result.push_back('S');
5333                 break;
5334             case 61:
5335                 result.push_back('%');
5336                 result.push_back('y');
5337                 break;
5338             case 364:
5339                 result.push_back('%');
5340                 result.push_back('j');
5341                 break;
5342             case 2061:
5343                 result.push_back('%');
5344                 result.push_back('Y');
5345                 break;
5346             default:
5347                 for (; w != bb; ++w)
5348                     result.push_back(*w);
5349                 break;
5350             }
5351             continue;
5352         }
5353         if (*bb == '%')
5354         {
5355             result.push_back('%');
5356             result.push_back('%');
5357             ++bb;
5358             continue;
5359         }
5360         result.push_back(*bb);
5361         ++bb;
5362     }
5363     return result;
5364 }
5365 
5366 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5367 
5368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5369 template <>
5370 wstring
5371 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
5372 {
5373     tm t = {0};
5374     t.tm_sec = 59;
5375     t.tm_min = 55;
5376     t.tm_hour = 23;
5377     t.tm_mday = 31;
5378     t.tm_mon = 11;
5379     t.tm_year = 161;
5380     t.tm_wday = 6;
5381     t.tm_yday = 364;
5382     t.tm_isdst = -1;
5383     char buf[100];
5384     char f[3] = {0};
5385     f[0] = '%';
5386     f[1] = fmt;
5387     strftime_l(buf, countof(buf), f, &t, __loc_);
5388     wchar_t wbuf[100];
5389     wchar_t* wbb = wbuf;
5390     mbstate_t mb = {0};
5391     const char* bb = buf;
5392     size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
5393     if (j == size_t(-1))
5394         __throw_runtime_error("locale not supported");
5395     wchar_t* wbe = wbb + j;
5396     wstring result;
5397     while (wbb != wbe)
5398     {
5399         if (ct.is(ctype_base::space, *wbb))
5400         {
5401             result.push_back(L' ');
5402             for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
5403                 ;
5404             continue;
5405         }
5406         wchar_t* w = wbb;
5407         ios_base::iostate err = ios_base::goodbit;
5408         ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
5409                                ct, err, false)
5410                                - this->__weeks_;
5411         if (i < 14)
5412         {
5413             result.push_back(L'%');
5414             if (i < 7)
5415                 result.push_back(L'A');
5416             else
5417                 result.push_back(L'a');
5418             wbb = w;
5419             continue;
5420         }
5421         w = wbb;
5422         i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5423                            ct, err, false)
5424                            - this->__months_;
5425         if (i < 24)
5426         {
5427             result.push_back(L'%');
5428             if (i < 12)
5429                 result.push_back(L'B');
5430             else
5431                 result.push_back(L'b');
5432             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5433                 result.back() = L'm';
5434             wbb = w;
5435             continue;
5436         }
5437         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5438         {
5439             w = wbb;
5440             i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5441                                ct, err, false) - this->__am_pm_;
5442             if (i < 2)
5443             {
5444                 result.push_back(L'%');
5445                 result.push_back(L'p');
5446                 wbb = w;
5447                 continue;
5448             }
5449         }
5450         w = wbb;
5451         if (ct.is(ctype_base::digit, *wbb))
5452         {
5453             switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5454             {
5455             case 6:
5456                 result.push_back(L'%');
5457                 result.push_back(L'w');
5458                 break;
5459             case 7:
5460                 result.push_back(L'%');
5461                 result.push_back(L'u');
5462                 break;
5463             case 11:
5464                 result.push_back(L'%');
5465                 result.push_back(L'I');
5466                 break;
5467             case 12:
5468                 result.push_back(L'%');
5469                 result.push_back(L'm');
5470                 break;
5471             case 23:
5472                 result.push_back(L'%');
5473                 result.push_back(L'H');
5474                 break;
5475             case 31:
5476                 result.push_back(L'%');
5477                 result.push_back(L'd');
5478                 break;
5479             case 55:
5480                 result.push_back(L'%');
5481                 result.push_back(L'M');
5482                 break;
5483             case 59:
5484                 result.push_back(L'%');
5485                 result.push_back(L'S');
5486                 break;
5487             case 61:
5488                 result.push_back(L'%');
5489                 result.push_back(L'y');
5490                 break;
5491             case 364:
5492                 result.push_back(L'%');
5493                 result.push_back(L'j');
5494                 break;
5495             case 2061:
5496                 result.push_back(L'%');
5497                 result.push_back(L'Y');
5498                 break;
5499             default:
5500                 for (; w != wbb; ++w)
5501                     result.push_back(*w);
5502                 break;
5503             }
5504             continue;
5505         }
5506         if (ct.narrow(*wbb, 0) == '%')
5507         {
5508             result.push_back(L'%');
5509             result.push_back(L'%');
5510             ++wbb;
5511             continue;
5512         }
5513         result.push_back(*wbb);
5514         ++wbb;
5515     }
5516     return result;
5517 }
5518 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5519 
5520 template <>
5521 void
5522 __time_get_storage<char>::init(const ctype<char>& ct)
5523 {
5524     tm t = {0};
5525     char buf[100];
5526     // __weeks_
5527     for (int i = 0; i < 7; ++i)
5528     {
5529         t.tm_wday = i;
5530         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5531         __weeks_[i] = buf;
5532         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5533         __weeks_[i+7] = buf;
5534     }
5535     // __months_
5536     for (int i = 0; i < 12; ++i)
5537     {
5538         t.tm_mon = i;
5539         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5540         __months_[i] = buf;
5541         strftime_l(buf, countof(buf), "%b", &t, __loc_);
5542         __months_[i+12] = buf;
5543     }
5544     // __am_pm_
5545     t.tm_hour = 1;
5546     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5547     __am_pm_[0] = buf;
5548     t.tm_hour = 13;
5549     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5550     __am_pm_[1] = buf;
5551     __c_ = __analyze('c', ct);
5552     __r_ = __analyze('r', ct);
5553     __x_ = __analyze('x', ct);
5554     __X_ = __analyze('X', ct);
5555 }
5556 
5557 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5558 template <>
5559 void
5560 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5561 {
5562     tm t = {0};
5563     char buf[100];
5564     wchar_t wbuf[100];
5565     wchar_t* wbe;
5566     mbstate_t mb = {0};
5567     // __weeks_
5568     for (int i = 0; i < 7; ++i)
5569     {
5570         t.tm_wday = i;
5571         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5572         mb = mbstate_t();
5573         const char* bb = buf;
5574         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5575         if (j == size_t(-1) || j == 0)
5576             __throw_runtime_error("locale not supported");
5577         wbe = wbuf + j;
5578         __weeks_[i].assign(wbuf, wbe);
5579         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5580         mb = mbstate_t();
5581         bb = buf;
5582         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5583         if (j == size_t(-1) || j == 0)
5584             __throw_runtime_error("locale not supported");
5585         wbe = wbuf + j;
5586         __weeks_[i+7].assign(wbuf, wbe);
5587     }
5588     // __months_
5589     for (int i = 0; i < 12; ++i)
5590     {
5591         t.tm_mon = i;
5592         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5593         mb = mbstate_t();
5594         const char* bb = buf;
5595         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5596         if (j == size_t(-1) || j == 0)
5597             __throw_runtime_error("locale not supported");
5598         wbe = wbuf + j;
5599         __months_[i].assign(wbuf, wbe);
5600         strftime_l(buf, countof(buf), "%b", &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) || j == 0)
5605             __throw_runtime_error("locale not supported");
5606         wbe = wbuf + j;
5607         __months_[i+12].assign(wbuf, wbe);
5608     }
5609     // __am_pm_
5610     t.tm_hour = 1;
5611     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5612     mb = mbstate_t();
5613     const char* bb = buf;
5614     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5615     if (j == size_t(-1))
5616         __throw_runtime_error("locale not supported");
5617     wbe = wbuf + j;
5618     __am_pm_[0].assign(wbuf, wbe);
5619     t.tm_hour = 13;
5620     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5621     mb = mbstate_t();
5622     bb = buf;
5623     j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5624     if (j == size_t(-1))
5625         __throw_runtime_error("locale not supported");
5626     wbe = wbuf + j;
5627     __am_pm_[1].assign(wbuf, wbe);
5628     __c_ = __analyze('c', ct);
5629     __r_ = __analyze('r', ct);
5630     __x_ = __analyze('x', ct);
5631     __X_ = __analyze('X', ct);
5632 }
5633 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5634 
5635 template <class CharT>
5636 struct _LIBCPP_HIDDEN __time_get_temp
5637     : public ctype_byname<CharT>
5638 {
5639     explicit __time_get_temp(const char* nm)
5640         : ctype_byname<CharT>(nm, 1) {}
5641     explicit __time_get_temp(const string& nm)
5642         : ctype_byname<CharT>(nm, 1) {}
5643 };
5644 
5645 template <>
5646 __time_get_storage<char>::__time_get_storage(const char* __nm)
5647     : __time_get(__nm)
5648 {
5649     const __time_get_temp<char> ct(__nm);
5650     init(ct);
5651 }
5652 
5653 template <>
5654 __time_get_storage<char>::__time_get_storage(const string& __nm)
5655     : __time_get(__nm)
5656 {
5657     const __time_get_temp<char> ct(__nm);
5658     init(ct);
5659 }
5660 
5661 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5662 template <>
5663 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5664     : __time_get(__nm)
5665 {
5666     const __time_get_temp<wchar_t> ct(__nm);
5667     init(ct);
5668 }
5669 
5670 template <>
5671 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5672     : __time_get(__nm)
5673 {
5674     const __time_get_temp<wchar_t> ct(__nm);
5675     init(ct);
5676 }
5677 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5678 
5679 template <>
5680 time_base::dateorder
5681 __time_get_storage<char>::__do_date_order() const
5682 {
5683     unsigned i;
5684     for (i = 0; i < __x_.size(); ++i)
5685         if (__x_[i] == '%')
5686             break;
5687     ++i;
5688     switch (__x_[i])
5689     {
5690     case 'y':
5691     case 'Y':
5692         for (++i; i < __x_.size(); ++i)
5693             if (__x_[i] == '%')
5694                 break;
5695         if (i == __x_.size())
5696             break;
5697         ++i;
5698         switch (__x_[i])
5699         {
5700         case 'm':
5701             for (++i; i < __x_.size(); ++i)
5702                 if (__x_[i] == '%')
5703                     break;
5704             if (i == __x_.size())
5705                 break;
5706             ++i;
5707             if (__x_[i] == 'd')
5708                 return time_base::ymd;
5709             break;
5710         case '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] == 'm')
5718                 return time_base::ydm;
5719             break;
5720         }
5721         break;
5722     case 'm':
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] == 'd')
5730         {
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::mdy;
5739             break;
5740         }
5741         break;
5742     case 'd':
5743         for (++i; i < __x_.size(); ++i)
5744             if (__x_[i] == '%')
5745                 break;
5746         if (i == __x_.size())
5747             break;
5748         ++i;
5749         if (__x_[i] == 'm')
5750         {
5751             for (++i; i < __x_.size(); ++i)
5752                 if (__x_[i] == '%')
5753                     break;
5754             if (i == __x_.size())
5755                 break;
5756             ++i;
5757             if (__x_[i] == 'y' || __x_[i] == 'Y')
5758                 return time_base::dmy;
5759             break;
5760         }
5761         break;
5762     }
5763     return time_base::no_order;
5764 }
5765 
5766 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5767 template <>
5768 time_base::dateorder
5769 __time_get_storage<wchar_t>::__do_date_order() const
5770 {
5771     unsigned i;
5772     for (i = 0; i < __x_.size(); ++i)
5773         if (__x_[i] == L'%')
5774             break;
5775     ++i;
5776     switch (__x_[i])
5777     {
5778     case L'y':
5779     case L'Y':
5780         for (++i; i < __x_.size(); ++i)
5781             if (__x_[i] == L'%')
5782                 break;
5783         if (i == __x_.size())
5784             break;
5785         ++i;
5786         switch (__x_[i])
5787         {
5788         case L'm':
5789             for (++i; i < __x_.size(); ++i)
5790                 if (__x_[i] == L'%')
5791                     break;
5792             if (i == __x_.size())
5793                 break;
5794             ++i;
5795             if (__x_[i] == L'd')
5796                 return time_base::ymd;
5797             break;
5798         case 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'm')
5806                 return time_base::ydm;
5807             break;
5808         }
5809         break;
5810     case L'm':
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'd')
5818         {
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::mdy;
5827             break;
5828         }
5829         break;
5830     case L'd':
5831         for (++i; i < __x_.size(); ++i)
5832             if (__x_[i] == L'%')
5833                 break;
5834         if (i == __x_.size())
5835             break;
5836         ++i;
5837         if (__x_[i] == L'm')
5838         {
5839             for (++i; i < __x_.size(); ++i)
5840                 if (__x_[i] == L'%')
5841                     break;
5842             if (i == __x_.size())
5843                 break;
5844             ++i;
5845             if (__x_[i] == L'y' || __x_[i] == L'Y')
5846                 return time_base::dmy;
5847             break;
5848         }
5849         break;
5850     }
5851     return time_base::no_order;
5852 }
5853 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5854 
5855 // time_put
5856 
5857 __time_put::__time_put(const char* nm)
5858     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5859 {
5860     if (__loc_ == 0)
5861         __throw_runtime_error("time_put_byname"
5862                             " failed to construct for " + string(nm));
5863 }
5864 
5865 __time_put::__time_put(const string& nm)
5866     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5867 {
5868     if (__loc_ == 0)
5869         __throw_runtime_error("time_put_byname"
5870                             " failed to construct for " + nm);
5871 }
5872 
5873 __time_put::~__time_put()
5874 {
5875     if (__loc_ != _LIBCPP_GET_C_LOCALE)
5876         freelocale(__loc_);
5877 }
5878 
5879 void
5880 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5881                      char __fmt, char __mod) const
5882 {
5883     char fmt[] = {'%', __fmt, __mod, 0};
5884     if (__mod != 0)
5885         swap(fmt[1], fmt[2]);
5886     size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5887     __ne = __nb + n;
5888 }
5889 
5890 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5891 void
5892 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5893                      char __fmt, char __mod) const
5894 {
5895     char __nar[100];
5896     char* __ne = __nar + 100;
5897     __do_put(__nar, __ne, __tm, __fmt, __mod);
5898     mbstate_t mb = {0};
5899     const char* __nb = __nar;
5900     size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5901     if (j == size_t(-1))
5902         __throw_runtime_error("locale not supported");
5903     __we = __wb + j;
5904 }
5905 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5906 
5907 // moneypunct_byname
5908 
5909 template <class charT>
5910 static
5911 void
5912 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5913            bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5914            charT space_char)
5915 {
5916     const char sign = static_cast<char>(money_base::sign);
5917     const char space = static_cast<char>(money_base::space);
5918     const char none = static_cast<char>(money_base::none);
5919     const char symbol = static_cast<char>(money_base::symbol);
5920     const char value = static_cast<char>(money_base::value);
5921     const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5922 
5923     // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5924     // function'. "Space between sign and symbol or value" means that
5925     // if the sign is adjacent to the symbol, there's a space between
5926     // them, and otherwise there's a space between the sign and value.
5927     //
5928     // C11's localeconv specifies that the fourth character of an
5929     // international curr_symbol is used to separate the sign and
5930     // value when sep_by_space says to do so. C++ can't represent
5931     // that, so we just use a space.  When sep_by_space says to
5932     // separate the symbol and value-or-sign with a space, we rearrange the
5933     // curr_symbol to put its spacing character on the correct side of
5934     // the symbol.
5935     //
5936     // We also need to avoid adding an extra space between the sign
5937     // and value when the currency symbol is suppressed (by not
5938     // setting showbase).  We match glibc's strfmon by interpreting
5939     // sep_by_space==1 as "omit the space when the currency symbol is
5940     // absent".
5941     //
5942     // Users who want to get this right should use ICU instead.
5943 
5944     switch (cs_precedes)
5945     {
5946     case 0:  // value before curr_symbol
5947         if (symbol_contains_sep) {
5948             // Move the separator to before the symbol, to place it
5949             // between the value and symbol.
5950             rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5951                    __curr_symbol_.end());
5952         }
5953         switch (sign_posn)
5954         {
5955         case 0:  // Parentheses surround the quantity and currency symbol.
5956             pat.field[0] = sign;
5957             pat.field[1] = value;
5958             pat.field[2] = none;  // Any space appears in the symbol.
5959             pat.field[3] = symbol;
5960             switch (sep_by_space)
5961             {
5962             case 0:  // No space separates the currency symbol and value.
5963                 // This case may have changed between C99 and C11;
5964                 // assume the currency symbol matches the intention.
5965             case 2:  // Space between sign and currency or value.
5966                 // The "sign" is two parentheses, so no space here either.
5967                 return;
5968             case 1:  // Space between currency-and-sign or currency and value.
5969                 if (!symbol_contains_sep) {
5970                     // We insert the space into the symbol instead of
5971                     // setting pat.field[2]=space so that when
5972                     // showbase is not set, the space goes away too.
5973                     __curr_symbol_.insert(0, 1, space_char);
5974                 }
5975                 return;
5976             default:
5977                 break;
5978             }
5979             break;
5980         case 1:  // The sign string precedes the quantity and currency symbol.
5981             pat.field[0] = sign;
5982             pat.field[3] = symbol;
5983             switch (sep_by_space)
5984             {
5985             case 0:  // No space separates the currency symbol and value.
5986                 pat.field[1] = value;
5987                 pat.field[2] = none;
5988                 return;
5989             case 1:  // Space between currency-and-sign or currency and value.
5990                 pat.field[1] = value;
5991                 pat.field[2] = none;
5992                 if (!symbol_contains_sep) {
5993                     // We insert the space into the symbol instead of
5994                     // setting pat.field[2]=space so that when
5995                     // showbase is not set, the space goes away too.
5996                     __curr_symbol_.insert(0, 1, space_char);
5997                 }
5998                 return;
5999             case 2:  // Space between sign and currency or value.
6000                 pat.field[1] = space;
6001                 pat.field[2] = value;
6002                 if (symbol_contains_sep) {
6003                     // Remove the separator from the symbol, since it
6004                     // has already appeared after the sign.
6005                     __curr_symbol_.erase(__curr_symbol_.begin());
6006                 }
6007                 return;
6008             default:
6009                 break;
6010             }
6011             break;
6012         case 2:  // The sign string succeeds the quantity and currency symbol.
6013             pat.field[0] = value;
6014             pat.field[3] = sign;
6015             switch (sep_by_space)
6016             {
6017             case 0:  // No space separates the currency symbol and value.
6018                 pat.field[1] = none;
6019                 pat.field[2] = symbol;
6020                 return;
6021             case 1:  // Space between currency-and-sign or currency and value.
6022                 if (!symbol_contains_sep) {
6023                     // We insert the space into the symbol instead of
6024                     // setting pat.field[1]=space so that when
6025                     // showbase is not set, the space goes away too.
6026                     __curr_symbol_.insert(0, 1, space_char);
6027                 }
6028                 pat.field[1] = none;
6029                 pat.field[2] = symbol;
6030                 return;
6031             case 2:  // Space between sign and currency or value.
6032                 pat.field[1] = symbol;
6033                 pat.field[2] = space;
6034                 if (symbol_contains_sep) {
6035                     // Remove the separator from the symbol, since it
6036                     // should not be removed if showbase is absent.
6037                     __curr_symbol_.erase(__curr_symbol_.begin());
6038                 }
6039                 return;
6040             default:
6041                 break;
6042             }
6043             break;
6044         case 3:  // The sign string immediately precedes the currency symbol.
6045             pat.field[0] = value;
6046             pat.field[3] = symbol;
6047             switch (sep_by_space)
6048             {
6049             case 0:  // No space separates the currency symbol and value.
6050                 pat.field[1] = none;
6051                 pat.field[2] = sign;
6052                 return;
6053             case 1:  // Space between currency-and-sign or currency and value.
6054                 pat.field[1] = space;
6055                 pat.field[2] = sign;
6056                 if (symbol_contains_sep) {
6057                     // Remove the separator from the symbol, since it
6058                     // has already appeared before the sign.
6059                     __curr_symbol_.erase(__curr_symbol_.begin());
6060                 }
6061                 return;
6062             case 2:  // Space between sign and currency or value.
6063                 pat.field[1] = sign;
6064                 pat.field[2] = none;
6065                 if (!symbol_contains_sep) {
6066                     // We insert the space into the symbol instead of
6067                     // setting pat.field[2]=space so that when
6068                     // showbase is not set, the space goes away too.
6069                     __curr_symbol_.insert(0, 1, space_char);
6070                 }
6071                 return;
6072             default:
6073                 break;
6074             }
6075             break;
6076         case 4:  // The sign string immediately succeeds the currency symbol.
6077             pat.field[0] = value;
6078             pat.field[3] = sign;
6079             switch (sep_by_space)
6080             {
6081             case 0:  // No space separates the currency symbol and value.
6082                 pat.field[1] = none;
6083                 pat.field[2] = symbol;
6084                 return;
6085             case 1:  // Space between currency-and-sign or currency and value.
6086                 pat.field[1] = none;
6087                 pat.field[2] = symbol;
6088                 if (!symbol_contains_sep) {
6089                     // We insert the space into the symbol instead of
6090                     // setting pat.field[1]=space so that when
6091                     // showbase is not set, the space goes away too.
6092                     __curr_symbol_.insert(0, 1, space_char);
6093                 }
6094                 return;
6095             case 2:  // Space between sign and currency or value.
6096                 pat.field[1] = symbol;
6097                 pat.field[2] = space;
6098                 if (symbol_contains_sep) {
6099                     // Remove the separator from the symbol, since it
6100                     // should not disappear when showbase is absent.
6101                     __curr_symbol_.erase(__curr_symbol_.begin());
6102                 }
6103                 return;
6104             default:
6105                 break;
6106             }
6107             break;
6108         default:
6109             break;
6110         }
6111         break;
6112     case 1:  // curr_symbol before value
6113         switch (sign_posn)
6114         {
6115         case 0:  // Parentheses surround the quantity and currency symbol.
6116             pat.field[0] = sign;
6117             pat.field[1] = symbol;
6118             pat.field[2] = none;  // Any space appears in the symbol.
6119             pat.field[3] = value;
6120             switch (sep_by_space)
6121             {
6122             case 0:  // No space separates the currency symbol and value.
6123                 // This case may have changed between C99 and C11;
6124                 // assume the currency symbol matches the intention.
6125             case 2:  // Space between sign and currency or value.
6126                 // The "sign" is two parentheses, so no space here either.
6127                 return;
6128             case 1:  // Space between currency-and-sign or currency and value.
6129                 if (!symbol_contains_sep) {
6130                     // We insert the space into the symbol instead of
6131                     // setting pat.field[2]=space so that when
6132                     // showbase is not set, the space goes away too.
6133                     __curr_symbol_.insert(0, 1, space_char);
6134                 }
6135                 return;
6136             default:
6137                 break;
6138             }
6139             break;
6140         case 1:  // The sign string precedes the quantity and currency symbol.
6141             pat.field[0] = sign;
6142             pat.field[3] = value;
6143             switch (sep_by_space)
6144             {
6145             case 0:  // No space separates the currency symbol and value.
6146                 pat.field[1] = symbol;
6147                 pat.field[2] = none;
6148                 return;
6149             case 1:  // Space between currency-and-sign or currency and value.
6150                 pat.field[1] = symbol;
6151                 pat.field[2] = none;
6152                 if (!symbol_contains_sep) {
6153                     // We insert the space into the symbol instead of
6154                     // setting pat.field[2]=space so that when
6155                     // showbase is not set, the space goes away too.
6156                     __curr_symbol_.push_back(space_char);
6157                 }
6158                 return;
6159             case 2:  // Space between sign and currency or value.
6160                 pat.field[1] = space;
6161                 pat.field[2] = symbol;
6162                 if (symbol_contains_sep) {
6163                     // Remove the separator from the symbol, since it
6164                     // has already appeared after the sign.
6165                     __curr_symbol_.pop_back();
6166                 }
6167                 return;
6168             default:
6169                 break;
6170             }
6171             break;
6172         case 2:  // The sign string succeeds the quantity and currency symbol.
6173             pat.field[0] = symbol;
6174             pat.field[3] = sign;
6175             switch (sep_by_space)
6176             {
6177             case 0:  // No space separates the currency symbol and value.
6178                 pat.field[1] = none;
6179                 pat.field[2] = value;
6180                 return;
6181             case 1:  // Space between currency-and-sign or currency and value.
6182                 pat.field[1] = none;
6183                 pat.field[2] = value;
6184                 if (!symbol_contains_sep) {
6185                     // We insert the space into the symbol instead of
6186                     // setting pat.field[1]=space so that when
6187                     // showbase is not set, the space goes away too.
6188                     __curr_symbol_.push_back(space_char);
6189                 }
6190                 return;
6191             case 2:  // Space between sign and currency or value.
6192                 pat.field[1] = value;
6193                 pat.field[2] = space;
6194                 if (symbol_contains_sep) {
6195                     // Remove the separator from the symbol, since it
6196                     // will appear before the sign.
6197                     __curr_symbol_.pop_back();
6198                 }
6199                 return;
6200             default:
6201                 break;
6202             }
6203             break;
6204         case 3:  // The sign string immediately precedes the currency symbol.
6205             pat.field[0] = sign;
6206             pat.field[3] = value;
6207             switch (sep_by_space)
6208             {
6209             case 0:  // No space separates the currency symbol and value.
6210                 pat.field[1] = symbol;
6211                 pat.field[2] = none;
6212                 return;
6213             case 1:  // Space between currency-and-sign or currency and value.
6214                 pat.field[1] = symbol;
6215                 pat.field[2] = none;
6216                 if (!symbol_contains_sep) {
6217                     // We insert the space into the symbol instead of
6218                     // setting pat.field[2]=space so that when
6219                     // showbase is not set, the space goes away too.
6220                     __curr_symbol_.push_back(space_char);
6221                 }
6222                 return;
6223             case 2:  // Space between sign and currency or value.
6224                 pat.field[1] = space;
6225                 pat.field[2] = symbol;
6226                 if (symbol_contains_sep) {
6227                     // Remove the separator from the symbol, since it
6228                     // has already appeared after the sign.
6229                     __curr_symbol_.pop_back();
6230                 }
6231                 return;
6232             default:
6233                 break;
6234             }
6235             break;
6236         case 4:  // The sign string immediately succeeds the currency symbol.
6237             pat.field[0] = symbol;
6238             pat.field[3] = value;
6239             switch (sep_by_space)
6240             {
6241             case 0:  // No space separates the currency symbol and value.
6242                 pat.field[1] = sign;
6243                 pat.field[2] = none;
6244                 return;
6245             case 1:  // Space between currency-and-sign or currency and value.
6246                 pat.field[1] = sign;
6247                 pat.field[2] = space;
6248                 if (symbol_contains_sep) {
6249                     // Remove the separator from the symbol, since it
6250                     // should not disappear when showbase is absent.
6251                     __curr_symbol_.pop_back();
6252                 }
6253                 return;
6254             case 2:  // Space between sign and currency or value.
6255                 pat.field[1] = none;
6256                 pat.field[2] = sign;
6257                 if (!symbol_contains_sep) {
6258                     // We insert the space into the symbol instead of
6259                     // setting pat.field[1]=space so that when
6260                     // showbase is not set, the space goes away too.
6261                     __curr_symbol_.push_back(space_char);
6262                 }
6263                 return;
6264            default:
6265                 break;
6266             }
6267             break;
6268         default:
6269             break;
6270         }
6271         break;
6272     default:
6273         break;
6274     }
6275     pat.field[0] = symbol;
6276     pat.field[1] = sign;
6277     pat.field[2] = none;
6278     pat.field[3] = value;
6279 }
6280 
6281 template<>
6282 void
6283 moneypunct_byname<char, false>::init(const char* nm)
6284 {
6285     typedef moneypunct<char, false> base;
6286     __libcpp_unique_locale loc(nm);
6287     if (!loc)
6288         __throw_runtime_error("moneypunct_byname"
6289                             " failed to construct for " + string(nm));
6290 
6291     lconv* lc = __libcpp_localeconv_l(loc.get());
6292     if (!checked_string_to_char_convert(__decimal_point_,
6293                                         lc->mon_decimal_point,
6294                                         loc.get()))
6295       __decimal_point_ = base::do_decimal_point();
6296     if (!checked_string_to_char_convert(__thousands_sep_,
6297                                         lc->mon_thousands_sep,
6298                                         loc.get()))
6299       __thousands_sep_ = base::do_thousands_sep();
6300 
6301     __grouping_ = lc->mon_grouping;
6302     __curr_symbol_ = lc->currency_symbol;
6303     if (lc->frac_digits != CHAR_MAX)
6304         __frac_digits_ = lc->frac_digits;
6305     else
6306         __frac_digits_ = base::do_frac_digits();
6307     if (lc->p_sign_posn == 0)
6308         __positive_sign_ = "()";
6309     else
6310         __positive_sign_ = lc->positive_sign;
6311     if (lc->n_sign_posn == 0)
6312         __negative_sign_ = "()";
6313     else
6314         __negative_sign_ = lc->negative_sign;
6315     // Assume the positive and negative formats will want spaces in
6316     // the same places in curr_symbol since there's no way to
6317     // represent anything else.
6318     string_type __dummy_curr_symbol = __curr_symbol_;
6319     __init_pat(__pos_format_, __dummy_curr_symbol, false,
6320                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6321     __init_pat(__neg_format_, __curr_symbol_, false,
6322                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6323 }
6324 
6325 template<>
6326 void
6327 moneypunct_byname<char, true>::init(const char* nm)
6328 {
6329     typedef moneypunct<char, true> base;
6330     __libcpp_unique_locale loc(nm);
6331     if (!loc)
6332         __throw_runtime_error("moneypunct_byname"
6333                             " failed to construct for " + string(nm));
6334 
6335     lconv* lc = __libcpp_localeconv_l(loc.get());
6336     if (!checked_string_to_char_convert(__decimal_point_,
6337                                         lc->mon_decimal_point,
6338                                         loc.get()))
6339       __decimal_point_ = base::do_decimal_point();
6340     if (!checked_string_to_char_convert(__thousands_sep_,
6341                                         lc->mon_thousands_sep,
6342                                         loc.get()))
6343       __thousands_sep_ = base::do_thousands_sep();
6344     __grouping_ = lc->mon_grouping;
6345     __curr_symbol_ = lc->int_curr_symbol;
6346     if (lc->int_frac_digits != CHAR_MAX)
6347         __frac_digits_ = lc->int_frac_digits;
6348     else
6349         __frac_digits_ = base::do_frac_digits();
6350 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6351     if (lc->p_sign_posn == 0)
6352 #else // _LIBCPP_MSVCRT
6353     if (lc->int_p_sign_posn == 0)
6354 #endif // !_LIBCPP_MSVCRT
6355         __positive_sign_ = "()";
6356     else
6357         __positive_sign_ = lc->positive_sign;
6358 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6359     if(lc->n_sign_posn == 0)
6360 #else // _LIBCPP_MSVCRT
6361     if (lc->int_n_sign_posn == 0)
6362 #endif // !_LIBCPP_MSVCRT
6363         __negative_sign_ = "()";
6364     else
6365         __negative_sign_ = lc->negative_sign;
6366     // Assume the positive and negative formats will want spaces in
6367     // the same places in curr_symbol since there's no way to
6368     // represent anything else.
6369     string_type __dummy_curr_symbol = __curr_symbol_;
6370 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6371     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6372                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6373     __init_pat(__neg_format_, __curr_symbol_, true,
6374                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6375 #else // _LIBCPP_MSVCRT
6376     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6377                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6378                lc->int_p_sign_posn, ' ');
6379     __init_pat(__neg_format_, __curr_symbol_, true,
6380                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6381                lc->int_n_sign_posn, ' ');
6382 #endif // !_LIBCPP_MSVCRT
6383 }
6384 
6385 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6386 template<>
6387 void
6388 moneypunct_byname<wchar_t, false>::init(const char* nm)
6389 {
6390     typedef moneypunct<wchar_t, false> base;
6391     __libcpp_unique_locale loc(nm);
6392     if (!loc)
6393         __throw_runtime_error("moneypunct_byname"
6394                             " failed to construct for " + string(nm));
6395     lconv* lc = __libcpp_localeconv_l(loc.get());
6396     if (!checked_string_to_wchar_convert(__decimal_point_,
6397                                          lc->mon_decimal_point,
6398                                          loc.get()))
6399       __decimal_point_ = base::do_decimal_point();
6400     if (!checked_string_to_wchar_convert(__thousands_sep_,
6401                                          lc->mon_thousands_sep,
6402                                          loc.get()))
6403       __thousands_sep_ = base::do_thousands_sep();
6404     __grouping_ = lc->mon_grouping;
6405     wchar_t wbuf[100];
6406     mbstate_t mb = {0};
6407     const char* bb = lc->currency_symbol;
6408     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6409     if (j == size_t(-1))
6410         __throw_runtime_error("locale not supported");
6411     wchar_t* wbe = wbuf + j;
6412     __curr_symbol_.assign(wbuf, wbe);
6413     if (lc->frac_digits != CHAR_MAX)
6414         __frac_digits_ = lc->frac_digits;
6415     else
6416         __frac_digits_ = base::do_frac_digits();
6417     if (lc->p_sign_posn == 0)
6418         __positive_sign_ = L"()";
6419     else
6420     {
6421         mb = mbstate_t();
6422         bb = lc->positive_sign;
6423         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6424         if (j == size_t(-1))
6425             __throw_runtime_error("locale not supported");
6426         wbe = wbuf + j;
6427         __positive_sign_.assign(wbuf, wbe);
6428     }
6429     if (lc->n_sign_posn == 0)
6430         __negative_sign_ = L"()";
6431     else
6432     {
6433         mb = mbstate_t();
6434         bb = lc->negative_sign;
6435         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6436         if (j == size_t(-1))
6437             __throw_runtime_error("locale not supported");
6438         wbe = wbuf + j;
6439         __negative_sign_.assign(wbuf, wbe);
6440     }
6441     // Assume the positive and negative formats will want spaces in
6442     // the same places in curr_symbol since there's no way to
6443     // represent anything else.
6444     string_type __dummy_curr_symbol = __curr_symbol_;
6445     __init_pat(__pos_format_, __dummy_curr_symbol, false,
6446                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6447     __init_pat(__neg_format_, __curr_symbol_, false,
6448                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6449 }
6450 
6451 template<>
6452 void
6453 moneypunct_byname<wchar_t, true>::init(const char* nm)
6454 {
6455     typedef moneypunct<wchar_t, true> base;
6456     __libcpp_unique_locale loc(nm);
6457     if (!loc)
6458         __throw_runtime_error("moneypunct_byname"
6459                             " failed to construct for " + string(nm));
6460 
6461     lconv* lc = __libcpp_localeconv_l(loc.get());
6462     if (!checked_string_to_wchar_convert(__decimal_point_,
6463                                          lc->mon_decimal_point,
6464                                          loc.get()))
6465       __decimal_point_ = base::do_decimal_point();
6466     if (!checked_string_to_wchar_convert(__thousands_sep_,
6467                                          lc->mon_thousands_sep,
6468                                          loc.get()))
6469       __thousands_sep_ = base::do_thousands_sep();
6470     __grouping_ = lc->mon_grouping;
6471     wchar_t wbuf[100];
6472     mbstate_t mb = {0};
6473     const char* bb = lc->int_curr_symbol;
6474     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6475     if (j == size_t(-1))
6476         __throw_runtime_error("locale not supported");
6477     wchar_t* wbe = wbuf + j;
6478     __curr_symbol_.assign(wbuf, wbe);
6479     if (lc->int_frac_digits != CHAR_MAX)
6480         __frac_digits_ = lc->int_frac_digits;
6481     else
6482         __frac_digits_ = base::do_frac_digits();
6483 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6484     if (lc->p_sign_posn == 0)
6485 #else // _LIBCPP_MSVCRT
6486     if (lc->int_p_sign_posn == 0)
6487 #endif // !_LIBCPP_MSVCRT
6488         __positive_sign_ = L"()";
6489     else
6490     {
6491         mb = mbstate_t();
6492         bb = lc->positive_sign;
6493         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6494         if (j == size_t(-1))
6495             __throw_runtime_error("locale not supported");
6496         wbe = wbuf + j;
6497         __positive_sign_.assign(wbuf, wbe);
6498     }
6499 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6500     if (lc->n_sign_posn == 0)
6501 #else // _LIBCPP_MSVCRT
6502     if (lc->int_n_sign_posn == 0)
6503 #endif // !_LIBCPP_MSVCRT
6504         __negative_sign_ = L"()";
6505     else
6506     {
6507         mb = mbstate_t();
6508         bb = lc->negative_sign;
6509         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6510         if (j == size_t(-1))
6511             __throw_runtime_error("locale not supported");
6512         wbe = wbuf + j;
6513         __negative_sign_.assign(wbuf, wbe);
6514     }
6515     // Assume the positive and negative formats will want spaces in
6516     // the same places in curr_symbol since there's no way to
6517     // represent anything else.
6518     string_type __dummy_curr_symbol = __curr_symbol_;
6519 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6520     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6521                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6522     __init_pat(__neg_format_, __curr_symbol_, true,
6523                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6524 #else // _LIBCPP_MSVCRT
6525     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6526                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6527                lc->int_p_sign_posn, L' ');
6528     __init_pat(__neg_format_, __curr_symbol_, true,
6529                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6530                lc->int_n_sign_posn, L' ');
6531 #endif // !_LIBCPP_MSVCRT
6532 }
6533 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6534 
6535 void __do_nothing(void*) {}
6536 
6537 void __throw_runtime_error(const char* msg)
6538 {
6539 #ifndef _LIBCPP_NO_EXCEPTIONS
6540     throw runtime_error(msg);
6541 #else
6542     (void)msg;
6543     _VSTD::abort();
6544 #endif
6545 }
6546 
6547                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6548 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
6549 
6550                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6551 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
6552 
6553                            template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6554 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
6555 
6556                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6557 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
6558 
6559                            template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6560 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
6561 
6562                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6563 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
6564 
6565                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6566 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
6567 
6568                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6569 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
6570 
6571                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6572 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
6573 
6574                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6575                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6576 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
6577 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
6578 
6579                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6580                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6581 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
6582 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
6583 
6584                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6585 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
6586 
6587                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6588 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)
6589 
6590                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6591 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)
6592 
6593                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6594 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)
6595 
6596                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6597 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
6598 
6599                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6600 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
6601 
6602                            template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6603 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
6604 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6605 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6606 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6607 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
6608 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
6609 #endif
6610 
6611 _LIBCPP_END_NAMESPACE_STD
6612 
6613 _LIBCPP_POP_MACROS
6614