xref: /llvm-project-15.0.7/libcxx/src/locale.cpp (revision 322f633c)
1 //===------------------------- locale.cpp ---------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "string"
11 #include "locale"
12 #include "codecvt"
13 #include "vector"
14 #include "algorithm"
15 #include "algorithm"
16 #include "typeinfo"
17 #include "type_traits"
18 #include "clocale"
19 #include "cstring"
20 #include "cwctype"
21 #include "__sso_allocator"
22 #if _WIN32
23 #include <support/win32/locale_win32.h>
24 #else // _WIN32
25 #include <langinfo.h>
26 #endif // _!WIN32
27 #include <stdlib.h>
28 
29 _LIBCPP_BEGIN_NAMESPACE_STD
30 
31 #ifdef __cloc_defined
32 locale_t __cloc() {
33   // In theory this could create a race condition. In practice
34   // the race condition is non-fatal since it will just create
35   // a little resource leak. Better approach would be appreciated.
36   static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
37   return result;
38 }
39 #endif // __cloc_defined
40 
41 namespace {
42 
43 struct release
44 {
45     void operator()(locale::facet* p) {p->__release_shared();}
46 };
47 
48 template <class T, class A0>
49 inline
50 T&
51 make(A0 a0)
52 {
53     static typename aligned_storage<sizeof(T)>::type buf;
54     ::new (&buf) T(a0);
55     return *(T*)&buf;
56 }
57 
58 template <class T, class A0, class A1>
59 inline
60 T&
61 make(A0 a0, A1 a1)
62 {
63     static typename aligned_storage<sizeof(T)>::type buf;
64     ::new (&buf) T(a0, a1);
65     return *(T*)&buf;
66 }
67 
68 template <class T, class A0, class A1, class A2>
69 inline
70 T&
71 make(A0 a0, A1 a1, A2 a2)
72 {
73     static typename aligned_storage<sizeof(T)>::type buf;
74     ::new (&buf) T(a0, a1, a2);
75     return *(T*)&buf;
76 }
77 
78 }
79 
80 #pragma clang diagnostic push
81 #pragma clang diagnostic ignored "-Wpadded"
82 
83 class _LIBCPP_HIDDEN locale::__imp
84     : public facet
85 {
86     enum {N = 28};
87     vector<facet*, __sso_allocator<facet*, N> > facets_;
88     string         name_;
89 public:
90     explicit __imp(size_t refs = 0);
91     explicit __imp(const string& name, size_t refs = 0);
92     __imp(const __imp&);
93     __imp(const __imp&, const string&, locale::category c);
94     __imp(const __imp& other, const __imp& one, locale::category c);
95     __imp(const __imp&, facet* f, long id);
96     ~__imp();
97 
98     const string& name() const {return name_;}
99     bool has_facet(long id) const
100         {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
101     const locale::facet* use_facet(long id) const;
102 
103     static const locale& make_classic();
104     static       locale& make_global();
105 private:
106     void install(facet* f, long id);
107     template <class F> void install(F* f) {install(f, f->id.__get());}
108     template <class F> void install_from(const __imp& other);
109 };
110 
111 #pragma clang diagnostic pop
112 
113 locale::__imp::__imp(size_t refs)
114     : facet(refs),
115       facets_(N),
116       name_("C")
117 {
118     facets_.clear();
119     install(&make<_VSTD::collate<char> >(1u));
120     install(&make<_VSTD::collate<wchar_t> >(1u));
121     install(&make<_VSTD::ctype<char> >((ctype_base::mask*)0, false, 1u));
122     install(&make<_VSTD::ctype<wchar_t> >(1u));
123     install(&make<codecvt<char, char, mbstate_t> >(1u));
124     install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
125     install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
126     install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
127     install(&make<numpunct<char> >(1u));
128     install(&make<numpunct<wchar_t> >(1u));
129     install(&make<num_get<char> >(1u));
130     install(&make<num_get<wchar_t> >(1u));
131     install(&make<num_put<char> >(1u));
132     install(&make<num_put<wchar_t> >(1u));
133     install(&make<moneypunct<char, false> >(1u));
134     install(&make<moneypunct<char, true> >(1u));
135     install(&make<moneypunct<wchar_t, false> >(1u));
136     install(&make<moneypunct<wchar_t, true> >(1u));
137     install(&make<money_get<char> >(1u));
138     install(&make<money_get<wchar_t> >(1u));
139     install(&make<money_put<char> >(1u));
140     install(&make<money_put<wchar_t> >(1u));
141     install(&make<time_get<char> >(1u));
142     install(&make<time_get<wchar_t> >(1u));
143     install(&make<time_put<char> >(1u));
144     install(&make<time_put<wchar_t> >(1u));
145     install(&make<_VSTD::messages<char> >(1u));
146     install(&make<_VSTD::messages<wchar_t> >(1u));
147 }
148 
149 locale::__imp::__imp(const string& name, size_t refs)
150     : facet(refs),
151       facets_(N),
152       name_(name)
153 {
154 #ifndef _LIBCPP_NO_EXCEPTIONS
155     try
156     {
157 #endif  // _LIBCPP_NO_EXCEPTIONS
158         facets_ = locale::classic().__locale_->facets_;
159         for (unsigned i = 0; i < facets_.size(); ++i)
160             if (facets_[i])
161                 facets_[i]->__add_shared();
162         install(new collate_byname<char>(name_));
163         install(new collate_byname<wchar_t>(name_));
164         install(new ctype_byname<char>(name_));
165         install(new ctype_byname<wchar_t>(name_));
166         install(new codecvt_byname<char, char, mbstate_t>(name_));
167         install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
168         install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
169         install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
170         install(new numpunct_byname<char>(name_));
171         install(new numpunct_byname<wchar_t>(name_));
172         install(new moneypunct_byname<char, false>(name_));
173         install(new moneypunct_byname<char, true>(name_));
174         install(new moneypunct_byname<wchar_t, false>(name_));
175         install(new moneypunct_byname<wchar_t, true>(name_));
176         install(new time_get_byname<char>(name_));
177         install(new time_get_byname<wchar_t>(name_));
178         install(new time_put_byname<char>(name_));
179         install(new time_put_byname<wchar_t>(name_));
180         install(new messages_byname<char>(name_));
181         install(new messages_byname<wchar_t>(name_));
182 #ifndef _LIBCPP_NO_EXCEPTIONS
183     }
184     catch (...)
185     {
186         for (unsigned i = 0; i < facets_.size(); ++i)
187             if (facets_[i])
188                 facets_[i]->__release_shared();
189         throw;
190     }
191 #endif  // _LIBCPP_NO_EXCEPTIONS
192 }
193 
194 locale::__imp::__imp(const __imp& other)
195     : facets_(max<size_t>(N, other.facets_.size())),
196       name_(other.name_)
197 {
198     facets_ = other.facets_;
199     for (unsigned i = 0; i < facets_.size(); ++i)
200         if (facets_[i])
201             facets_[i]->__add_shared();
202 }
203 
204 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
205     : facets_(N),
206       name_("*")
207 {
208     facets_ = other.facets_;
209     for (unsigned i = 0; i < facets_.size(); ++i)
210         if (facets_[i])
211             facets_[i]->__add_shared();
212 #ifndef _LIBCPP_NO_EXCEPTIONS
213     try
214     {
215 #endif  // _LIBCPP_NO_EXCEPTIONS
216         if (c & locale::collate)
217         {
218             install(new collate_byname<char>(name));
219             install(new collate_byname<wchar_t>(name));
220         }
221         if (c & locale::ctype)
222         {
223             install(new ctype_byname<char>(name));
224             install(new ctype_byname<wchar_t>(name));
225             install(new codecvt_byname<char, char, mbstate_t>(name));
226             install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
227             install(new codecvt_byname<char16_t, char, mbstate_t>(name));
228             install(new codecvt_byname<char32_t, char, mbstate_t>(name));
229         }
230         if (c & locale::monetary)
231         {
232             install(new moneypunct_byname<char, false>(name));
233             install(new moneypunct_byname<char, true>(name));
234             install(new moneypunct_byname<wchar_t, false>(name));
235             install(new moneypunct_byname<wchar_t, true>(name));
236         }
237         if (c & locale::numeric)
238         {
239             install(new numpunct_byname<char>(name));
240             install(new numpunct_byname<wchar_t>(name));
241         }
242         if (c & locale::time)
243         {
244             install(new time_get_byname<char>(name));
245             install(new time_get_byname<wchar_t>(name));
246             install(new time_put_byname<char>(name));
247             install(new time_put_byname<wchar_t>(name));
248         }
249         if (c & locale::messages)
250         {
251             install(new messages_byname<char>(name));
252             install(new messages_byname<wchar_t>(name));
253         }
254 #ifndef _LIBCPP_NO_EXCEPTIONS
255     }
256     catch (...)
257     {
258         for (unsigned i = 0; i < facets_.size(); ++i)
259             if (facets_[i])
260                 facets_[i]->__release_shared();
261         throw;
262     }
263 #endif  // _LIBCPP_NO_EXCEPTIONS
264 }
265 
266 template<class F>
267 inline
268 void
269 locale::__imp::install_from(const locale::__imp& one)
270 {
271     long id = F::id.__get();
272     install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
273 }
274 
275 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
276     : facets_(N),
277       name_("*")
278 {
279     facets_ = other.facets_;
280     for (unsigned i = 0; i < facets_.size(); ++i)
281         if (facets_[i])
282             facets_[i]->__add_shared();
283 #ifndef _LIBCPP_NO_EXCEPTIONS
284     try
285     {
286 #endif  // _LIBCPP_NO_EXCEPTIONS
287         if (c & locale::collate)
288         {
289             install_from<_VSTD::collate<char> >(one);
290             install_from<_VSTD::collate<wchar_t> >(one);
291         }
292         if (c & locale::ctype)
293         {
294             install_from<_VSTD::ctype<char> >(one);
295             install_from<_VSTD::ctype<wchar_t> >(one);
296             install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
297             install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
298             install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
299             install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
300         }
301         if (c & locale::monetary)
302         {
303             install_from<moneypunct<char, false> >(one);
304             install_from<moneypunct<char, true> >(one);
305             install_from<moneypunct<wchar_t, false> >(one);
306             install_from<moneypunct<wchar_t, true> >(one);
307             install_from<money_get<char> >(one);
308             install_from<money_get<wchar_t> >(one);
309             install_from<money_put<char> >(one);
310             install_from<money_put<wchar_t> >(one);
311         }
312         if (c & locale::numeric)
313         {
314             install_from<numpunct<char> >(one);
315             install_from<numpunct<wchar_t> >(one);
316             install_from<num_get<char> >(one);
317             install_from<num_get<wchar_t> >(one);
318             install_from<num_put<char> >(one);
319             install_from<num_put<wchar_t> >(one);
320         }
321         if (c & locale::time)
322         {
323             install_from<time_get<char> >(one);
324             install_from<time_get<wchar_t> >(one);
325             install_from<time_put<char> >(one);
326             install_from<time_put<wchar_t> >(one);
327         }
328         if (c & locale::messages)
329         {
330             install_from<_VSTD::messages<char> >(one);
331             install_from<_VSTD::messages<wchar_t> >(one);
332         }
333 #ifndef _LIBCPP_NO_EXCEPTIONS
334     }
335     catch (...)
336     {
337         for (unsigned i = 0; i < facets_.size(); ++i)
338             if (facets_[i])
339                 facets_[i]->__release_shared();
340         throw;
341     }
342 #endif  // _LIBCPP_NO_EXCEPTIONS
343 }
344 
345 locale::__imp::__imp(const __imp& other, facet* f, long id)
346     : facets_(max<size_t>(N, other.facets_.size()+1)),
347       name_("*")
348 {
349     f->__add_shared();
350     unique_ptr<facet, release> hold(f);
351     facets_ = other.facets_;
352     for (unsigned i = 0; i < other.facets_.size(); ++i)
353         if (facets_[i])
354             facets_[i]->__add_shared();
355     install(hold.get(), id);
356 }
357 
358 locale::__imp::~__imp()
359 {
360     for (unsigned i = 0; i < facets_.size(); ++i)
361         if (facets_[i])
362             facets_[i]->__release_shared();
363 }
364 
365 void
366 locale::__imp::install(facet* f, long id)
367 {
368     f->__add_shared();
369     unique_ptr<facet, release> hold(f);
370     if (static_cast<size_t>(id) >= facets_.size())
371         facets_.resize(static_cast<size_t>(id+1));
372     if (facets_[static_cast<size_t>(id)])
373         facets_[static_cast<size_t>(id)]->__release_shared();
374     facets_[static_cast<size_t>(id)] = hold.release();
375 }
376 
377 const locale::facet*
378 locale::__imp::use_facet(long id) const
379 {
380 #ifndef _LIBCPP_NO_EXCEPTIONS
381     if (!has_facet(id))
382         throw bad_cast();
383 #endif  // _LIBCPP_NO_EXCEPTIONS
384     return facets_[static_cast<size_t>(id)];
385 }
386 
387 // locale
388 
389 const locale&
390 locale::__imp::make_classic()
391 {
392     // only one thread can get in here and it only gets in once
393     static aligned_storage<sizeof(locale)>::type buf;
394     locale* c = (locale*)&buf;
395     c->__locale_ = &make<__imp>(1u);
396     return *c;
397 }
398 
399 const locale&
400 locale::classic()
401 {
402     static const locale& c = __imp::make_classic();
403     return c;
404 }
405 
406 locale&
407 locale::__imp::make_global()
408 {
409     // only one thread can get in here and it only gets in once
410     static aligned_storage<sizeof(locale)>::type buf;
411     ::new (&buf) locale(locale::classic());
412     return *(locale*)&buf;
413 }
414 
415 locale&
416 locale::__global()
417 {
418     static locale& g = __imp::make_global();
419     return g;
420 }
421 
422 locale::locale()  _NOEXCEPT
423     : __locale_(__global().__locale_)
424 {
425     __locale_->__add_shared();
426 }
427 
428 locale::locale(const locale& l)  _NOEXCEPT
429     : __locale_(l.__locale_)
430 {
431     __locale_->__add_shared();
432 }
433 
434 locale::~locale()
435 {
436     __locale_->__release_shared();
437 }
438 
439 const locale&
440 locale::operator=(const locale& other)  _NOEXCEPT
441 {
442     other.__locale_->__add_shared();
443     __locale_->__release_shared();
444     __locale_ = other.__locale_;
445     return *this;
446 }
447 
448 locale::locale(const char* name)
449 #ifndef _LIBCPP_NO_EXCEPTIONS
450     : __locale_(name ? new __imp(name)
451                      : throw runtime_error("locale constructed with null"))
452 #else  // _LIBCPP_NO_EXCEPTIONS
453     : __locale_(new __imp(name))
454 #endif
455 {
456     __locale_->__add_shared();
457 }
458 
459 locale::locale(const string& name)
460     : __locale_(new __imp(name))
461 {
462     __locale_->__add_shared();
463 }
464 
465 locale::locale(const locale& other, const char* name, category c)
466 #ifndef _LIBCPP_NO_EXCEPTIONS
467     : __locale_(name ? new __imp(*other.__locale_, name, c)
468                      : throw runtime_error("locale constructed with null"))
469 #else  // _LIBCPP_NO_EXCEPTIONS
470     : __locale_(new __imp(*other.__locale_, name, c))
471 #endif
472 {
473     __locale_->__add_shared();
474 }
475 
476 locale::locale(const locale& other, const string& name, category c)
477     : __locale_(new __imp(*other.__locale_, name, c))
478 {
479     __locale_->__add_shared();
480 }
481 
482 locale::locale(const locale& other, const locale& one, category c)
483     : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
484 {
485     __locale_->__add_shared();
486 }
487 
488 string
489 locale::name() const
490 {
491     return __locale_->name();
492 }
493 
494 void
495 locale::__install_ctor(const locale& other, facet* f, long id)
496 {
497     if (f)
498         __locale_ = new __imp(*other.__locale_, f, id);
499     else
500         __locale_ = other.__locale_;
501     __locale_->__add_shared();
502 }
503 
504 locale
505 locale::global(const locale& loc)
506 {
507     locale& g = __global();
508     locale r = g;
509     g = loc;
510     if (g.name() != "*")
511         setlocale(LC_ALL, g.name().c_str());
512     return r;
513 }
514 
515 bool
516 locale::has_facet(id& x) const
517 {
518     return __locale_->has_facet(x.__get());
519 }
520 
521 const locale::facet*
522 locale::use_facet(id& x) const
523 {
524     return __locale_->use_facet(x.__get());
525 }
526 
527 bool
528 locale::operator==(const locale& y) const
529 {
530     return (__locale_ == y.__locale_)
531         || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
532 }
533 
534 // locale::facet
535 
536 locale::facet::~facet()
537 {
538 }
539 
540 void
541 locale::facet::__on_zero_shared() _NOEXCEPT
542 {
543     delete this;
544 }
545 
546 // locale::id
547 
548 int32_t locale::id::__next_id = 0;
549 
550 namespace
551 {
552 
553 class __fake_bind
554 {
555     locale::id* id_;
556     void (locale::id::* pmf_)();
557 public:
558     __fake_bind(void (locale::id::* pmf)(), locale::id* id)
559         : id_(id), pmf_(pmf) {}
560 
561     void operator()() const
562     {
563         (id_->*pmf_)();
564     }
565 };
566 
567 }
568 
569 long
570 locale::id::__get()
571 {
572     call_once(__flag_, __fake_bind(&locale::id::__init, this));
573     return __id_ - 1;
574 }
575 
576 void
577 locale::id::__init()
578 {
579     __id_ = __sync_add_and_fetch(&__next_id, 1);
580 }
581 
582 // template <> class collate_byname<char>
583 
584 collate_byname<char>::collate_byname(const char* n, size_t refs)
585     : collate<char>(refs),
586       __l(newlocale(LC_ALL_MASK, n, 0))
587 {
588 #ifndef _LIBCPP_NO_EXCEPTIONS
589     if (__l == 0)
590         throw runtime_error("collate_byname<char>::collate_byname"
591                             " failed to construct for " + string(n));
592 #endif  // _LIBCPP_NO_EXCEPTIONS
593 }
594 
595 collate_byname<char>::collate_byname(const string& name, size_t refs)
596     : collate<char>(refs),
597       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
598 {
599 #ifndef _LIBCPP_NO_EXCEPTIONS
600     if (__l == 0)
601         throw runtime_error("collate_byname<char>::collate_byname"
602                             " failed to construct for " + name);
603 #endif  // _LIBCPP_NO_EXCEPTIONS
604 }
605 
606 collate_byname<char>::~collate_byname()
607 {
608     freelocale(__l);
609 }
610 
611 int
612 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
613                                  const char_type* __lo2, const char_type* __hi2) const
614 {
615     string_type lhs(__lo1, __hi1);
616     string_type rhs(__lo2, __hi2);
617     int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
618     if (r < 0)
619         return -1;
620     if (r > 0)
621         return 1;
622     return r;
623 }
624 
625 collate_byname<char>::string_type
626 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
627 {
628     const string_type in(lo, hi);
629     string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
630     strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
631     return out;
632 }
633 
634 // template <> class collate_byname<wchar_t>
635 
636 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
637     : collate<wchar_t>(refs),
638       __l(newlocale(LC_ALL_MASK, n, 0))
639 {
640 #ifndef _LIBCPP_NO_EXCEPTIONS
641     if (__l == 0)
642         throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
643                             " failed to construct for " + string(n));
644 #endif  // _LIBCPP_NO_EXCEPTIONS
645 }
646 
647 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
648     : collate<wchar_t>(refs),
649       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
650 {
651 #ifndef _LIBCPP_NO_EXCEPTIONS
652     if (__l == 0)
653         throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
654                             " failed to construct for " + name);
655 #endif  // _LIBCPP_NO_EXCEPTIONS
656 }
657 
658 collate_byname<wchar_t>::~collate_byname()
659 {
660     freelocale(__l);
661 }
662 
663 int
664 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
665                                  const char_type* __lo2, const char_type* __hi2) const
666 {
667     string_type lhs(__lo1, __hi1);
668     string_type rhs(__lo2, __hi2);
669     int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
670     if (r < 0)
671         return -1;
672     if (r > 0)
673         return 1;
674     return r;
675 }
676 
677 collate_byname<wchar_t>::string_type
678 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
679 {
680     const string_type in(lo, hi);
681     string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
682     wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
683     return out;
684 }
685 
686 // template <> class ctype<wchar_t>;
687 
688 locale::id ctype<wchar_t>::id;
689 
690 ctype<wchar_t>::~ctype()
691 {
692 }
693 
694 bool
695 ctype<wchar_t>::do_is(mask m, char_type c) const
696 {
697     return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
698 }
699 
700 const wchar_t*
701 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
702 {
703     for (; low != high; ++low, ++vec)
704         *vec = static_cast<mask>(isascii(*low) ?
705                                    ctype<char>::classic_table()[*low] : 0);
706     return low;
707 }
708 
709 const wchar_t*
710 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
711 {
712     for (; low != high; ++low)
713         if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
714             break;
715     return low;
716 }
717 
718 const wchar_t*
719 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
720 {
721     for (; low != high; ++low)
722         if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
723             break;
724     return low;
725 }
726 
727 wchar_t
728 ctype<wchar_t>::do_toupper(char_type c) const
729 {
730 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
731     return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
732 #elif defined(__GLIBC__)
733     return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
734 #else
735     return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
736 #endif
737 }
738 
739 const wchar_t*
740 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
741 {
742     for (; low != high; ++low)
743 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
744         *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
745 #elif defined(__GLIBC__)
746         *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
747                              : *low;
748 #else
749         *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
750 #endif
751     return low;
752 }
753 
754 wchar_t
755 ctype<wchar_t>::do_tolower(char_type c) const
756 {
757 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
758     return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
759 #elif defined(__GLIBC__)
760     return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
761 #else
762     return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
763 #endif
764 }
765 
766 const wchar_t*
767 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
768 {
769     for (; low != high; ++low)
770 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
771         *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
772 #elif defined(__GLIBC__)
773         *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
774                              : *low;
775 #else
776         *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
777 #endif
778     return low;
779 }
780 
781 wchar_t
782 ctype<wchar_t>::do_widen(char c) const
783 {
784     return c;
785 }
786 
787 const char*
788 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
789 {
790     for (; low != high; ++low, ++dest)
791         *dest = *low;
792     return low;
793 }
794 
795 char
796 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
797 {
798     if (isascii(c))
799         return static_cast<char>(c);
800     return dfault;
801 }
802 
803 const wchar_t*
804 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
805 {
806     for (; low != high; ++low, ++dest)
807         if (isascii(*low))
808             *dest = static_cast<char>(*low);
809         else
810             *dest = dfault;
811     return low;
812 }
813 
814 // template <> class ctype<char>;
815 
816 locale::id ctype<char>::id;
817 
818 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
819     : locale::facet(refs),
820       __tab_(tab),
821       __del_(del)
822 {
823   if (__tab_ == 0)
824       __tab_ = classic_table();
825 }
826 
827 ctype<char>::~ctype()
828 {
829     if (__tab_ && __del_)
830         delete [] __tab_;
831 }
832 
833 char
834 ctype<char>::do_toupper(char_type c) const
835 {
836 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
837     return isascii(c) ?
838       static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
839 #elif defined(__GLIBC__)
840     return isascii(c) ? __classic_upper_table()[c] : c;
841 #else
842     return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
843 #endif
844 }
845 
846 const char*
847 ctype<char>::do_toupper(char_type* low, const char_type* high) const
848 {
849     for (; low != high; ++low)
850 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
851         *low = isascii(*low) ?
852           static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
853 #elif defined(__GLIBC__)
854         *low = isascii(*low) ? __classic_upper_table()[*low] : *low;
855 #else
856         *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
857 #endif
858     return low;
859 }
860 
861 char
862 ctype<char>::do_tolower(char_type c) const
863 {
864 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
865     return isascii(c) ?
866       static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
867 #elif defined(__GLIBC__)
868     return isascii(c) ? __classic_lower_table()[c] : c;
869 #else
870     return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
871 #endif
872 }
873 
874 const char*
875 ctype<char>::do_tolower(char_type* low, const char_type* high) const
876 {
877     for (; low != high; ++low)
878 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
879         *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
880 #elif defined(__GLIBC__)
881         *low = isascii(*low) ? __classic_lower_table()[*low] : *low;
882 #else
883         *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
884 #endif
885     return low;
886 }
887 
888 char
889 ctype<char>::do_widen(char c) const
890 {
891     return c;
892 }
893 
894 const char*
895 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
896 {
897     for (; low != high; ++low, ++dest)
898         *dest = *low;
899     return low;
900 }
901 
902 char
903 ctype<char>::do_narrow(char_type c, char dfault) const
904 {
905     if (isascii(c))
906         return static_cast<char>(c);
907     return dfault;
908 }
909 
910 const char*
911 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
912 {
913     for (; low != high; ++low, ++dest)
914         if (isascii(*low))
915             *dest = *low;
916         else
917             *dest = dfault;
918     return low;
919 }
920 
921 const ctype<char>::mask*
922 ctype<char>::classic_table()  _NOEXCEPT
923 {
924 #if defined(__APPLE__) || defined(__FreeBSD__)
925     return _DefaultRuneLocale.__runetype;
926 #elif defined(__GLIBC__)
927     return __cloc()->__ctype_b;
928 #elif _WIN32
929     return _ctype+1; // internal ctype mask table defined in msvcrt.dll
930 // This is assumed to be safe, which is a nonsense assumption because we're
931 // going to end up dereferencing it later...
932 #else
933     return NULL;
934 #endif
935 }
936 
937 #if defined(__GLIBC__)
938 const int*
939 ctype<char>::__classic_lower_table() _NOEXCEPT
940 {
941     return __cloc()->__ctype_tolower;
942 }
943 
944 const int*
945 ctype<char>::__classic_upper_table() _NOEXCEPT
946 {
947     return __cloc()->__ctype_toupper;
948 }
949 #endif // __GLIBC__
950 
951 // template <> class ctype_byname<char>
952 
953 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
954     : ctype<char>(0, false, refs),
955       __l(newlocale(LC_ALL_MASK, name, 0))
956 {
957 #ifndef _LIBCPP_NO_EXCEPTIONS
958     if (__l == 0)
959         throw runtime_error("ctype_byname<char>::ctype_byname"
960                             " failed to construct for " + string(name));
961 #endif  // _LIBCPP_NO_EXCEPTIONS
962 }
963 
964 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
965     : ctype<char>(0, false, refs),
966       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
967 {
968 #ifndef _LIBCPP_NO_EXCEPTIONS
969     if (__l == 0)
970         throw runtime_error("ctype_byname<char>::ctype_byname"
971                             " failed to construct for " + name);
972 #endif  // _LIBCPP_NO_EXCEPTIONS
973 }
974 
975 ctype_byname<char>::~ctype_byname()
976 {
977     freelocale(__l);
978 }
979 
980 char
981 ctype_byname<char>::do_toupper(char_type c) const
982 {
983     return static_cast<char>(toupper_l(c, __l));
984 }
985 
986 const char*
987 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
988 {
989     for (; low != high; ++low)
990         *low = static_cast<char>(toupper_l(*low, __l));
991     return low;
992 }
993 
994 char
995 ctype_byname<char>::do_tolower(char_type c) const
996 {
997     return static_cast<char>(tolower_l(c, __l));
998 }
999 
1000 const char*
1001 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1002 {
1003     for (; low != high; ++low)
1004         *low = static_cast<char>(tolower_l(*low, __l));
1005     return low;
1006 }
1007 
1008 // template <> class ctype_byname<wchar_t>
1009 
1010 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1011     : ctype<wchar_t>(refs),
1012       __l(newlocale(LC_ALL_MASK, name, 0))
1013 {
1014 #ifndef _LIBCPP_NO_EXCEPTIONS
1015     if (__l == 0)
1016         throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1017                             " failed to construct for " + string(name));
1018 #endif  // _LIBCPP_NO_EXCEPTIONS
1019 }
1020 
1021 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1022     : ctype<wchar_t>(refs),
1023       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1024 {
1025 #ifndef _LIBCPP_NO_EXCEPTIONS
1026     if (__l == 0)
1027         throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
1028                             " failed to construct for " + name);
1029 #endif  // _LIBCPP_NO_EXCEPTIONS
1030 }
1031 
1032 ctype_byname<wchar_t>::~ctype_byname()
1033 {
1034     freelocale(__l);
1035 }
1036 
1037 bool
1038 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1039 {
1040 #ifdef _LIBCPP_WCTYPE_IS_MASK
1041     return static_cast<bool>(iswctype_l(c, m, __l));
1042 #else
1043     bool result = true;
1044     if (m & space && !iswspace_l(c, __l)) result = false;
1045     if (m & print && !iswprint_l(c, __l)) result = false;
1046     if (m & cntrl && !iswcntrl_l(c, __l)) result = false;
1047     if (m & upper && !iswupper_l(c, __l)) result = false;
1048     if (m & lower && !iswlower_l(c, __l)) result = false;
1049     if (m & alpha && !iswalpha_l(c, __l)) result = false;
1050     if (m & digit && !iswdigit_l(c, __l)) result = false;
1051     if (m & punct && !iswpunct_l(c, __l)) result = false;
1052     if (m & xdigit && !iswxdigit_l(c, __l)) result = false;
1053     if (m & blank && !iswblank_l(c, __l)) result = false;
1054     return result;
1055 #endif
1056 }
1057 
1058 const wchar_t*
1059 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1060 {
1061     for (; low != high; ++low, ++vec)
1062     {
1063         if (isascii(*low))
1064             *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1065         else
1066         {
1067             *vec = 0;
1068             if (iswspace_l(*low, __l))
1069                 *vec |= space;
1070             if (iswprint_l(*low, __l))
1071                 *vec |= print;
1072             if (iswcntrl_l(*low, __l))
1073                 *vec |= cntrl;
1074             if (iswupper_l(*low, __l))
1075                 *vec |= upper;
1076             if (iswlower_l(*low, __l))
1077                 *vec |= lower;
1078             if (iswalpha_l(*low, __l))
1079                 *vec |= alpha;
1080             if (iswdigit_l(*low, __l))
1081                 *vec |= digit;
1082             if (iswpunct_l(*low, __l))
1083                 *vec |= punct;
1084             if (iswxdigit_l(*low, __l))
1085                 *vec |= xdigit;
1086         }
1087     }
1088     return low;
1089 }
1090 
1091 const wchar_t*
1092 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1093 {
1094     for (; low != high; ++low)
1095     {
1096 #ifdef _LIBCPP_WCTYPE_IS_MASK
1097         if (iswctype_l(*low, m, __l))
1098             break;
1099 #else
1100         if (m & space && !iswspace_l(*low, __l)) continue;
1101         if (m & print && !iswprint_l(*low, __l)) continue;
1102         if (m & cntrl && !iswcntrl_l(*low, __l)) continue;
1103         if (m & upper && !iswupper_l(*low, __l)) continue;
1104         if (m & lower && !iswlower_l(*low, __l)) continue;
1105         if (m & alpha && !iswalpha_l(*low, __l)) continue;
1106         if (m & digit && !iswdigit_l(*low, __l)) continue;
1107         if (m & punct && !iswpunct_l(*low, __l)) continue;
1108         if (m & xdigit && !iswxdigit_l(*low, __l)) continue;
1109         if (m & blank && !iswblank_l(*low, __l)) continue;
1110         break;
1111 #endif
1112     }
1113     return low;
1114 }
1115 
1116 const wchar_t*
1117 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1118 {
1119     for (; low != high; ++low)
1120     {
1121 #ifdef _LIBCPP_WCTYPE_IS_MASK
1122         if (!iswctype_l(*low, m, __l))
1123             break;
1124 #else
1125         if (m & space && iswspace_l(*low, __l)) continue;
1126         if (m & print && iswprint_l(*low, __l)) continue;
1127         if (m & cntrl && iswcntrl_l(*low, __l)) continue;
1128         if (m & upper && iswupper_l(*low, __l)) continue;
1129         if (m & lower && iswlower_l(*low, __l)) continue;
1130         if (m & alpha && iswalpha_l(*low, __l)) continue;
1131         if (m & digit && iswdigit_l(*low, __l)) continue;
1132         if (m & punct && iswpunct_l(*low, __l)) continue;
1133         if (m & xdigit && iswxdigit_l(*low, __l)) continue;
1134         if (m & blank && iswblank_l(*low, __l)) continue;
1135         break;
1136 #endif
1137     }
1138     return low;
1139 }
1140 
1141 wchar_t
1142 ctype_byname<wchar_t>::do_toupper(char_type c) const
1143 {
1144     return towupper_l(c, __l);
1145 }
1146 
1147 const wchar_t*
1148 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1149 {
1150     for (; low != high; ++low)
1151         *low = towupper_l(*low, __l);
1152     return low;
1153 }
1154 
1155 wchar_t
1156 ctype_byname<wchar_t>::do_tolower(char_type c) const
1157 {
1158     return towlower_l(c, __l);
1159 }
1160 
1161 const wchar_t*
1162 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1163 {
1164     for (; low != high; ++low)
1165         *low = towlower_l(*low, __l);
1166     return low;
1167 }
1168 
1169 wchar_t
1170 ctype_byname<wchar_t>::do_widen(char c) const
1171 {
1172 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1173     return btowc_l(c, __l);
1174 #else
1175     return __btowc_l(c, __l);
1176 #endif
1177 }
1178 
1179 const char*
1180 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1181 {
1182     for (; low != high; ++low, ++dest)
1183 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1184         *dest = btowc_l(*low, __l);
1185 #else
1186         *dest = __btowc_l(*low, __l);
1187 #endif
1188     return low;
1189 }
1190 
1191 char
1192 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1193 {
1194 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1195     int r = wctob_l(c, __l);
1196 #else
1197     int r = __wctob_l(c, __l);
1198 #endif
1199     return r != WEOF ? static_cast<char>(r) : dfault;
1200 }
1201 
1202 const wchar_t*
1203 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1204 {
1205     for (; low != high; ++low, ++dest)
1206     {
1207 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1208         int r = wctob_l(*low, __l);
1209 #else
1210         int r = __wctob_l(*low, __l);
1211 #endif
1212         *dest = r != WEOF ? static_cast<char>(r) : dfault;
1213     }
1214     return low;
1215 }
1216 
1217 // template <> class codecvt<char, char, mbstate_t>
1218 
1219 locale::id codecvt<char, char, mbstate_t>::id;
1220 
1221 codecvt<char, char, mbstate_t>::~codecvt()
1222 {
1223 }
1224 
1225 codecvt<char, char, mbstate_t>::result
1226 codecvt<char, char, mbstate_t>::do_out(state_type&,
1227     const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1228     extern_type* to, extern_type*, extern_type*& to_nxt) const
1229 {
1230     frm_nxt = frm;
1231     to_nxt = to;
1232     return noconv;
1233 }
1234 
1235 codecvt<char, char, mbstate_t>::result
1236 codecvt<char, char, mbstate_t>::do_in(state_type&,
1237     const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1238     intern_type* to, intern_type*, intern_type*& to_nxt) const
1239 {
1240     frm_nxt = frm;
1241     to_nxt = to;
1242     return noconv;
1243 }
1244 
1245 codecvt<char, char, mbstate_t>::result
1246 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1247     extern_type* to, extern_type*, extern_type*& to_nxt) const
1248 {
1249     to_nxt = to;
1250     return noconv;
1251 }
1252 
1253 int
1254 codecvt<char, char, mbstate_t>::do_encoding() const  _NOEXCEPT
1255 {
1256     return 1;
1257 }
1258 
1259 bool
1260 codecvt<char, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
1261 {
1262     return true;
1263 }
1264 
1265 int
1266 codecvt<char, char, mbstate_t>::do_length(state_type&,
1267     const extern_type* frm, const extern_type* end, size_t mx) const
1268 {
1269     return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1270 }
1271 
1272 int
1273 codecvt<char, char, mbstate_t>::do_max_length() const  _NOEXCEPT
1274 {
1275     return 1;
1276 }
1277 
1278 // template <> class codecvt<wchar_t, char, mbstate_t>
1279 
1280 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1281 
1282 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1283     : locale::facet(refs),
1284       __l(0)
1285 {
1286 }
1287 
1288 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1289     : locale::facet(refs),
1290       __l(newlocale(LC_ALL_MASK, nm, 0))
1291 {
1292 #ifndef _LIBCPP_NO_EXCEPTIONS
1293     if (__l == 0)
1294         throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1295                             " failed to construct for " + string(nm));
1296 #endif  // _LIBCPP_NO_EXCEPTIONS
1297 }
1298 
1299 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1300 {
1301     if (__l != 0)
1302         freelocale(__l);
1303 }
1304 
1305 codecvt<wchar_t, char, mbstate_t>::result
1306 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1307     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1308     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1309 {
1310     // look for first internal null in frm
1311     const intern_type* fend = frm;
1312     for (; fend != frm_end; ++fend)
1313         if (*fend == 0)
1314             break;
1315     // loop over all null-terminated sequences in frm
1316     to_nxt = to;
1317     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1318     {
1319         // save state in case needed to reover to_nxt on error
1320         mbstate_t save_state = st;
1321 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1322         size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1323                                 static_cast<size_t>(to_end-to), &st, __l);
1324 #else
1325         size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1326 #endif
1327         if (n == size_t(-1))
1328         {
1329             // need to recover to_nxt
1330             for (to_nxt = to; frm != frm_nxt; ++frm)
1331             {
1332 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1333                 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1334 #else
1335                 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1336 #endif
1337                 if (n == size_t(-1))
1338                     break;
1339                 to_nxt += n;
1340             }
1341             frm_nxt = frm;
1342             return error;
1343         }
1344         if (n == 0)
1345             return partial;
1346         to_nxt += n;
1347         if (to_nxt == to_end)
1348             break;
1349         if (fend != frm_end)  // set up next null terminated sequence
1350         {
1351             // Try to write the terminating null
1352             extern_type tmp[MB_LEN_MAX];
1353 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1354             n = wcrtomb_l(tmp, intern_type(), &st, __l);
1355 #else
1356             n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1357 #endif
1358             if (n == size_t(-1))  // on error
1359                 return error;
1360             if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
1361                 return partial;
1362             for (extern_type* p = tmp; n; --n)  // write it
1363                 *to_nxt++ = *p++;
1364             ++frm_nxt;
1365             // look for next null in frm
1366             for (fend = frm_nxt; fend != frm_end; ++fend)
1367                 if (*fend == 0)
1368                     break;
1369         }
1370     }
1371     return frm_nxt == frm_end ? ok : partial;
1372 }
1373 
1374 codecvt<wchar_t, char, mbstate_t>::result
1375 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1376     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1377     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1378 {
1379     // look for first internal null in frm
1380     const extern_type* fend = frm;
1381     for (; fend != frm_end; ++fend)
1382         if (*fend == 0)
1383             break;
1384     // loop over all null-terminated sequences in frm
1385     to_nxt = to;
1386     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1387     {
1388         // save state in case needed to reover to_nxt on error
1389         mbstate_t save_state = st;
1390 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1391         size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1392                                 static_cast<size_t>(to_end-to), &st, __l);
1393 #else
1394         size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1395 #endif
1396         if (n == size_t(-1))
1397         {
1398             // need to recover to_nxt
1399             for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1400             {
1401 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1402                 n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1403                               &save_state, __l);
1404 #else
1405                 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1406 #endif
1407                 switch (n)
1408                 {
1409                 case 0:
1410                     ++frm;
1411                     break;
1412                 case -1:
1413                     frm_nxt = frm;
1414                     return error;
1415                 case -2:
1416                     frm_nxt = frm;
1417                     return partial;
1418                 default:
1419                     frm += n;
1420                     break;
1421                 }
1422             }
1423             frm_nxt = frm;
1424             return frm_nxt == frm_end ? ok : partial;
1425         }
1426         if (n == 0)
1427             return error;
1428         to_nxt += n;
1429         if (to_nxt == to_end)
1430             break;
1431         if (fend != frm_end)  // set up next null terminated sequence
1432         {
1433             // Try to write the terminating null
1434 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1435             n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1436 #else
1437             n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1438 #endif
1439             if (n != 0)  // on error
1440                 return error;
1441             ++to_nxt;
1442             ++frm_nxt;
1443             // look for next null in frm
1444             for (fend = frm_nxt; fend != frm_end; ++fend)
1445                 if (*fend == 0)
1446                     break;
1447         }
1448     }
1449     return frm_nxt == frm_end ? ok : partial;
1450 }
1451 
1452 codecvt<wchar_t, char, mbstate_t>::result
1453 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1454     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1455 {
1456     to_nxt = to;
1457     extern_type tmp[MB_LEN_MAX];
1458 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1459     size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1460 #else
1461     size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1462 #endif
1463     if (n == size_t(-1) || n == 0)  // on error
1464         return error;
1465     --n;
1466     if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
1467         return partial;
1468     for (extern_type* p = tmp; n; --n)  // write it
1469         *to_nxt++ = *p++;
1470     return ok;
1471 }
1472 
1473 int
1474 codecvt<wchar_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
1475 {
1476 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1477     if (mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1478 #else
1479     if (__mbtowc_l((wchar_t*) 0, (const char*) 0, MB_LEN_MAX, __l) == 0)
1480 #endif
1481     {
1482         // stateless encoding
1483 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1484         if (__l == 0 || MB_CUR_MAX_L(__l) == 1)  // there are no known constant length encodings
1485 #else
1486         if (__l == 0 || __mb_cur_max_l(__l) == 1)  // there are no known constant length encodings
1487 #endif
1488             return 1;                // which take more than 1 char to form a wchar_t
1489          return 0;
1490     }
1491     return -1;
1492 }
1493 
1494 bool
1495 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
1496 {
1497     return false;
1498 }
1499 
1500 int
1501 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1502     const extern_type* frm, const extern_type* frm_end, size_t mx) const
1503 {
1504     int nbytes = 0;
1505     for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1506     {
1507 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1508         size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1509 #else
1510         size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1511 #endif
1512         switch (n)
1513         {
1514         case 0:
1515             ++nbytes;
1516             ++frm;
1517             break;
1518         case -1:
1519         case -2:
1520             return nbytes;
1521         default:
1522             nbytes += n;
1523             frm += n;
1524             break;
1525         }
1526     }
1527     return nbytes;
1528 }
1529 
1530 int
1531 codecvt<wchar_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
1532 {
1533 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1534     return __l == 0 ? 1 : MB_CUR_MAX_L(__l);
1535 #else
1536     return __l == 0 ? 1 : __mb_cur_max_l(__l);
1537 #endif
1538 }
1539 
1540 //                                     Valid UTF ranges
1541 //     UTF-32               UTF-16                          UTF-8               # of code points
1542 //                     first      second       first   second    third   fourth
1543 // 000000 - 00007F  0000 - 007F               00 - 7F                                 127
1544 // 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920
1545 // 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048
1546 // 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152
1547 // 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048
1548 // 00D800 - 00DFFF                invalid
1549 // 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192
1550 // 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608
1551 // 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432
1552 // 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536
1553 
1554 static
1555 codecvt_base::result
1556 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1557               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1558               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1559 {
1560     frm_nxt = frm;
1561     to_nxt = to;
1562     if (mode & generate_header)
1563     {
1564         if (to_end-to_nxt < 3)
1565             return codecvt_base::partial;
1566         *to_nxt++ = static_cast<uint8_t>(0xEF);
1567         *to_nxt++ = static_cast<uint8_t>(0xBB);
1568         *to_nxt++ = static_cast<uint8_t>(0xBF);
1569     }
1570     for (; frm_nxt < frm_end; ++frm_nxt)
1571     {
1572         uint16_t wc1 = *frm_nxt;
1573         if (wc1 > Maxcode)
1574             return codecvt_base::error;
1575         if (wc1 < 0x0080)
1576         {
1577             if (to_end-to_nxt < 1)
1578                 return codecvt_base::partial;
1579             *to_nxt++ = static_cast<uint8_t>(wc1);
1580         }
1581         else if (wc1 < 0x0800)
1582         {
1583             if (to_end-to_nxt < 2)
1584                 return codecvt_base::partial;
1585             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1586             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1587         }
1588         else if (wc1 < 0xD800)
1589         {
1590             if (to_end-to_nxt < 3)
1591                 return codecvt_base::partial;
1592             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1593             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1594             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1595         }
1596         else if (wc1 < 0xDC00)
1597         {
1598             if (frm_end-frm_nxt < 2)
1599                 return codecvt_base::partial;
1600             uint16_t wc2 = frm_nxt[1];
1601             if ((wc2 & 0xFC00) != 0xDC00)
1602                 return codecvt_base::error;
1603             if (to_end-to_nxt < 4)
1604                 return codecvt_base::partial;
1605             if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1606                 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1607                 return codecvt_base::error;
1608             ++frm_nxt;
1609             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1610             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1611             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1612             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1613             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1614         }
1615         else if (wc1 < 0xE000)
1616         {
1617             return codecvt_base::error;
1618         }
1619         else
1620         {
1621             if (to_end-to_nxt < 3)
1622                 return codecvt_base::partial;
1623             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1624             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1625             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1626         }
1627     }
1628     return codecvt_base::ok;
1629 }
1630 
1631 static
1632 codecvt_base::result
1633 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1634               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1635               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1636 {
1637     frm_nxt = frm;
1638     to_nxt = to;
1639     if (mode & generate_header)
1640     {
1641         if (to_end-to_nxt < 3)
1642             return codecvt_base::partial;
1643         *to_nxt++ = static_cast<uint8_t>(0xEF);
1644         *to_nxt++ = static_cast<uint8_t>(0xBB);
1645         *to_nxt++ = static_cast<uint8_t>(0xBF);
1646     }
1647     for (; frm_nxt < frm_end; ++frm_nxt)
1648     {
1649         uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1650         if (wc1 > Maxcode)
1651             return codecvt_base::error;
1652         if (wc1 < 0x0080)
1653         {
1654             if (to_end-to_nxt < 1)
1655                 return codecvt_base::partial;
1656             *to_nxt++ = static_cast<uint8_t>(wc1);
1657         }
1658         else if (wc1 < 0x0800)
1659         {
1660             if (to_end-to_nxt < 2)
1661                 return codecvt_base::partial;
1662             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1663             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1664         }
1665         else if (wc1 < 0xD800)
1666         {
1667             if (to_end-to_nxt < 3)
1668                 return codecvt_base::partial;
1669             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1670             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1671             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1672         }
1673         else if (wc1 < 0xDC00)
1674         {
1675             if (frm_end-frm_nxt < 2)
1676                 return codecvt_base::partial;
1677             uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1678             if ((wc2 & 0xFC00) != 0xDC00)
1679                 return codecvt_base::error;
1680             if (to_end-to_nxt < 4)
1681                 return codecvt_base::partial;
1682             if ((((((unsigned long)wc1 & 0x03C0) >> 6) + 1) << 16) +
1683                 (((unsigned long)wc1 & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
1684                 return codecvt_base::error;
1685             ++frm_nxt;
1686             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1687             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1688             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1689             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1690             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1691         }
1692         else if (wc1 < 0xE000)
1693         {
1694             return codecvt_base::error;
1695         }
1696         else
1697         {
1698             if (to_end-to_nxt < 3)
1699                 return codecvt_base::partial;
1700             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1701             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1702             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1703         }
1704     }
1705     return codecvt_base::ok;
1706 }
1707 
1708 static
1709 codecvt_base::result
1710 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1711               uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1712               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1713 {
1714     frm_nxt = frm;
1715     to_nxt = to;
1716     if (mode & consume_header)
1717     {
1718         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1719                                                           frm_nxt[2] == 0xBF)
1720             frm_nxt += 3;
1721     }
1722     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1723     {
1724         uint8_t c1 = *frm_nxt;
1725         if (c1 > Maxcode)
1726             return codecvt_base::error;
1727         if (c1 < 0x80)
1728         {
1729             *to_nxt = static_cast<uint16_t>(c1);
1730             ++frm_nxt;
1731         }
1732         else if (c1 < 0xC2)
1733         {
1734             return codecvt_base::error;
1735         }
1736         else if (c1 < 0xE0)
1737         {
1738             if (frm_end-frm_nxt < 2)
1739                 return codecvt_base::partial;
1740             uint8_t c2 = frm_nxt[1];
1741             if ((c2 & 0xC0) != 0x80)
1742                 return codecvt_base::error;
1743             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1744             if (t > Maxcode)
1745                 return codecvt_base::error;
1746             *to_nxt = t;
1747             frm_nxt += 2;
1748         }
1749         else if (c1 < 0xF0)
1750         {
1751             if (frm_end-frm_nxt < 3)
1752                 return codecvt_base::partial;
1753             uint8_t c2 = frm_nxt[1];
1754             uint8_t c3 = frm_nxt[2];
1755             switch (c1)
1756             {
1757             case 0xE0:
1758                 if ((c2 & 0xE0) != 0xA0)
1759                     return codecvt_base::error;
1760                  break;
1761             case 0xED:
1762                 if ((c2 & 0xE0) != 0x80)
1763                     return codecvt_base::error;
1764                  break;
1765             default:
1766                 if ((c2 & 0xC0) != 0x80)
1767                     return codecvt_base::error;
1768                  break;
1769             }
1770             if ((c3 & 0xC0) != 0x80)
1771                 return codecvt_base::error;
1772             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1773                                              | ((c2 & 0x3F) << 6)
1774                                              |  (c3 & 0x3F));
1775             if (t > Maxcode)
1776                 return codecvt_base::error;
1777             *to_nxt = t;
1778             frm_nxt += 3;
1779         }
1780         else if (c1 < 0xF5)
1781         {
1782             if (frm_end-frm_nxt < 4)
1783                 return codecvt_base::partial;
1784             uint8_t c2 = frm_nxt[1];
1785             uint8_t c3 = frm_nxt[2];
1786             uint8_t c4 = frm_nxt[3];
1787             switch (c1)
1788             {
1789             case 0xF0:
1790                 if (!(0x90 <= c2 && c2 <= 0xBF))
1791                     return codecvt_base::error;
1792                  break;
1793             case 0xF4:
1794                 if ((c2 & 0xF0) != 0x80)
1795                     return codecvt_base::error;
1796                  break;
1797             default:
1798                 if ((c2 & 0xC0) != 0x80)
1799                     return codecvt_base::error;
1800                  break;
1801             }
1802             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1803                 return codecvt_base::error;
1804             if (to_end-to_nxt < 2)
1805                 return codecvt_base::partial;
1806             if (((((unsigned long)c1 & 7) << 18) +
1807                 (((unsigned long)c2 & 0x3F) << 12) +
1808                 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1809                 return codecvt_base::error;
1810             *to_nxt = static_cast<uint16_t>(
1811                     0xD800
1812                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1813                   | ((c2 & 0x0F) << 2)
1814                   | ((c3 & 0x30) >> 4));
1815             *++to_nxt = static_cast<uint16_t>(
1816                     0xDC00
1817                   | ((c3 & 0x0F) << 6)
1818                   |  (c4 & 0x3F));
1819             frm_nxt += 4;
1820         }
1821         else
1822         {
1823             return codecvt_base::error;
1824         }
1825     }
1826     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1827 }
1828 
1829 static
1830 codecvt_base::result
1831 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1832               uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1833               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1834 {
1835     frm_nxt = frm;
1836     to_nxt = to;
1837     if (mode & consume_header)
1838     {
1839         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1840                                                           frm_nxt[2] == 0xBF)
1841             frm_nxt += 3;
1842     }
1843     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1844     {
1845         uint8_t c1 = *frm_nxt;
1846         if (c1 > Maxcode)
1847             return codecvt_base::error;
1848         if (c1 < 0x80)
1849         {
1850             *to_nxt = static_cast<uint32_t>(c1);
1851             ++frm_nxt;
1852         }
1853         else if (c1 < 0xC2)
1854         {
1855             return codecvt_base::error;
1856         }
1857         else if (c1 < 0xE0)
1858         {
1859             if (frm_end-frm_nxt < 2)
1860                 return codecvt_base::partial;
1861             uint8_t c2 = frm_nxt[1];
1862             if ((c2 & 0xC0) != 0x80)
1863                 return codecvt_base::error;
1864             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1865             if (t > Maxcode)
1866                 return codecvt_base::error;
1867             *to_nxt = static_cast<uint32_t>(t);
1868             frm_nxt += 2;
1869         }
1870         else if (c1 < 0xF0)
1871         {
1872             if (frm_end-frm_nxt < 3)
1873                 return codecvt_base::partial;
1874             uint8_t c2 = frm_nxt[1];
1875             uint8_t c3 = frm_nxt[2];
1876             switch (c1)
1877             {
1878             case 0xE0:
1879                 if ((c2 & 0xE0) != 0xA0)
1880                     return codecvt_base::error;
1881                  break;
1882             case 0xED:
1883                 if ((c2 & 0xE0) != 0x80)
1884                     return codecvt_base::error;
1885                  break;
1886             default:
1887                 if ((c2 & 0xC0) != 0x80)
1888                     return codecvt_base::error;
1889                  break;
1890             }
1891             if ((c3 & 0xC0) != 0x80)
1892                 return codecvt_base::error;
1893             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1894                                              | ((c2 & 0x3F) << 6)
1895                                              |  (c3 & 0x3F));
1896             if (t > Maxcode)
1897                 return codecvt_base::error;
1898             *to_nxt = static_cast<uint32_t>(t);
1899             frm_nxt += 3;
1900         }
1901         else if (c1 < 0xF5)
1902         {
1903             if (frm_end-frm_nxt < 4)
1904                 return codecvt_base::partial;
1905             uint8_t c2 = frm_nxt[1];
1906             uint8_t c3 = frm_nxt[2];
1907             uint8_t c4 = frm_nxt[3];
1908             switch (c1)
1909             {
1910             case 0xF0:
1911                 if (!(0x90 <= c2 && c2 <= 0xBF))
1912                     return codecvt_base::error;
1913                  break;
1914             case 0xF4:
1915                 if ((c2 & 0xF0) != 0x80)
1916                     return codecvt_base::error;
1917                  break;
1918             default:
1919                 if ((c2 & 0xC0) != 0x80)
1920                     return codecvt_base::error;
1921                  break;
1922             }
1923             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1924                 return codecvt_base::error;
1925             if (to_end-to_nxt < 2)
1926                 return codecvt_base::partial;
1927             if (((((unsigned long)c1 & 7) << 18) +
1928                 (((unsigned long)c2 & 0x3F) << 12) +
1929                 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
1930                 return codecvt_base::error;
1931             *to_nxt = static_cast<uint32_t>(
1932                     0xD800
1933                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1934                   | ((c2 & 0x0F) << 2)
1935                   | ((c3 & 0x30) >> 4));
1936             *++to_nxt = static_cast<uint32_t>(
1937                     0xDC00
1938                   | ((c3 & 0x0F) << 6)
1939                   |  (c4 & 0x3F));
1940             frm_nxt += 4;
1941         }
1942         else
1943         {
1944             return codecvt_base::error;
1945         }
1946     }
1947     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1948 }
1949 
1950 static
1951 int
1952 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
1953                      size_t mx, unsigned long Maxcode = 0x10FFFF,
1954                      codecvt_mode mode = codecvt_mode(0))
1955 {
1956     const uint8_t* frm_nxt = frm;
1957     if (mode & consume_header)
1958     {
1959         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1960                                                           frm_nxt[2] == 0xBF)
1961             frm_nxt += 3;
1962     }
1963     for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
1964     {
1965         uint8_t c1 = *frm_nxt;
1966         if (c1 > Maxcode)
1967             break;
1968         if (c1 < 0x80)
1969         {
1970             ++frm_nxt;
1971         }
1972         else if (c1 < 0xC2)
1973         {
1974             break;
1975         }
1976         else if (c1 < 0xE0)
1977         {
1978             if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
1979                 break;
1980             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
1981             if (t > Maxcode)
1982                 break;
1983             frm_nxt += 2;
1984         }
1985         else if (c1 < 0xF0)
1986         {
1987             if (frm_end-frm_nxt < 3)
1988                 break;
1989             uint8_t c2 = frm_nxt[1];
1990             uint8_t c3 = frm_nxt[2];
1991             switch (c1)
1992             {
1993             case 0xE0:
1994                 if ((c2 & 0xE0) != 0xA0)
1995                     return static_cast<int>(frm_nxt - frm);
1996                 break;
1997             case 0xED:
1998                 if ((c2 & 0xE0) != 0x80)
1999                     return static_cast<int>(frm_nxt - frm);
2000                  break;
2001             default:
2002                 if ((c2 & 0xC0) != 0x80)
2003                     return static_cast<int>(frm_nxt - frm);
2004                  break;
2005             }
2006             if ((c3 & 0xC0) != 0x80)
2007                 break;
2008             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2009                 break;
2010             frm_nxt += 3;
2011         }
2012         else if (c1 < 0xF5)
2013         {
2014             if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2015                 break;
2016             uint8_t c2 = frm_nxt[1];
2017             uint8_t c3 = frm_nxt[2];
2018             uint8_t c4 = frm_nxt[3];
2019             switch (c1)
2020             {
2021             case 0xF0:
2022                 if (!(0x90 <= c2 && c2 <= 0xBF))
2023                     return static_cast<int>(frm_nxt - frm);
2024                  break;
2025             case 0xF4:
2026                 if ((c2 & 0xF0) != 0x80)
2027                     return static_cast<int>(frm_nxt - frm);
2028                  break;
2029             default:
2030                 if ((c2 & 0xC0) != 0x80)
2031                     return static_cast<int>(frm_nxt - frm);
2032                  break;
2033             }
2034             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2035                 break;
2036             if (((((unsigned long)c1 & 7) << 18) +
2037                 (((unsigned long)c2 & 0x3F) << 12) +
2038                 (((unsigned long)c3 & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
2039                 break;
2040             ++nchar16_t;
2041             frm_nxt += 4;
2042         }
2043         else
2044         {
2045             break;
2046         }
2047     }
2048     return static_cast<int>(frm_nxt - frm);
2049 }
2050 
2051 static
2052 codecvt_base::result
2053 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2054              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2055              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2056 {
2057     frm_nxt = frm;
2058     to_nxt = to;
2059     if (mode & generate_header)
2060     {
2061         if (to_end-to_nxt < 3)
2062             return codecvt_base::partial;
2063         *to_nxt++ = static_cast<uint8_t>(0xEF);
2064         *to_nxt++ = static_cast<uint8_t>(0xBB);
2065         *to_nxt++ = static_cast<uint8_t>(0xBF);
2066     }
2067     for (; frm_nxt < frm_end; ++frm_nxt)
2068     {
2069         uint32_t wc = *frm_nxt;
2070         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2071             return codecvt_base::error;
2072         if (wc < 0x000080)
2073         {
2074             if (to_end-to_nxt < 1)
2075                 return codecvt_base::partial;
2076             *to_nxt++ = static_cast<uint8_t>(wc);
2077         }
2078         else if (wc < 0x000800)
2079         {
2080             if (to_end-to_nxt < 2)
2081                 return codecvt_base::partial;
2082             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2083             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2084         }
2085         else if (wc < 0x010000)
2086         {
2087             if (to_end-to_nxt < 3)
2088                 return codecvt_base::partial;
2089             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2090             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2091             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2092         }
2093         else // if (wc < 0x110000)
2094         {
2095             if (to_end-to_nxt < 4)
2096                 return codecvt_base::partial;
2097             *to_nxt++ = static_cast<uint8_t>(0xF0 |  (wc >> 18));
2098             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2099             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2100             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x00003F));
2101         }
2102     }
2103     return codecvt_base::ok;
2104 }
2105 
2106 static
2107 codecvt_base::result
2108 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2109              uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2110              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2111 {
2112     frm_nxt = frm;
2113     to_nxt = to;
2114     if (mode & consume_header)
2115     {
2116         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2117                                                           frm_nxt[2] == 0xBF)
2118             frm_nxt += 3;
2119     }
2120     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2121     {
2122         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2123         if (c1 < 0x80)
2124         {
2125             if (c1 > Maxcode)
2126                 return codecvt_base::error;
2127             *to_nxt = static_cast<uint32_t>(c1);
2128             ++frm_nxt;
2129         }
2130         else if (c1 < 0xC2)
2131         {
2132             return codecvt_base::error;
2133         }
2134         else if (c1 < 0xE0)
2135         {
2136             if (frm_end-frm_nxt < 2)
2137                 return codecvt_base::partial;
2138             uint8_t c2 = frm_nxt[1];
2139             if ((c2 & 0xC0) != 0x80)
2140                 return codecvt_base::error;
2141             uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2142                                               | (c2 & 0x3F));
2143             if (t > Maxcode)
2144                 return codecvt_base::error;
2145             *to_nxt = t;
2146             frm_nxt += 2;
2147         }
2148         else if (c1 < 0xF0)
2149         {
2150             if (frm_end-frm_nxt < 3)
2151                 return codecvt_base::partial;
2152             uint8_t c2 = frm_nxt[1];
2153             uint8_t c3 = frm_nxt[2];
2154             switch (c1)
2155             {
2156             case 0xE0:
2157                 if ((c2 & 0xE0) != 0xA0)
2158                     return codecvt_base::error;
2159                  break;
2160             case 0xED:
2161                 if ((c2 & 0xE0) != 0x80)
2162                     return codecvt_base::error;
2163                  break;
2164             default:
2165                 if ((c2 & 0xC0) != 0x80)
2166                     return codecvt_base::error;
2167                  break;
2168             }
2169             if ((c3 & 0xC0) != 0x80)
2170                 return codecvt_base::error;
2171             uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2172                                              | ((c2 & 0x3F) << 6)
2173                                              |  (c3 & 0x3F));
2174             if (t > Maxcode)
2175                 return codecvt_base::error;
2176             *to_nxt = t;
2177             frm_nxt += 3;
2178         }
2179         else if (c1 < 0xF5)
2180         {
2181             if (frm_end-frm_nxt < 4)
2182                 return codecvt_base::partial;
2183             uint8_t c2 = frm_nxt[1];
2184             uint8_t c3 = frm_nxt[2];
2185             uint8_t c4 = frm_nxt[3];
2186             switch (c1)
2187             {
2188             case 0xF0:
2189                 if (!(0x90 <= c2 && c2 <= 0xBF))
2190                     return codecvt_base::error;
2191                  break;
2192             case 0xF4:
2193                 if ((c2 & 0xF0) != 0x80)
2194                     return codecvt_base::error;
2195                  break;
2196             default:
2197                 if ((c2 & 0xC0) != 0x80)
2198                     return codecvt_base::error;
2199                  break;
2200             }
2201             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2202                 return codecvt_base::error;
2203             uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2204                                              | ((c2 & 0x3F) << 12)
2205                                              | ((c3 & 0x3F) << 6)
2206                                              |  (c4 & 0x3F));
2207             if (t > Maxcode)
2208                 return codecvt_base::error;
2209             *to_nxt = t;
2210             frm_nxt += 4;
2211         }
2212         else
2213         {
2214             return codecvt_base::error;
2215         }
2216     }
2217     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2218 }
2219 
2220 static
2221 int
2222 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2223                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2224                     codecvt_mode mode = codecvt_mode(0))
2225 {
2226     const uint8_t* frm_nxt = frm;
2227     if (mode & consume_header)
2228     {
2229         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2230                                                           frm_nxt[2] == 0xBF)
2231             frm_nxt += 3;
2232     }
2233     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2234     {
2235         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2236         if (c1 < 0x80)
2237         {
2238             if (c1 > Maxcode)
2239                 break;
2240             ++frm_nxt;
2241         }
2242         else if (c1 < 0xC2)
2243         {
2244             break;
2245         }
2246         else if (c1 < 0xE0)
2247         {
2248             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2249                 break;
2250             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2251                 break;
2252             frm_nxt += 2;
2253         }
2254         else if (c1 < 0xF0)
2255         {
2256             if (frm_end-frm_nxt < 3)
2257                 break;
2258             uint8_t c2 = frm_nxt[1];
2259             uint8_t c3 = frm_nxt[2];
2260             switch (c1)
2261             {
2262             case 0xE0:
2263                 if ((c2 & 0xE0) != 0xA0)
2264                     return static_cast<int>(frm_nxt - frm);
2265                 break;
2266             case 0xED:
2267                 if ((c2 & 0xE0) != 0x80)
2268                     return static_cast<int>(frm_nxt - frm);
2269                  break;
2270             default:
2271                 if ((c2 & 0xC0) != 0x80)
2272                     return static_cast<int>(frm_nxt - frm);
2273                  break;
2274             }
2275             if ((c3 & 0xC0) != 0x80)
2276                 break;
2277             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2278                 break;
2279             frm_nxt += 3;
2280         }
2281         else if (c1 < 0xF5)
2282         {
2283             if (frm_end-frm_nxt < 4)
2284                 break;
2285             uint8_t c2 = frm_nxt[1];
2286             uint8_t c3 = frm_nxt[2];
2287             uint8_t c4 = frm_nxt[3];
2288             switch (c1)
2289             {
2290             case 0xF0:
2291                 if (!(0x90 <= c2 && c2 <= 0xBF))
2292                     return static_cast<int>(frm_nxt - frm);
2293                  break;
2294             case 0xF4:
2295                 if ((c2 & 0xF0) != 0x80)
2296                     return static_cast<int>(frm_nxt - frm);
2297                  break;
2298             default:
2299                 if ((c2 & 0xC0) != 0x80)
2300                     return static_cast<int>(frm_nxt - frm);
2301                  break;
2302             }
2303             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2304                 break;
2305             if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2306                  ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)
2307                 break;
2308             frm_nxt += 4;
2309         }
2310         else
2311         {
2312             break;
2313         }
2314     }
2315     return static_cast<int>(frm_nxt - frm);
2316 }
2317 
2318 static
2319 codecvt_base::result
2320 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2321              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2322              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2323 {
2324     frm_nxt = frm;
2325     to_nxt = to;
2326     if (mode & generate_header)
2327     {
2328         if (to_end-to_nxt < 3)
2329             return codecvt_base::partial;
2330         *to_nxt++ = static_cast<uint8_t>(0xEF);
2331         *to_nxt++ = static_cast<uint8_t>(0xBB);
2332         *to_nxt++ = static_cast<uint8_t>(0xBF);
2333     }
2334     for (; frm_nxt < frm_end; ++frm_nxt)
2335     {
2336         uint16_t wc = *frm_nxt;
2337         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2338             return codecvt_base::error;
2339         if (wc < 0x0080)
2340         {
2341             if (to_end-to_nxt < 1)
2342                 return codecvt_base::partial;
2343             *to_nxt++ = static_cast<uint8_t>(wc);
2344         }
2345         else if (wc < 0x0800)
2346         {
2347             if (to_end-to_nxt < 2)
2348                 return codecvt_base::partial;
2349             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2350             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2351         }
2352         else // if (wc <= 0xFFFF)
2353         {
2354             if (to_end-to_nxt < 3)
2355                 return codecvt_base::partial;
2356             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2357             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2358             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2359         }
2360     }
2361     return codecvt_base::ok;
2362 }
2363 
2364 static
2365 codecvt_base::result
2366 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2367              uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2368              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2369 {
2370     frm_nxt = frm;
2371     to_nxt = to;
2372     if (mode & consume_header)
2373     {
2374         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2375                                                           frm_nxt[2] == 0xBF)
2376             frm_nxt += 3;
2377     }
2378     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2379     {
2380         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2381         if (c1 < 0x80)
2382         {
2383             if (c1 > Maxcode)
2384                 return codecvt_base::error;
2385             *to_nxt = static_cast<uint16_t>(c1);
2386             ++frm_nxt;
2387         }
2388         else if (c1 < 0xC2)
2389         {
2390             return codecvt_base::error;
2391         }
2392         else if (c1 < 0xE0)
2393         {
2394             if (frm_end-frm_nxt < 2)
2395                 return codecvt_base::partial;
2396             uint8_t c2 = frm_nxt[1];
2397             if ((c2 & 0xC0) != 0x80)
2398                 return codecvt_base::error;
2399             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2400                                               | (c2 & 0x3F));
2401             if (t > Maxcode)
2402                 return codecvt_base::error;
2403             *to_nxt = t;
2404             frm_nxt += 2;
2405         }
2406         else if (c1 < 0xF0)
2407         {
2408             if (frm_end-frm_nxt < 3)
2409                 return codecvt_base::partial;
2410             uint8_t c2 = frm_nxt[1];
2411             uint8_t c3 = frm_nxt[2];
2412             switch (c1)
2413             {
2414             case 0xE0:
2415                 if ((c2 & 0xE0) != 0xA0)
2416                     return codecvt_base::error;
2417                  break;
2418             case 0xED:
2419                 if ((c2 & 0xE0) != 0x80)
2420                     return codecvt_base::error;
2421                  break;
2422             default:
2423                 if ((c2 & 0xC0) != 0x80)
2424                     return codecvt_base::error;
2425                  break;
2426             }
2427             if ((c3 & 0xC0) != 0x80)
2428                 return codecvt_base::error;
2429             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2430                                              | ((c2 & 0x3F) << 6)
2431                                              |  (c3 & 0x3F));
2432             if (t > Maxcode)
2433                 return codecvt_base::error;
2434             *to_nxt = t;
2435             frm_nxt += 3;
2436         }
2437         else
2438         {
2439             return codecvt_base::error;
2440         }
2441     }
2442     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2443 }
2444 
2445 static
2446 int
2447 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2448                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2449                     codecvt_mode mode = codecvt_mode(0))
2450 {
2451     const uint8_t* frm_nxt = frm;
2452     if (mode & consume_header)
2453     {
2454         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2455                                                           frm_nxt[2] == 0xBF)
2456             frm_nxt += 3;
2457     }
2458     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2459     {
2460         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2461         if (c1 < 0x80)
2462         {
2463             if (c1 > Maxcode)
2464                 break;
2465             ++frm_nxt;
2466         }
2467         else if (c1 < 0xC2)
2468         {
2469             break;
2470         }
2471         else if (c1 < 0xE0)
2472         {
2473             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2474                 break;
2475             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2476                 break;
2477             frm_nxt += 2;
2478         }
2479         else if (c1 < 0xF0)
2480         {
2481             if (frm_end-frm_nxt < 3)
2482                 break;
2483             uint8_t c2 = frm_nxt[1];
2484             uint8_t c3 = frm_nxt[2];
2485             switch (c1)
2486             {
2487             case 0xE0:
2488                 if ((c2 & 0xE0) != 0xA0)
2489                     return static_cast<int>(frm_nxt - frm);
2490                 break;
2491             case 0xED:
2492                 if ((c2 & 0xE0) != 0x80)
2493                     return static_cast<int>(frm_nxt - frm);
2494                  break;
2495             default:
2496                 if ((c2 & 0xC0) != 0x80)
2497                     return static_cast<int>(frm_nxt - frm);
2498                  break;
2499             }
2500             if ((c3 & 0xC0) != 0x80)
2501                 break;
2502             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2503                 break;
2504             frm_nxt += 3;
2505         }
2506         else
2507         {
2508             break;
2509         }
2510     }
2511     return static_cast<int>(frm_nxt - frm);
2512 }
2513 
2514 static
2515 codecvt_base::result
2516 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2517                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2518                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2519 {
2520     frm_nxt = frm;
2521     to_nxt = to;
2522     if (mode & generate_header)
2523     {
2524         if (to_end-to_nxt < 2)
2525             return codecvt_base::partial;
2526         *to_nxt++ = static_cast<uint8_t>(0xFE);
2527         *to_nxt++ = static_cast<uint8_t>(0xFF);
2528     }
2529     for (; frm_nxt < frm_end; ++frm_nxt)
2530     {
2531         uint32_t wc = *frm_nxt;
2532         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2533             return codecvt_base::error;
2534         if (wc < 0x010000)
2535         {
2536             if (to_end-to_nxt < 2)
2537                 return codecvt_base::partial;
2538             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2539             *to_nxt++ = static_cast<uint8_t>(wc);
2540         }
2541         else
2542         {
2543             if (to_end-to_nxt < 4)
2544                 return codecvt_base::partial;
2545             uint16_t t = static_cast<uint16_t>(
2546                     0xD800
2547                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2548                   |   ((wc & 0x00FC00) >> 10));
2549             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2550             *to_nxt++ = static_cast<uint8_t>(t);
2551             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2552             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2553             *to_nxt++ = static_cast<uint8_t>(t);
2554         }
2555     }
2556     return codecvt_base::ok;
2557 }
2558 
2559 static
2560 codecvt_base::result
2561 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2562                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2563                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2564 {
2565     frm_nxt = frm;
2566     to_nxt = to;
2567     if (mode & consume_header)
2568     {
2569         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2570             frm_nxt += 2;
2571     }
2572     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2573     {
2574         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2575         if ((c1 & 0xFC00) == 0xDC00)
2576             return codecvt_base::error;
2577         if ((c1 & 0xFC00) != 0xD800)
2578         {
2579             if (c1 > Maxcode)
2580                 return codecvt_base::error;
2581             *to_nxt = static_cast<uint32_t>(c1);
2582             frm_nxt += 2;
2583         }
2584         else
2585         {
2586             if (frm_end-frm_nxt < 4)
2587                 return codecvt_base::partial;
2588             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2589             if ((c2 & 0xFC00) != 0xDC00)
2590                 return codecvt_base::error;
2591             uint32_t t = static_cast<uint32_t>(
2592                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2593                   |   ((c1 & 0x003F) << 10)
2594                   |    (c2 & 0x03FF));
2595             if (t > Maxcode)
2596                 return codecvt_base::error;
2597             *to_nxt = t;
2598             frm_nxt += 4;
2599         }
2600     }
2601     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2602 }
2603 
2604 static
2605 int
2606 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2607                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2608                        codecvt_mode mode = codecvt_mode(0))
2609 {
2610     const uint8_t* frm_nxt = frm;
2611     frm_nxt = frm;
2612     if (mode & consume_header)
2613     {
2614         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2615             frm_nxt += 2;
2616     }
2617     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2618     {
2619         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2620         if ((c1 & 0xFC00) == 0xDC00)
2621             break;
2622         if ((c1 & 0xFC00) != 0xD800)
2623         {
2624             if (c1 > Maxcode)
2625                 break;
2626             frm_nxt += 2;
2627         }
2628         else
2629         {
2630             if (frm_end-frm_nxt < 4)
2631                 break;
2632             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2633             if ((c2 & 0xFC00) != 0xDC00)
2634                 break;
2635             uint32_t t = static_cast<uint32_t>(
2636                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2637                   |   ((c1 & 0x003F) << 10)
2638                   |    (c2 & 0x03FF));
2639             if (t > Maxcode)
2640                 break;
2641             frm_nxt += 4;
2642         }
2643     }
2644     return static_cast<int>(frm_nxt - frm);
2645 }
2646 
2647 static
2648 codecvt_base::result
2649 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2650                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2651                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2652 {
2653     frm_nxt = frm;
2654     to_nxt = to;
2655     if (mode & generate_header)
2656     {
2657         if (to_end-to_nxt < 2)
2658             return codecvt_base::partial;
2659             *to_nxt++ = static_cast<uint8_t>(0xFF);
2660             *to_nxt++ = static_cast<uint8_t>(0xFE);
2661     }
2662     for (; frm_nxt < frm_end; ++frm_nxt)
2663     {
2664         uint32_t wc = *frm_nxt;
2665         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2666             return codecvt_base::error;
2667         if (wc < 0x010000)
2668         {
2669             if (to_end-to_nxt < 2)
2670                 return codecvt_base::partial;
2671             *to_nxt++ = static_cast<uint8_t>(wc);
2672             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2673         }
2674         else
2675         {
2676             if (to_end-to_nxt < 4)
2677                 return codecvt_base::partial;
2678             uint16_t t = static_cast<uint16_t>(
2679                     0xD800
2680                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2681                   |   ((wc & 0x00FC00) >> 10));
2682             *to_nxt++ = static_cast<uint8_t>(t);
2683             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2684             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2685             *to_nxt++ = static_cast<uint8_t>(t);
2686             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2687         }
2688     }
2689     return codecvt_base::ok;
2690 }
2691 
2692 static
2693 codecvt_base::result
2694 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2695                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2696                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2697 {
2698     frm_nxt = frm;
2699     to_nxt = to;
2700     if (mode & consume_header)
2701     {
2702         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2703             frm_nxt += 2;
2704     }
2705     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2706     {
2707         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2708         if ((c1 & 0xFC00) == 0xDC00)
2709             return codecvt_base::error;
2710         if ((c1 & 0xFC00) != 0xD800)
2711         {
2712             if (c1 > Maxcode)
2713                 return codecvt_base::error;
2714             *to_nxt = static_cast<uint32_t>(c1);
2715             frm_nxt += 2;
2716         }
2717         else
2718         {
2719             if (frm_end-frm_nxt < 4)
2720                 return codecvt_base::partial;
2721             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2722             if ((c2 & 0xFC00) != 0xDC00)
2723                 return codecvt_base::error;
2724             uint32_t t = static_cast<uint32_t>(
2725                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2726                   |   ((c1 & 0x003F) << 10)
2727                   |    (c2 & 0x03FF));
2728             if (t > Maxcode)
2729                 return codecvt_base::error;
2730             *to_nxt = t;
2731             frm_nxt += 4;
2732         }
2733     }
2734     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2735 }
2736 
2737 static
2738 int
2739 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2740                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2741                        codecvt_mode mode = codecvt_mode(0))
2742 {
2743     const uint8_t* frm_nxt = frm;
2744     frm_nxt = frm;
2745     if (mode & consume_header)
2746     {
2747         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2748             frm_nxt += 2;
2749     }
2750     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2751     {
2752         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2753         if ((c1 & 0xFC00) == 0xDC00)
2754             break;
2755         if ((c1 & 0xFC00) != 0xD800)
2756         {
2757             if (c1 > Maxcode)
2758                 break;
2759             frm_nxt += 2;
2760         }
2761         else
2762         {
2763             if (frm_end-frm_nxt < 4)
2764                 break;
2765             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2766             if ((c2 & 0xFC00) != 0xDC00)
2767                 break;
2768             uint32_t t = static_cast<uint32_t>(
2769                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2770                   |   ((c1 & 0x003F) << 10)
2771                   |    (c2 & 0x03FF));
2772             if (t > Maxcode)
2773                 break;
2774             frm_nxt += 4;
2775         }
2776     }
2777     return static_cast<int>(frm_nxt - frm);
2778 }
2779 
2780 static
2781 codecvt_base::result
2782 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2783                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2784                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2785 {
2786     frm_nxt = frm;
2787     to_nxt = to;
2788     if (mode & generate_header)
2789     {
2790         if (to_end-to_nxt < 2)
2791             return codecvt_base::partial;
2792         *to_nxt++ = static_cast<uint8_t>(0xFE);
2793         *to_nxt++ = static_cast<uint8_t>(0xFF);
2794     }
2795     for (; frm_nxt < frm_end; ++frm_nxt)
2796     {
2797         uint16_t wc = *frm_nxt;
2798         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2799             return codecvt_base::error;
2800         if (to_end-to_nxt < 2)
2801             return codecvt_base::partial;
2802         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2803         *to_nxt++ = static_cast<uint8_t>(wc);
2804     }
2805     return codecvt_base::ok;
2806 }
2807 
2808 static
2809 codecvt_base::result
2810 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2811                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2812                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2813 {
2814     frm_nxt = frm;
2815     to_nxt = to;
2816     if (mode & consume_header)
2817     {
2818         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2819             frm_nxt += 2;
2820     }
2821     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2822     {
2823         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2824         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2825             return codecvt_base::error;
2826         *to_nxt = c1;
2827         frm_nxt += 2;
2828     }
2829     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2830 }
2831 
2832 static
2833 int
2834 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2835                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2836                        codecvt_mode mode = codecvt_mode(0))
2837 {
2838     const uint8_t* frm_nxt = frm;
2839     frm_nxt = frm;
2840     if (mode & consume_header)
2841     {
2842         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2843             frm_nxt += 2;
2844     }
2845     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2846     {
2847         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2848         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2849             break;
2850         frm_nxt += 2;
2851     }
2852     return static_cast<int>(frm_nxt - frm);
2853 }
2854 
2855 static
2856 codecvt_base::result
2857 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2858                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2859                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2860 {
2861     frm_nxt = frm;
2862     to_nxt = to;
2863     if (mode & generate_header)
2864     {
2865         if (to_end-to_nxt < 2)
2866             return codecvt_base::partial;
2867         *to_nxt++ = static_cast<uint8_t>(0xFF);
2868         *to_nxt++ = static_cast<uint8_t>(0xFE);
2869     }
2870     for (; frm_nxt < frm_end; ++frm_nxt)
2871     {
2872         uint16_t wc = *frm_nxt;
2873         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2874             return codecvt_base::error;
2875         if (to_end-to_nxt < 2)
2876             return codecvt_base::partial;
2877         *to_nxt++ = static_cast<uint8_t>(wc);
2878         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2879     }
2880     return codecvt_base::ok;
2881 }
2882 
2883 static
2884 codecvt_base::result
2885 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2886                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2887                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2888 {
2889     frm_nxt = frm;
2890     to_nxt = to;
2891     if (mode & consume_header)
2892     {
2893         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2894             frm_nxt += 2;
2895     }
2896     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2897     {
2898         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2899         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2900             return codecvt_base::error;
2901         *to_nxt = c1;
2902         frm_nxt += 2;
2903     }
2904     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2905 }
2906 
2907 static
2908 int
2909 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2910                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2911                        codecvt_mode mode = codecvt_mode(0))
2912 {
2913     const uint8_t* frm_nxt = frm;
2914     frm_nxt = frm;
2915     if (mode & consume_header)
2916     {
2917         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2918             frm_nxt += 2;
2919     }
2920     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
2921     {
2922         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2923         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2924             break;
2925         frm_nxt += 2;
2926     }
2927     return static_cast<int>(frm_nxt - frm);
2928 }
2929 
2930 // template <> class codecvt<char16_t, char, mbstate_t>
2931 
2932 locale::id codecvt<char16_t, char, mbstate_t>::id;
2933 
2934 codecvt<char16_t, char, mbstate_t>::~codecvt()
2935 {
2936 }
2937 
2938 codecvt<char16_t, char, mbstate_t>::result
2939 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
2940     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
2941     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
2942 {
2943     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
2944     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
2945     const uint16_t* _frm_nxt = _frm;
2946     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
2947     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
2948     uint8_t* _to_nxt = _to;
2949     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2950     frm_nxt = frm + (_frm_nxt - _frm);
2951     to_nxt = to + (_to_nxt - _to);
2952     return r;
2953 }
2954 
2955 codecvt<char16_t, char, mbstate_t>::result
2956 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
2957     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
2958     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
2959 {
2960     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2961     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2962     const uint8_t* _frm_nxt = _frm;
2963     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
2964     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
2965     uint16_t* _to_nxt = _to;
2966     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
2967     frm_nxt = frm + (_frm_nxt - _frm);
2968     to_nxt = to + (_to_nxt - _to);
2969     return r;
2970 }
2971 
2972 codecvt<char16_t, char, mbstate_t>::result
2973 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
2974     extern_type* to, extern_type*, extern_type*& to_nxt) const
2975 {
2976     to_nxt = to;
2977     return noconv;
2978 }
2979 
2980 int
2981 codecvt<char16_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
2982 {
2983     return 0;
2984 }
2985 
2986 bool
2987 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
2988 {
2989     return false;
2990 }
2991 
2992 int
2993 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
2994     const extern_type* frm, const extern_type* frm_end, size_t mx) const
2995 {
2996     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
2997     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
2998     return utf8_to_utf16_length(_frm, _frm_end, mx);
2999 }
3000 
3001 int
3002 codecvt<char16_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
3003 {
3004     return 4;
3005 }
3006 
3007 // template <> class codecvt<char32_t, char, mbstate_t>
3008 
3009 locale::id codecvt<char32_t, char, mbstate_t>::id;
3010 
3011 codecvt<char32_t, char, mbstate_t>::~codecvt()
3012 {
3013 }
3014 
3015 codecvt<char32_t, char, mbstate_t>::result
3016 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3017     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3018     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3019 {
3020     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3021     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3022     const uint32_t* _frm_nxt = _frm;
3023     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3024     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3025     uint8_t* _to_nxt = _to;
3026     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3027     frm_nxt = frm + (_frm_nxt - _frm);
3028     to_nxt = to + (_to_nxt - _to);
3029     return r;
3030 }
3031 
3032 codecvt<char32_t, char, mbstate_t>::result
3033 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3034     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3035     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3036 {
3037     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3038     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3039     const uint8_t* _frm_nxt = _frm;
3040     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3041     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3042     uint32_t* _to_nxt = _to;
3043     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3044     frm_nxt = frm + (_frm_nxt - _frm);
3045     to_nxt = to + (_to_nxt - _to);
3046     return r;
3047 }
3048 
3049 codecvt<char32_t, char, mbstate_t>::result
3050 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3051     extern_type* to, extern_type*, extern_type*& to_nxt) const
3052 {
3053     to_nxt = to;
3054     return noconv;
3055 }
3056 
3057 int
3058 codecvt<char32_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
3059 {
3060     return 0;
3061 }
3062 
3063 bool
3064 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
3065 {
3066     return false;
3067 }
3068 
3069 int
3070 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3071     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3072 {
3073     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3074     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3075     return utf8_to_ucs4_length(_frm, _frm_end, mx);
3076 }
3077 
3078 int
3079 codecvt<char32_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
3080 {
3081     return 4;
3082 }
3083 
3084 // __codecvt_utf8<wchar_t>
3085 
3086 __codecvt_utf8<wchar_t>::result
3087 __codecvt_utf8<wchar_t>::do_out(state_type&,
3088     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3089     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3090 {
3091     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3092     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3093     const uint32_t* _frm_nxt = _frm;
3094     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3095     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3096     uint8_t* _to_nxt = _to;
3097     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3098                             _Maxcode_, _Mode_);
3099     frm_nxt = frm + (_frm_nxt - _frm);
3100     to_nxt = to + (_to_nxt - _to);
3101     return r;
3102 }
3103 
3104 __codecvt_utf8<wchar_t>::result
3105 __codecvt_utf8<wchar_t>::do_in(state_type&,
3106     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3107     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3108 {
3109     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3110     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3111     const uint8_t* _frm_nxt = _frm;
3112     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3113     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3114     uint32_t* _to_nxt = _to;
3115     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3116                             _Maxcode_, _Mode_);
3117     frm_nxt = frm + (_frm_nxt - _frm);
3118     to_nxt = to + (_to_nxt - _to);
3119     return r;
3120 }
3121 
3122 __codecvt_utf8<wchar_t>::result
3123 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3124     extern_type* to, extern_type*, extern_type*& to_nxt) const
3125 {
3126     to_nxt = to;
3127     return noconv;
3128 }
3129 
3130 int
3131 __codecvt_utf8<wchar_t>::do_encoding() const  _NOEXCEPT
3132 {
3133     return 0;
3134 }
3135 
3136 bool
3137 __codecvt_utf8<wchar_t>::do_always_noconv() const  _NOEXCEPT
3138 {
3139     return false;
3140 }
3141 
3142 int
3143 __codecvt_utf8<wchar_t>::do_length(state_type&,
3144     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3145 {
3146     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3147     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3148     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3149 }
3150 
3151 int
3152 __codecvt_utf8<wchar_t>::do_max_length() const  _NOEXCEPT
3153 {
3154     if (_Mode_ & consume_header)
3155         return 7;
3156     return 4;
3157 }
3158 
3159 // __codecvt_utf8<char16_t>
3160 
3161 __codecvt_utf8<char16_t>::result
3162 __codecvt_utf8<char16_t>::do_out(state_type&,
3163     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3164     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3165 {
3166     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3167     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3168     const uint16_t* _frm_nxt = _frm;
3169     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3170     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3171     uint8_t* _to_nxt = _to;
3172     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3173                             _Maxcode_, _Mode_);
3174     frm_nxt = frm + (_frm_nxt - _frm);
3175     to_nxt = to + (_to_nxt - _to);
3176     return r;
3177 }
3178 
3179 __codecvt_utf8<char16_t>::result
3180 __codecvt_utf8<char16_t>::do_in(state_type&,
3181     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3182     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3183 {
3184     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3185     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3186     const uint8_t* _frm_nxt = _frm;
3187     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3188     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3189     uint16_t* _to_nxt = _to;
3190     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3191                             _Maxcode_, _Mode_);
3192     frm_nxt = frm + (_frm_nxt - _frm);
3193     to_nxt = to + (_to_nxt - _to);
3194     return r;
3195 }
3196 
3197 __codecvt_utf8<char16_t>::result
3198 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3199     extern_type* to, extern_type*, extern_type*& to_nxt) const
3200 {
3201     to_nxt = to;
3202     return noconv;
3203 }
3204 
3205 int
3206 __codecvt_utf8<char16_t>::do_encoding() const  _NOEXCEPT
3207 {
3208     return 0;
3209 }
3210 
3211 bool
3212 __codecvt_utf8<char16_t>::do_always_noconv() const  _NOEXCEPT
3213 {
3214     return false;
3215 }
3216 
3217 int
3218 __codecvt_utf8<char16_t>::do_length(state_type&,
3219     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3220 {
3221     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3222     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3223     return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3224 }
3225 
3226 int
3227 __codecvt_utf8<char16_t>::do_max_length() const  _NOEXCEPT
3228 {
3229     if (_Mode_ & consume_header)
3230         return 6;
3231     return 3;
3232 }
3233 
3234 // __codecvt_utf8<char32_t>
3235 
3236 __codecvt_utf8<char32_t>::result
3237 __codecvt_utf8<char32_t>::do_out(state_type&,
3238     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3239     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3240 {
3241     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3242     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3243     const uint32_t* _frm_nxt = _frm;
3244     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3245     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3246     uint8_t* _to_nxt = _to;
3247     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3248                             _Maxcode_, _Mode_);
3249     frm_nxt = frm + (_frm_nxt - _frm);
3250     to_nxt = to + (_to_nxt - _to);
3251     return r;
3252 }
3253 
3254 __codecvt_utf8<char32_t>::result
3255 __codecvt_utf8<char32_t>::do_in(state_type&,
3256     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3257     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3258 {
3259     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3260     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3261     const uint8_t* _frm_nxt = _frm;
3262     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3263     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3264     uint32_t* _to_nxt = _to;
3265     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3266                             _Maxcode_, _Mode_);
3267     frm_nxt = frm + (_frm_nxt - _frm);
3268     to_nxt = to + (_to_nxt - _to);
3269     return r;
3270 }
3271 
3272 __codecvt_utf8<char32_t>::result
3273 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3274     extern_type* to, extern_type*, extern_type*& to_nxt) const
3275 {
3276     to_nxt = to;
3277     return noconv;
3278 }
3279 
3280 int
3281 __codecvt_utf8<char32_t>::do_encoding() const  _NOEXCEPT
3282 {
3283     return 0;
3284 }
3285 
3286 bool
3287 __codecvt_utf8<char32_t>::do_always_noconv() const  _NOEXCEPT
3288 {
3289     return false;
3290 }
3291 
3292 int
3293 __codecvt_utf8<char32_t>::do_length(state_type&,
3294     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3295 {
3296     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3297     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3298     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3299 }
3300 
3301 int
3302 __codecvt_utf8<char32_t>::do_max_length() const  _NOEXCEPT
3303 {
3304     if (_Mode_ & consume_header)
3305         return 7;
3306     return 4;
3307 }
3308 
3309 // __codecvt_utf16<wchar_t, false>
3310 
3311 __codecvt_utf16<wchar_t, false>::result
3312 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3313     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3314     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3315 {
3316     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3317     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3318     const uint32_t* _frm_nxt = _frm;
3319     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3320     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3321     uint8_t* _to_nxt = _to;
3322     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3323                                _Maxcode_, _Mode_);
3324     frm_nxt = frm + (_frm_nxt - _frm);
3325     to_nxt = to + (_to_nxt - _to);
3326     return r;
3327 }
3328 
3329 __codecvt_utf16<wchar_t, false>::result
3330 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3331     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3332     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3333 {
3334     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3335     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3336     const uint8_t* _frm_nxt = _frm;
3337     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3338     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3339     uint32_t* _to_nxt = _to;
3340     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3341                                _Maxcode_, _Mode_);
3342     frm_nxt = frm + (_frm_nxt - _frm);
3343     to_nxt = to + (_to_nxt - _to);
3344     return r;
3345 }
3346 
3347 __codecvt_utf16<wchar_t, false>::result
3348 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3349     extern_type* to, extern_type*, extern_type*& to_nxt) const
3350 {
3351     to_nxt = to;
3352     return noconv;
3353 }
3354 
3355 int
3356 __codecvt_utf16<wchar_t, false>::do_encoding() const  _NOEXCEPT
3357 {
3358     return 0;
3359 }
3360 
3361 bool
3362 __codecvt_utf16<wchar_t, false>::do_always_noconv() const  _NOEXCEPT
3363 {
3364     return false;
3365 }
3366 
3367 int
3368 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3369     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3370 {
3371     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3372     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3373     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3374 }
3375 
3376 int
3377 __codecvt_utf16<wchar_t, false>::do_max_length() const  _NOEXCEPT
3378 {
3379     if (_Mode_ & consume_header)
3380         return 6;
3381     return 4;
3382 }
3383 
3384 // __codecvt_utf16<wchar_t, true>
3385 
3386 __codecvt_utf16<wchar_t, true>::result
3387 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3388     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3389     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3390 {
3391     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3392     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3393     const uint32_t* _frm_nxt = _frm;
3394     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3395     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3396     uint8_t* _to_nxt = _to;
3397     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3398                                _Maxcode_, _Mode_);
3399     frm_nxt = frm + (_frm_nxt - _frm);
3400     to_nxt = to + (_to_nxt - _to);
3401     return r;
3402 }
3403 
3404 __codecvt_utf16<wchar_t, true>::result
3405 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3406     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3407     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3408 {
3409     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3410     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3411     const uint8_t* _frm_nxt = _frm;
3412     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3413     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3414     uint32_t* _to_nxt = _to;
3415     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3416                                _Maxcode_, _Mode_);
3417     frm_nxt = frm + (_frm_nxt - _frm);
3418     to_nxt = to + (_to_nxt - _to);
3419     return r;
3420 }
3421 
3422 __codecvt_utf16<wchar_t, true>::result
3423 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3424     extern_type* to, extern_type*, extern_type*& to_nxt) const
3425 {
3426     to_nxt = to;
3427     return noconv;
3428 }
3429 
3430 int
3431 __codecvt_utf16<wchar_t, true>::do_encoding() const  _NOEXCEPT
3432 {
3433     return 0;
3434 }
3435 
3436 bool
3437 __codecvt_utf16<wchar_t, true>::do_always_noconv() const  _NOEXCEPT
3438 {
3439     return false;
3440 }
3441 
3442 int
3443 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3444     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3445 {
3446     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3447     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3448     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3449 }
3450 
3451 int
3452 __codecvt_utf16<wchar_t, true>::do_max_length() const  _NOEXCEPT
3453 {
3454     if (_Mode_ & consume_header)
3455         return 6;
3456     return 4;
3457 }
3458 
3459 // __codecvt_utf16<char16_t, false>
3460 
3461 __codecvt_utf16<char16_t, false>::result
3462 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3463     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3464     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3465 {
3466     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3467     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3468     const uint16_t* _frm_nxt = _frm;
3469     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3470     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3471     uint8_t* _to_nxt = _to;
3472     result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3473                                _Maxcode_, _Mode_);
3474     frm_nxt = frm + (_frm_nxt - _frm);
3475     to_nxt = to + (_to_nxt - _to);
3476     return r;
3477 }
3478 
3479 __codecvt_utf16<char16_t, false>::result
3480 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3481     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3482     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3483 {
3484     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3485     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3486     const uint8_t* _frm_nxt = _frm;
3487     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3488     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3489     uint16_t* _to_nxt = _to;
3490     result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3491                                _Maxcode_, _Mode_);
3492     frm_nxt = frm + (_frm_nxt - _frm);
3493     to_nxt = to + (_to_nxt - _to);
3494     return r;
3495 }
3496 
3497 __codecvt_utf16<char16_t, false>::result
3498 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3499     extern_type* to, extern_type*, extern_type*& to_nxt) const
3500 {
3501     to_nxt = to;
3502     return noconv;
3503 }
3504 
3505 int
3506 __codecvt_utf16<char16_t, false>::do_encoding() const  _NOEXCEPT
3507 {
3508     return 0;
3509 }
3510 
3511 bool
3512 __codecvt_utf16<char16_t, false>::do_always_noconv() const  _NOEXCEPT
3513 {
3514     return false;
3515 }
3516 
3517 int
3518 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3519     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3520 {
3521     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3522     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3523     return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3524 }
3525 
3526 int
3527 __codecvt_utf16<char16_t, false>::do_max_length() const  _NOEXCEPT
3528 {
3529     if (_Mode_ & consume_header)
3530         return 4;
3531     return 2;
3532 }
3533 
3534 // __codecvt_utf16<char16_t, true>
3535 
3536 __codecvt_utf16<char16_t, true>::result
3537 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3538     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3539     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3540 {
3541     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3542     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3543     const uint16_t* _frm_nxt = _frm;
3544     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3545     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3546     uint8_t* _to_nxt = _to;
3547     result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3548                                _Maxcode_, _Mode_);
3549     frm_nxt = frm + (_frm_nxt - _frm);
3550     to_nxt = to + (_to_nxt - _to);
3551     return r;
3552 }
3553 
3554 __codecvt_utf16<char16_t, true>::result
3555 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3556     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3557     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3558 {
3559     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3560     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3561     const uint8_t* _frm_nxt = _frm;
3562     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3563     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3564     uint16_t* _to_nxt = _to;
3565     result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3566                                _Maxcode_, _Mode_);
3567     frm_nxt = frm + (_frm_nxt - _frm);
3568     to_nxt = to + (_to_nxt - _to);
3569     return r;
3570 }
3571 
3572 __codecvt_utf16<char16_t, true>::result
3573 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3574     extern_type* to, extern_type*, extern_type*& to_nxt) const
3575 {
3576     to_nxt = to;
3577     return noconv;
3578 }
3579 
3580 int
3581 __codecvt_utf16<char16_t, true>::do_encoding() const  _NOEXCEPT
3582 {
3583     return 0;
3584 }
3585 
3586 bool
3587 __codecvt_utf16<char16_t, true>::do_always_noconv() const  _NOEXCEPT
3588 {
3589     return false;
3590 }
3591 
3592 int
3593 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3594     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3595 {
3596     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3597     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3598     return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3599 }
3600 
3601 int
3602 __codecvt_utf16<char16_t, true>::do_max_length() const  _NOEXCEPT
3603 {
3604     if (_Mode_ & consume_header)
3605         return 4;
3606     return 2;
3607 }
3608 
3609 // __codecvt_utf16<char32_t, false>
3610 
3611 __codecvt_utf16<char32_t, false>::result
3612 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3613     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3614     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3615 {
3616     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3617     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3618     const uint32_t* _frm_nxt = _frm;
3619     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3620     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3621     uint8_t* _to_nxt = _to;
3622     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3623                                _Maxcode_, _Mode_);
3624     frm_nxt = frm + (_frm_nxt - _frm);
3625     to_nxt = to + (_to_nxt - _to);
3626     return r;
3627 }
3628 
3629 __codecvt_utf16<char32_t, false>::result
3630 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3631     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3632     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3633 {
3634     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3635     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3636     const uint8_t* _frm_nxt = _frm;
3637     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3638     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3639     uint32_t* _to_nxt = _to;
3640     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3641                                _Maxcode_, _Mode_);
3642     frm_nxt = frm + (_frm_nxt - _frm);
3643     to_nxt = to + (_to_nxt - _to);
3644     return r;
3645 }
3646 
3647 __codecvt_utf16<char32_t, false>::result
3648 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3649     extern_type* to, extern_type*, extern_type*& to_nxt) const
3650 {
3651     to_nxt = to;
3652     return noconv;
3653 }
3654 
3655 int
3656 __codecvt_utf16<char32_t, false>::do_encoding() const  _NOEXCEPT
3657 {
3658     return 0;
3659 }
3660 
3661 bool
3662 __codecvt_utf16<char32_t, false>::do_always_noconv() const  _NOEXCEPT
3663 {
3664     return false;
3665 }
3666 
3667 int
3668 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3669     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3670 {
3671     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3672     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3673     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3674 }
3675 
3676 int
3677 __codecvt_utf16<char32_t, false>::do_max_length() const  _NOEXCEPT
3678 {
3679     if (_Mode_ & consume_header)
3680         return 6;
3681     return 4;
3682 }
3683 
3684 // __codecvt_utf16<char32_t, true>
3685 
3686 __codecvt_utf16<char32_t, true>::result
3687 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3688     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3689     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3690 {
3691     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3692     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3693     const uint32_t* _frm_nxt = _frm;
3694     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3695     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3696     uint8_t* _to_nxt = _to;
3697     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3698                                _Maxcode_, _Mode_);
3699     frm_nxt = frm + (_frm_nxt - _frm);
3700     to_nxt = to + (_to_nxt - _to);
3701     return r;
3702 }
3703 
3704 __codecvt_utf16<char32_t, true>::result
3705 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3706     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3707     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3708 {
3709     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3710     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3711     const uint8_t* _frm_nxt = _frm;
3712     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3713     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3714     uint32_t* _to_nxt = _to;
3715     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3716                                _Maxcode_, _Mode_);
3717     frm_nxt = frm + (_frm_nxt - _frm);
3718     to_nxt = to + (_to_nxt - _to);
3719     return r;
3720 }
3721 
3722 __codecvt_utf16<char32_t, true>::result
3723 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3724     extern_type* to, extern_type*, extern_type*& to_nxt) const
3725 {
3726     to_nxt = to;
3727     return noconv;
3728 }
3729 
3730 int
3731 __codecvt_utf16<char32_t, true>::do_encoding() const  _NOEXCEPT
3732 {
3733     return 0;
3734 }
3735 
3736 bool
3737 __codecvt_utf16<char32_t, true>::do_always_noconv() const  _NOEXCEPT
3738 {
3739     return false;
3740 }
3741 
3742 int
3743 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3744     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3745 {
3746     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3747     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3748     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3749 }
3750 
3751 int
3752 __codecvt_utf16<char32_t, true>::do_max_length() const  _NOEXCEPT
3753 {
3754     if (_Mode_ & consume_header)
3755         return 6;
3756     return 4;
3757 }
3758 
3759 // __codecvt_utf8_utf16<wchar_t>
3760 
3761 __codecvt_utf8_utf16<wchar_t>::result
3762 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3763     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3764     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3765 {
3766     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3767     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3768     const uint32_t* _frm_nxt = _frm;
3769     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3770     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3771     uint8_t* _to_nxt = _to;
3772     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3773                              _Maxcode_, _Mode_);
3774     frm_nxt = frm + (_frm_nxt - _frm);
3775     to_nxt = to + (_to_nxt - _to);
3776     return r;
3777 }
3778 
3779 __codecvt_utf8_utf16<wchar_t>::result
3780 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3781     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3782     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3783 {
3784     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3785     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3786     const uint8_t* _frm_nxt = _frm;
3787     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3788     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3789     uint32_t* _to_nxt = _to;
3790     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3791                              _Maxcode_, _Mode_);
3792     frm_nxt = frm + (_frm_nxt - _frm);
3793     to_nxt = to + (_to_nxt - _to);
3794     return r;
3795 }
3796 
3797 __codecvt_utf8_utf16<wchar_t>::result
3798 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3799     extern_type* to, extern_type*, extern_type*& to_nxt) const
3800 {
3801     to_nxt = to;
3802     return noconv;
3803 }
3804 
3805 int
3806 __codecvt_utf8_utf16<wchar_t>::do_encoding() const  _NOEXCEPT
3807 {
3808     return 0;
3809 }
3810 
3811 bool
3812 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const  _NOEXCEPT
3813 {
3814     return false;
3815 }
3816 
3817 int
3818 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3819     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3820 {
3821     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3822     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3823     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3824 }
3825 
3826 int
3827 __codecvt_utf8_utf16<wchar_t>::do_max_length() const  _NOEXCEPT
3828 {
3829     if (_Mode_ & consume_header)
3830         return 7;
3831     return 4;
3832 }
3833 
3834 // __codecvt_utf8_utf16<char16_t>
3835 
3836 __codecvt_utf8_utf16<char16_t>::result
3837 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
3838     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3839     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3840 {
3841     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3842     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3843     const uint16_t* _frm_nxt = _frm;
3844     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3845     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3846     uint8_t* _to_nxt = _to;
3847     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3848                              _Maxcode_, _Mode_);
3849     frm_nxt = frm + (_frm_nxt - _frm);
3850     to_nxt = to + (_to_nxt - _to);
3851     return r;
3852 }
3853 
3854 __codecvt_utf8_utf16<char16_t>::result
3855 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
3856     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3857     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3858 {
3859     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3860     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3861     const uint8_t* _frm_nxt = _frm;
3862     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3863     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3864     uint16_t* _to_nxt = _to;
3865     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3866                              _Maxcode_, _Mode_);
3867     frm_nxt = frm + (_frm_nxt - _frm);
3868     to_nxt = to + (_to_nxt - _to);
3869     return r;
3870 }
3871 
3872 __codecvt_utf8_utf16<char16_t>::result
3873 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
3874     extern_type* to, extern_type*, extern_type*& to_nxt) const
3875 {
3876     to_nxt = to;
3877     return noconv;
3878 }
3879 
3880 int
3881 __codecvt_utf8_utf16<char16_t>::do_encoding() const  _NOEXCEPT
3882 {
3883     return 0;
3884 }
3885 
3886 bool
3887 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const  _NOEXCEPT
3888 {
3889     return false;
3890 }
3891 
3892 int
3893 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
3894     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3895 {
3896     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3897     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3898     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3899 }
3900 
3901 int
3902 __codecvt_utf8_utf16<char16_t>::do_max_length() const  _NOEXCEPT
3903 {
3904     if (_Mode_ & consume_header)
3905         return 7;
3906     return 4;
3907 }
3908 
3909 // __codecvt_utf8_utf16<char32_t>
3910 
3911 __codecvt_utf8_utf16<char32_t>::result
3912 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
3913     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3914     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3915 {
3916     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3917     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3918     const uint32_t* _frm_nxt = _frm;
3919     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3920     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3921     uint8_t* _to_nxt = _to;
3922     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3923                              _Maxcode_, _Mode_);
3924     frm_nxt = frm + (_frm_nxt - _frm);
3925     to_nxt = to + (_to_nxt - _to);
3926     return r;
3927 }
3928 
3929 __codecvt_utf8_utf16<char32_t>::result
3930 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
3931     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3932     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3933 {
3934     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3935     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3936     const uint8_t* _frm_nxt = _frm;
3937     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3938     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3939     uint32_t* _to_nxt = _to;
3940     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3941                              _Maxcode_, _Mode_);
3942     frm_nxt = frm + (_frm_nxt - _frm);
3943     to_nxt = to + (_to_nxt - _to);
3944     return r;
3945 }
3946 
3947 __codecvt_utf8_utf16<char32_t>::result
3948 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
3949     extern_type* to, extern_type*, extern_type*& to_nxt) const
3950 {
3951     to_nxt = to;
3952     return noconv;
3953 }
3954 
3955 int
3956 __codecvt_utf8_utf16<char32_t>::do_encoding() const  _NOEXCEPT
3957 {
3958     return 0;
3959 }
3960 
3961 bool
3962 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const  _NOEXCEPT
3963 {
3964     return false;
3965 }
3966 
3967 int
3968 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
3969     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3970 {
3971     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3972     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3973     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3974 }
3975 
3976 int
3977 __codecvt_utf8_utf16<char32_t>::do_max_length() const  _NOEXCEPT
3978 {
3979     if (_Mode_ & consume_header)
3980         return 7;
3981     return 4;
3982 }
3983 
3984 // __narrow_to_utf8<16>
3985 
3986 __narrow_to_utf8<16>::~__narrow_to_utf8()
3987 {
3988 }
3989 
3990 // __narrow_to_utf8<32>
3991 
3992 __narrow_to_utf8<32>::~__narrow_to_utf8()
3993 {
3994 }
3995 
3996 // __widen_from_utf8<16>
3997 
3998 __widen_from_utf8<16>::~__widen_from_utf8()
3999 {
4000 }
4001 
4002 // __widen_from_utf8<32>
4003 
4004 __widen_from_utf8<32>::~__widen_from_utf8()
4005 {
4006 }
4007 
4008 // numpunct<char> && numpunct<wchar_t>
4009 
4010 locale::id numpunct< char  >::id;
4011 locale::id numpunct<wchar_t>::id;
4012 
4013 numpunct<char>::numpunct(size_t refs)
4014     : locale::facet(refs),
4015       __decimal_point_('.'),
4016       __thousands_sep_(',')
4017 {
4018 }
4019 
4020 numpunct<wchar_t>::numpunct(size_t refs)
4021     : locale::facet(refs),
4022       __decimal_point_(L'.'),
4023       __thousands_sep_(L',')
4024 {
4025 }
4026 
4027 numpunct<char>::~numpunct()
4028 {
4029 }
4030 
4031 numpunct<wchar_t>::~numpunct()
4032 {
4033 }
4034 
4035  char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}
4036 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4037 
4038  char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}
4039 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4040 
4041 string numpunct< char  >::do_grouping() const {return __grouping_;}
4042 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4043 
4044  string numpunct< char  >::do_truename() const {return "true";}
4045 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4046 
4047  string numpunct< char  >::do_falsename() const {return "false";}
4048 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4049 
4050 // numpunct_byname<char>
4051 
4052 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4053     : numpunct<char>(refs)
4054 {
4055     __init(nm);
4056 }
4057 
4058 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4059     : numpunct<char>(refs)
4060 {
4061     __init(nm.c_str());
4062 }
4063 
4064 numpunct_byname<char>::~numpunct_byname()
4065 {
4066 }
4067 
4068 void
4069 numpunct_byname<char>::__init(const char* nm)
4070 {
4071     if (strcmp(nm, "C") != 0)
4072     {
4073         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4074 #ifndef _LIBCPP_NO_EXCEPTIONS
4075         if (loc == 0)
4076             throw runtime_error("numpunct_byname<char>::numpunct_byname"
4077                                 " failed to construct for " + string(nm));
4078 #endif  // _LIBCPP_NO_EXCEPTIONS
4079 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4080         lconv* lc = localeconv_l(loc.get());
4081 #else
4082         lconv* lc = __localeconv_l(loc.get());
4083 #endif
4084         if (*lc->decimal_point)
4085             __decimal_point_ = *lc->decimal_point;
4086         if (*lc->thousands_sep)
4087             __thousands_sep_ = *lc->thousands_sep;
4088         __grouping_ = lc->grouping;
4089         // localization for truename and falsename is not available
4090     }
4091 }
4092 
4093 // numpunct_byname<wchar_t>
4094 
4095 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4096     : numpunct<wchar_t>(refs)
4097 {
4098     __init(nm);
4099 }
4100 
4101 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4102     : numpunct<wchar_t>(refs)
4103 {
4104     __init(nm.c_str());
4105 }
4106 
4107 numpunct_byname<wchar_t>::~numpunct_byname()
4108 {
4109 }
4110 
4111 void
4112 numpunct_byname<wchar_t>::__init(const char* nm)
4113 {
4114     if (strcmp(nm, "C") != 0)
4115     {
4116         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4117 #ifndef _LIBCPP_NO_EXCEPTIONS
4118         if (loc == 0)
4119             throw runtime_error("numpunct_byname<char>::numpunct_byname"
4120                                 " failed to construct for " + string(nm));
4121 #endif  // _LIBCPP_NO_EXCEPTIONS
4122 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4123         lconv* lc = localeconv_l(loc.get());
4124 #else
4125         lconv* lc = __localeconv_l(loc.get());
4126 #endif
4127         if (*lc->decimal_point)
4128             __decimal_point_ = *lc->decimal_point;
4129         if (*lc->thousands_sep)
4130             __thousands_sep_ = *lc->thousands_sep;
4131         __grouping_ = lc->grouping;
4132         // locallization for truename and falsename is not available
4133     }
4134 }
4135 
4136 // num_get helpers
4137 
4138 int
4139 __num_get_base::__get_base(ios_base& iob)
4140 {
4141     ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4142     if (__basefield == ios_base::oct)
4143         return 8;
4144     else if (__basefield == ios_base::hex)
4145         return 16;
4146     else if (__basefield == 0)
4147         return 0;
4148     return 10;
4149 }
4150 
4151 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4152 
4153 void
4154 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4155                  ios_base::iostate& __err)
4156 {
4157     if (__grouping.size() != 0)
4158     {
4159         reverse(__g, __g_end);
4160         const char* __ig = __grouping.data();
4161         const char* __eg = __ig + __grouping.size();
4162         for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4163         {
4164             if (0 < *__ig && *__ig < numeric_limits<char>::max())
4165             {
4166                 if (static_cast<unsigned>(*__ig) != *__r)
4167                 {
4168                     __err = ios_base::failbit;
4169                     return;
4170                 }
4171             }
4172             if (__eg - __ig > 1)
4173                 ++__ig;
4174         }
4175         if (0 < *__ig && *__ig < numeric_limits<char>::max())
4176         {
4177             if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4178                 __err = ios_base::failbit;
4179         }
4180     }
4181 }
4182 
4183 void
4184 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4185                              ios_base::fmtflags __flags)
4186 {
4187     if (__flags & ios_base::showpos)
4188         *__fmtp++ = '+';
4189     if (__flags & ios_base::showbase)
4190         *__fmtp++ = '#';
4191     while(*__len)
4192         *__fmtp++ = *__len++;
4193     if ((__flags & ios_base::basefield) == ios_base::oct)
4194         *__fmtp = 'o';
4195     else if ((__flags & ios_base::basefield) == ios_base::hex)
4196     {
4197         if (__flags & ios_base::uppercase)
4198             *__fmtp = 'X';
4199         else
4200             *__fmtp = 'x';
4201     }
4202     else if (__signd)
4203         *__fmtp = 'd';
4204     else
4205         *__fmtp = 'u';
4206 }
4207 
4208 bool
4209 __num_put_base::__format_float(char* __fmtp, const char* __len,
4210                                ios_base::fmtflags __flags)
4211 {
4212     bool specify_precision = true;
4213     if (__flags & ios_base::showpos)
4214         *__fmtp++ = '+';
4215     if (__flags & ios_base::showpoint)
4216         *__fmtp++ = '#';
4217     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4218     bool uppercase = __flags & ios_base::uppercase;
4219     if (floatfield == (ios_base::fixed | ios_base::scientific))
4220         specify_precision = false;
4221     else
4222     {
4223         *__fmtp++ = '.';
4224         *__fmtp++ = '*';
4225     }
4226     while(*__len)
4227         *__fmtp++ = *__len++;
4228     if (floatfield == ios_base::fixed)
4229     {
4230         if (uppercase)
4231             *__fmtp = 'F';
4232         else
4233             *__fmtp = 'f';
4234     }
4235     else if (floatfield == ios_base::scientific)
4236     {
4237         if (uppercase)
4238             *__fmtp = 'E';
4239         else
4240             *__fmtp = 'e';
4241     }
4242     else if (floatfield == (ios_base::fixed | ios_base::scientific))
4243     {
4244         if (uppercase)
4245             *__fmtp = 'A';
4246         else
4247             *__fmtp = 'a';
4248     }
4249     else
4250     {
4251         if (uppercase)
4252             *__fmtp = 'G';
4253         else
4254             *__fmtp = 'g';
4255     }
4256     return specify_precision;
4257 }
4258 
4259 char*
4260 __num_put_base::__identify_padding(char* __nb, char* __ne,
4261                                    const ios_base& __iob)
4262 {
4263     switch (__iob.flags() & ios_base::adjustfield)
4264     {
4265     case ios_base::internal:
4266         if (__nb[0] == '-' || __nb[0] == '+')
4267             return __nb+1;
4268         if (__ne - __nb >= 2 && __nb[0] == '0'
4269                             && (__nb[1] == 'x' || __nb[1] == 'X'))
4270             return __nb+2;
4271         break;
4272     case ios_base::left:
4273         return __ne;
4274     case ios_base::right:
4275     default:
4276         break;
4277     }
4278     return __nb;
4279 }
4280 
4281 // time_get
4282 
4283 static
4284 string*
4285 init_weeks()
4286 {
4287     static string weeks[14];
4288     weeks[0]  = "Sunday";
4289     weeks[1]  = "Monday";
4290     weeks[2]  = "Tuesday";
4291     weeks[3]  = "Wednesday";
4292     weeks[4]  = "Thursday";
4293     weeks[5]  = "Friday";
4294     weeks[6]  = "Saturday";
4295     weeks[7]  = "Sun";
4296     weeks[8]  = "Mon";
4297     weeks[9]  = "Tue";
4298     weeks[10] = "Wed";
4299     weeks[11] = "Thu";
4300     weeks[12] = "Fri";
4301     weeks[13] = "Sat";
4302     return weeks;
4303 }
4304 
4305 static
4306 wstring*
4307 init_wweeks()
4308 {
4309     static wstring weeks[14];
4310     weeks[0]  = L"Sunday";
4311     weeks[1]  = L"Monday";
4312     weeks[2]  = L"Tuesday";
4313     weeks[3]  = L"Wednesday";
4314     weeks[4]  = L"Thursday";
4315     weeks[5]  = L"Friday";
4316     weeks[6]  = L"Saturday";
4317     weeks[7]  = L"Sun";
4318     weeks[8]  = L"Mon";
4319     weeks[9]  = L"Tue";
4320     weeks[10] = L"Wed";
4321     weeks[11] = L"Thu";
4322     weeks[12] = L"Fri";
4323     weeks[13] = L"Sat";
4324     return weeks;
4325 }
4326 
4327 template <>
4328 const string*
4329 __time_get_c_storage<char>::__weeks() const
4330 {
4331     static const string* weeks = init_weeks();
4332     return weeks;
4333 }
4334 
4335 template <>
4336 const wstring*
4337 __time_get_c_storage<wchar_t>::__weeks() const
4338 {
4339     static const wstring* weeks = init_wweeks();
4340     return weeks;
4341 }
4342 
4343 static
4344 string*
4345 init_months()
4346 {
4347     static string months[24];
4348     months[0]  = "January";
4349     months[1]  = "February";
4350     months[2]  = "March";
4351     months[3]  = "April";
4352     months[4]  = "May";
4353     months[5]  = "June";
4354     months[6]  = "July";
4355     months[7]  = "August";
4356     months[8]  = "September";
4357     months[9]  = "October";
4358     months[10] = "November";
4359     months[11] = "December";
4360     months[12] = "Jan";
4361     months[13] = "Feb";
4362     months[14] = "Mar";
4363     months[15] = "Apr";
4364     months[16] = "May";
4365     months[17] = "Jun";
4366     months[18] = "Jul";
4367     months[19] = "Aug";
4368     months[20] = "Sep";
4369     months[21] = "Oct";
4370     months[22] = "Nov";
4371     months[23] = "Dec";
4372     return months;
4373 }
4374 
4375 static
4376 wstring*
4377 init_wmonths()
4378 {
4379     static wstring months[24];
4380     months[0]  = L"January";
4381     months[1]  = L"February";
4382     months[2]  = L"March";
4383     months[3]  = L"April";
4384     months[4]  = L"May";
4385     months[5]  = L"June";
4386     months[6]  = L"July";
4387     months[7]  = L"August";
4388     months[8]  = L"September";
4389     months[9]  = L"October";
4390     months[10] = L"November";
4391     months[11] = L"December";
4392     months[12] = L"Jan";
4393     months[13] = L"Feb";
4394     months[14] = L"Mar";
4395     months[15] = L"Apr";
4396     months[16] = L"May";
4397     months[17] = L"Jun";
4398     months[18] = L"Jul";
4399     months[19] = L"Aug";
4400     months[20] = L"Sep";
4401     months[21] = L"Oct";
4402     months[22] = L"Nov";
4403     months[23] = L"Dec";
4404     return months;
4405 }
4406 
4407 template <>
4408 const string*
4409 __time_get_c_storage<char>::__months() const
4410 {
4411     static const string* months = init_months();
4412     return months;
4413 }
4414 
4415 template <>
4416 const wstring*
4417 __time_get_c_storage<wchar_t>::__months() const
4418 {
4419     static const wstring* months = init_wmonths();
4420     return months;
4421 }
4422 
4423 static
4424 string*
4425 init_am_pm()
4426 {
4427     static string am_pm[24];
4428     am_pm[0]  = "AM";
4429     am_pm[1]  = "PM";
4430     return am_pm;
4431 }
4432 
4433 static
4434 wstring*
4435 init_wam_pm()
4436 {
4437     static wstring am_pm[24];
4438     am_pm[0]  = L"AM";
4439     am_pm[1]  = L"PM";
4440     return am_pm;
4441 }
4442 
4443 template <>
4444 const string*
4445 __time_get_c_storage<char>::__am_pm() const
4446 {
4447     static const string* am_pm = init_am_pm();
4448     return am_pm;
4449 }
4450 
4451 template <>
4452 const wstring*
4453 __time_get_c_storage<wchar_t>::__am_pm() const
4454 {
4455     static const wstring* am_pm = init_wam_pm();
4456     return am_pm;
4457 }
4458 
4459 template <>
4460 const string&
4461 __time_get_c_storage<char>::__x() const
4462 {
4463     static string s("%m/%d/%y");
4464     return s;
4465 }
4466 
4467 template <>
4468 const wstring&
4469 __time_get_c_storage<wchar_t>::__x() const
4470 {
4471     static wstring s(L"%m/%d/%y");
4472     return s;
4473 }
4474 
4475 template <>
4476 const string&
4477 __time_get_c_storage<char>::__X() const
4478 {
4479     static string s("%H:%M:%S");
4480     return s;
4481 }
4482 
4483 template <>
4484 const wstring&
4485 __time_get_c_storage<wchar_t>::__X() const
4486 {
4487     static wstring s(L"%H:%M:%S");
4488     return s;
4489 }
4490 
4491 template <>
4492 const string&
4493 __time_get_c_storage<char>::__c() const
4494 {
4495     static string s("%a %b %d %H:%M:%S %Y");
4496     return s;
4497 }
4498 
4499 template <>
4500 const wstring&
4501 __time_get_c_storage<wchar_t>::__c() const
4502 {
4503     static wstring s(L"%a %b %d %H:%M:%S %Y");
4504     return s;
4505 }
4506 
4507 template <>
4508 const string&
4509 __time_get_c_storage<char>::__r() const
4510 {
4511     static string s("%I:%M:%S %p");
4512     return s;
4513 }
4514 
4515 template <>
4516 const wstring&
4517 __time_get_c_storage<wchar_t>::__r() const
4518 {
4519     static wstring s(L"%I:%M:%S %p");
4520     return s;
4521 }
4522 
4523 // time_get_byname
4524 
4525 __time_get::__time_get(const char* nm)
4526     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4527 {
4528 #ifndef _LIBCPP_NO_EXCEPTIONS
4529     if (__loc_ == 0)
4530         throw runtime_error("time_get_byname"
4531                             " failed to construct for " + string(nm));
4532 #endif  // _LIBCPP_NO_EXCEPTIONS
4533 }
4534 
4535 __time_get::__time_get(const string& nm)
4536     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4537 {
4538 #ifndef _LIBCPP_NO_EXCEPTIONS
4539     if (__loc_ == 0)
4540         throw runtime_error("time_get_byname"
4541                             " failed to construct for " + nm);
4542 #endif  // _LIBCPP_NO_EXCEPTIONS
4543 }
4544 
4545 __time_get::~__time_get()
4546 {
4547     freelocale(__loc_);
4548 }
4549 
4550 template <>
4551 string
4552 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4553 {
4554     tm t;
4555     t.tm_sec = 59;
4556     t.tm_min = 55;
4557     t.tm_hour = 23;
4558     t.tm_mday = 31;
4559     t.tm_mon = 11;
4560     t.tm_year = 161;
4561     t.tm_wday = 6;
4562     t.tm_yday = 364;
4563     t.tm_isdst = -1;
4564     char buf[100];
4565     char f[3] = {0};
4566     f[0] = '%';
4567     f[1] = fmt;
4568     size_t n = strftime_l(buf, 100, f, &t, __loc_);
4569     char* bb = buf;
4570     char* be = buf + n;
4571     string result;
4572     while (bb != be)
4573     {
4574         if (ct.is(ctype_base::space, *bb))
4575         {
4576             result.push_back(' ');
4577             for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4578                 ;
4579             continue;
4580         }
4581         char* w = bb;
4582         ios_base::iostate err = ios_base::goodbit;
4583         ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4584                                ct, err, false)
4585                                - this->__weeks_;
4586         if (i < 14)
4587         {
4588             result.push_back('%');
4589             if (i < 7)
4590                 result.push_back('A');
4591             else
4592                 result.push_back('a');
4593             bb = w;
4594             continue;
4595         }
4596         w = bb;
4597         i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4598                            ct, err, false)
4599                            - this->__months_;
4600         if (i < 24)
4601         {
4602             result.push_back('%');
4603             if (i < 12)
4604                 result.push_back('B');
4605             else
4606                 result.push_back('b');
4607             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4608                 result.back() = 'm';
4609             bb = w;
4610             continue;
4611         }
4612         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4613         {
4614             w = bb;
4615             i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4616                                ct, err, false) - this->__am_pm_;
4617             if (i < 2)
4618             {
4619                 result.push_back('%');
4620                 result.push_back('p');
4621                 bb = w;
4622                 continue;
4623             }
4624         }
4625         w = bb;
4626         if (ct.is(ctype_base::digit, *bb))
4627         {
4628             switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4629             {
4630             case 6:
4631                 result.push_back('%');
4632                 result.push_back('w');
4633                 break;
4634             case 7:
4635                 result.push_back('%');
4636                 result.push_back('u');
4637                 break;
4638             case 11:
4639                 result.push_back('%');
4640                 result.push_back('I');
4641                 break;
4642             case 12:
4643                 result.push_back('%');
4644                 result.push_back('m');
4645                 break;
4646             case 23:
4647                 result.push_back('%');
4648                 result.push_back('H');
4649                 break;
4650             case 31:
4651                 result.push_back('%');
4652                 result.push_back('d');
4653                 break;
4654             case 55:
4655                 result.push_back('%');
4656                 result.push_back('M');
4657                 break;
4658             case 59:
4659                 result.push_back('%');
4660                 result.push_back('S');
4661                 break;
4662             case 61:
4663                 result.push_back('%');
4664                 result.push_back('y');
4665                 break;
4666             case 364:
4667                 result.push_back('%');
4668                 result.push_back('j');
4669                 break;
4670             case 2061:
4671                 result.push_back('%');
4672                 result.push_back('Y');
4673                 break;
4674             default:
4675                 for (; w != bb; ++w)
4676                     result.push_back(*w);
4677                 break;
4678             }
4679             continue;
4680         }
4681         if (*bb == '%')
4682         {
4683             result.push_back('%');
4684             result.push_back('%');
4685             ++bb;
4686             continue;
4687         }
4688         result.push_back(*bb);
4689         ++bb;
4690     }
4691     return result;
4692 }
4693 
4694 #pragma clang diagnostic ignored "-Wmissing-braces"
4695 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4696 
4697 template <>
4698 wstring
4699 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4700 {
4701     tm t;
4702     t.tm_sec = 59;
4703     t.tm_min = 55;
4704     t.tm_hour = 23;
4705     t.tm_mday = 31;
4706     t.tm_mon = 11;
4707     t.tm_year = 161;
4708     t.tm_wday = 6;
4709     t.tm_yday = 364;
4710     t.tm_isdst = -1;
4711     char buf[100];
4712     char f[3] = {0};
4713     f[0] = '%';
4714     f[1] = fmt;
4715     strftime_l(buf, 100, f, &t, __loc_);
4716     wchar_t wbuf[100];
4717     wchar_t* wbb = wbuf;
4718     mbstate_t mb = {0};
4719     const char* bb = buf;
4720 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4721     size_t j = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4722 #else
4723     size_t j = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4724 #endif
4725     if (j == size_t(-1))
4726         __throw_runtime_error("locale not supported");
4727     wchar_t* wbe = wbb + j;
4728     wstring result;
4729     while (wbb != wbe)
4730     {
4731         if (ct.is(ctype_base::space, *wbb))
4732         {
4733             result.push_back(L' ');
4734             for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4735                 ;
4736             continue;
4737         }
4738         wchar_t* w = wbb;
4739         ios_base::iostate err = ios_base::goodbit;
4740         ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4741                                ct, err, false)
4742                                - this->__weeks_;
4743         if (i < 14)
4744         {
4745             result.push_back(L'%');
4746             if (i < 7)
4747                 result.push_back(L'A');
4748             else
4749                 result.push_back(L'a');
4750             wbb = w;
4751             continue;
4752         }
4753         w = wbb;
4754         i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4755                            ct, err, false)
4756                            - this->__months_;
4757         if (i < 24)
4758         {
4759             result.push_back(L'%');
4760             if (i < 12)
4761                 result.push_back(L'B');
4762             else
4763                 result.push_back(L'b');
4764             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4765                 result.back() = L'm';
4766             wbb = w;
4767             continue;
4768         }
4769         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4770         {
4771             w = wbb;
4772             i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4773                                ct, err, false) - this->__am_pm_;
4774             if (i < 2)
4775             {
4776                 result.push_back(L'%');
4777                 result.push_back(L'p');
4778                 wbb = w;
4779                 continue;
4780             }
4781         }
4782         w = wbb;
4783         if (ct.is(ctype_base::digit, *wbb))
4784         {
4785             switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4786             {
4787             case 6:
4788                 result.push_back(L'%');
4789                 result.push_back(L'w');
4790                 break;
4791             case 7:
4792                 result.push_back(L'%');
4793                 result.push_back(L'u');
4794                 break;
4795             case 11:
4796                 result.push_back(L'%');
4797                 result.push_back(L'I');
4798                 break;
4799             case 12:
4800                 result.push_back(L'%');
4801                 result.push_back(L'm');
4802                 break;
4803             case 23:
4804                 result.push_back(L'%');
4805                 result.push_back(L'H');
4806                 break;
4807             case 31:
4808                 result.push_back(L'%');
4809                 result.push_back(L'd');
4810                 break;
4811             case 55:
4812                 result.push_back(L'%');
4813                 result.push_back(L'M');
4814                 break;
4815             case 59:
4816                 result.push_back(L'%');
4817                 result.push_back(L'S');
4818                 break;
4819             case 61:
4820                 result.push_back(L'%');
4821                 result.push_back(L'y');
4822                 break;
4823             case 364:
4824                 result.push_back(L'%');
4825                 result.push_back(L'j');
4826                 break;
4827             case 2061:
4828                 result.push_back(L'%');
4829                 result.push_back(L'Y');
4830                 break;
4831             default:
4832                 for (; w != wbb; ++w)
4833                     result.push_back(*w);
4834                 break;
4835             }
4836             continue;
4837         }
4838         if (ct.narrow(*wbb, 0) == '%')
4839         {
4840             result.push_back(L'%');
4841             result.push_back(L'%');
4842             ++wbb;
4843             continue;
4844         }
4845         result.push_back(*wbb);
4846         ++wbb;
4847     }
4848     return result;
4849 }
4850 
4851 template <>
4852 void
4853 __time_get_storage<char>::init(const ctype<char>& ct)
4854 {
4855     tm t;
4856     char buf[100];
4857     // __weeks_
4858     for (int i = 0; i < 7; ++i)
4859     {
4860         t.tm_wday = i;
4861         strftime_l(buf, 100, "%A", &t, __loc_);
4862         __weeks_[i] = buf;
4863         strftime_l(buf, 100, "%a", &t, __loc_);
4864         __weeks_[i+7] = buf;
4865     }
4866     // __months_
4867     for (int i = 0; i < 12; ++i)
4868     {
4869         t.tm_mon = i;
4870         strftime_l(buf, 100, "%B", &t, __loc_);
4871         __months_[i] = buf;
4872         strftime_l(buf, 100, "%b", &t, __loc_);
4873         __months_[i+12] = buf;
4874     }
4875     // __am_pm_
4876     t.tm_hour = 1;
4877     strftime_l(buf, 100, "%p", &t, __loc_);
4878     __am_pm_[0] = buf;
4879     t.tm_hour = 13;
4880     strftime_l(buf, 100, "%p", &t, __loc_);
4881     __am_pm_[1] = buf;
4882     __c_ = __analyze('c', ct);
4883     __r_ = __analyze('r', ct);
4884     __x_ = __analyze('x', ct);
4885     __X_ = __analyze('X', ct);
4886 }
4887 
4888 template <>
4889 void
4890 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
4891 {
4892     tm t = {0};
4893     char buf[100];
4894     size_t be;
4895     wchar_t wbuf[100];
4896     wchar_t* wbe;
4897     mbstate_t mb = {0};
4898     // __weeks_
4899     for (int i = 0; i < 7; ++i)
4900     {
4901         t.tm_wday = i;
4902         be = strftime_l(buf, 100, "%A", &t, __loc_);
4903         mb = mbstate_t();
4904         const char* bb = buf;
4905 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4906         size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4907 #else
4908         size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4909 #endif
4910         if (j == size_t(-1))
4911             __throw_runtime_error("locale not supported");
4912         wbe = wbuf + j;
4913         __weeks_[i].assign(wbuf, wbe);
4914         be = strftime_l(buf, 100, "%a", &t, __loc_);
4915         mb = mbstate_t();
4916         bb = buf;
4917 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4918         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4919 #else
4920         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4921 #endif
4922         if (j == size_t(-1))
4923             __throw_runtime_error("locale not supported");
4924         wbe = wbuf + j;
4925         __weeks_[i+7].assign(wbuf, wbe);
4926     }
4927     // __months_
4928     for (int i = 0; i < 12; ++i)
4929     {
4930         t.tm_mon = i;
4931         be = strftime_l(buf, 100, "%B", &t, __loc_);
4932         mb = mbstate_t();
4933         const char* bb = buf;
4934 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4935         size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4936 #else
4937         size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4938 #endif
4939         if (j == size_t(-1))
4940             __throw_runtime_error("locale not supported");
4941         wbe = wbuf + j;
4942         __months_[i].assign(wbuf, wbe);
4943         be = strftime_l(buf, 100, "%b", &t, __loc_);
4944         mb = mbstate_t();
4945         bb = buf;
4946 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4947         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4948 #else
4949         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4950 #endif
4951         if (j == size_t(-1))
4952             __throw_runtime_error("locale not supported");
4953         wbe = wbuf + j;
4954         __months_[i+12].assign(wbuf, wbe);
4955     }
4956     // __am_pm_
4957     t.tm_hour = 1;
4958     be = strftime_l(buf, 100, "%p", &t, __loc_);
4959     mb = mbstate_t();
4960     const char* bb = buf;
4961 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4962     size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4963 #else
4964     size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4965 #endif
4966     if (j == size_t(-1))
4967         __throw_runtime_error("locale not supported");
4968     wbe = wbuf + j;
4969     __am_pm_[0].assign(wbuf, wbe);
4970     t.tm_hour = 13;
4971     be = strftime_l(buf, 100, "%p", &t, __loc_);
4972     mb = mbstate_t();
4973     bb = buf;
4974 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4975     j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4976 #else
4977     j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_);
4978 #endif
4979     if (j == size_t(-1))
4980         __throw_runtime_error("locale not supported");
4981     wbe = wbuf + j;
4982     __am_pm_[1].assign(wbuf, wbe);
4983     __c_ = __analyze('c', ct);
4984     __r_ = __analyze('r', ct);
4985     __x_ = __analyze('x', ct);
4986     __X_ = __analyze('X', ct);
4987 }
4988 
4989 template <class CharT>
4990 struct _LIBCPP_HIDDEN __time_get_temp
4991     : public ctype_byname<CharT>
4992 {
4993     explicit __time_get_temp(const char* nm)
4994         : ctype_byname<CharT>(nm, 1) {}
4995     explicit __time_get_temp(const string& nm)
4996         : ctype_byname<CharT>(nm, 1) {}
4997 };
4998 
4999 template <>
5000 __time_get_storage<char>::__time_get_storage(const char* __nm)
5001     : __time_get(__nm)
5002 {
5003     const __time_get_temp<char> ct(__nm);
5004     init(ct);
5005 }
5006 
5007 template <>
5008 __time_get_storage<char>::__time_get_storage(const string& __nm)
5009     : __time_get(__nm)
5010 {
5011     const __time_get_temp<char> ct(__nm);
5012     init(ct);
5013 }
5014 
5015 template <>
5016 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5017     : __time_get(__nm)
5018 {
5019     const __time_get_temp<wchar_t> ct(__nm);
5020     init(ct);
5021 }
5022 
5023 template <>
5024 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5025     : __time_get(__nm)
5026 {
5027     const __time_get_temp<wchar_t> ct(__nm);
5028     init(ct);
5029 }
5030 
5031 template <>
5032 time_base::dateorder
5033 __time_get_storage<char>::__do_date_order() const
5034 {
5035     unsigned i;
5036     for (i = 0; i < __x_.size(); ++i)
5037         if (__x_[i] == '%')
5038             break;
5039     ++i;
5040     switch (__x_[i])
5041     {
5042     case 'y':
5043     case 'Y':
5044         for (++i; i < __x_.size(); ++i)
5045             if (__x_[i] == '%')
5046                 break;
5047         if (i == __x_.size())
5048             break;
5049         ++i;
5050         switch (__x_[i])
5051         {
5052         case 'm':
5053             for (++i; i < __x_.size(); ++i)
5054                 if (__x_[i] == '%')
5055                     break;
5056             if (i == __x_.size())
5057                 break;
5058             ++i;
5059             if (__x_[i] == 'd')
5060                 return time_base::ymd;
5061             break;
5062         case 'd':
5063             for (++i; i < __x_.size(); ++i)
5064                 if (__x_[i] == '%')
5065                     break;
5066             if (i == __x_.size())
5067                 break;
5068             ++i;
5069             if (__x_[i] == 'm')
5070                 return time_base::ydm;
5071             break;
5072         }
5073         break;
5074     case 'm':
5075         for (++i; i < __x_.size(); ++i)
5076             if (__x_[i] == '%')
5077                 break;
5078         if (i == __x_.size())
5079             break;
5080         ++i;
5081         if (__x_[i] == 'd')
5082         {
5083             for (++i; i < __x_.size(); ++i)
5084                 if (__x_[i] == '%')
5085                     break;
5086             if (i == __x_.size())
5087                 break;
5088             ++i;
5089             if (__x_[i] == 'y' || __x_[i] == 'Y')
5090                 return time_base::mdy;
5091             break;
5092         }
5093         break;
5094     case 'd':
5095         for (++i; i < __x_.size(); ++i)
5096             if (__x_[i] == '%')
5097                 break;
5098         if (i == __x_.size())
5099             break;
5100         ++i;
5101         if (__x_[i] == 'm')
5102         {
5103             for (++i; i < __x_.size(); ++i)
5104                 if (__x_[i] == '%')
5105                     break;
5106             if (i == __x_.size())
5107                 break;
5108             ++i;
5109             if (__x_[i] == 'y' || __x_[i] == 'Y')
5110                 return time_base::dmy;
5111             break;
5112         }
5113         break;
5114     }
5115     return time_base::no_order;
5116 }
5117 
5118 template <>
5119 time_base::dateorder
5120 __time_get_storage<wchar_t>::__do_date_order() const
5121 {
5122     unsigned i;
5123     for (i = 0; i < __x_.size(); ++i)
5124         if (__x_[i] == L'%')
5125             break;
5126     ++i;
5127     switch (__x_[i])
5128     {
5129     case L'y':
5130     case L'Y':
5131         for (++i; i < __x_.size(); ++i)
5132             if (__x_[i] == L'%')
5133                 break;
5134         if (i == __x_.size())
5135             break;
5136         ++i;
5137         switch (__x_[i])
5138         {
5139         case L'm':
5140             for (++i; i < __x_.size(); ++i)
5141                 if (__x_[i] == L'%')
5142                     break;
5143             if (i == __x_.size())
5144                 break;
5145             ++i;
5146             if (__x_[i] == L'd')
5147                 return time_base::ymd;
5148             break;
5149         case L'd':
5150             for (++i; i < __x_.size(); ++i)
5151                 if (__x_[i] == L'%')
5152                     break;
5153             if (i == __x_.size())
5154                 break;
5155             ++i;
5156             if (__x_[i] == L'm')
5157                 return time_base::ydm;
5158             break;
5159         }
5160         break;
5161     case L'm':
5162         for (++i; i < __x_.size(); ++i)
5163             if (__x_[i] == L'%')
5164                 break;
5165         if (i == __x_.size())
5166             break;
5167         ++i;
5168         if (__x_[i] == L'd')
5169         {
5170             for (++i; i < __x_.size(); ++i)
5171                 if (__x_[i] == L'%')
5172                     break;
5173             if (i == __x_.size())
5174                 break;
5175             ++i;
5176             if (__x_[i] == L'y' || __x_[i] == L'Y')
5177                 return time_base::mdy;
5178             break;
5179         }
5180         break;
5181     case L'd':
5182         for (++i; i < __x_.size(); ++i)
5183             if (__x_[i] == L'%')
5184                 break;
5185         if (i == __x_.size())
5186             break;
5187         ++i;
5188         if (__x_[i] == L'm')
5189         {
5190             for (++i; i < __x_.size(); ++i)
5191                 if (__x_[i] == L'%')
5192                     break;
5193             if (i == __x_.size())
5194                 break;
5195             ++i;
5196             if (__x_[i] == L'y' || __x_[i] == L'Y')
5197                 return time_base::dmy;
5198             break;
5199         }
5200         break;
5201     }
5202     return time_base::no_order;
5203 }
5204 
5205 // time_put
5206 
5207 __time_put::__time_put(const char* nm)
5208     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5209 {
5210 #ifndef _LIBCPP_NO_EXCEPTIONS
5211     if (__loc_ == 0)
5212         throw runtime_error("time_put_byname"
5213                             " failed to construct for " + string(nm));
5214 #endif  // _LIBCPP_NO_EXCEPTIONS
5215 }
5216 
5217 __time_put::__time_put(const string& nm)
5218     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5219 {
5220 #ifndef _LIBCPP_NO_EXCEPTIONS
5221     if (__loc_ == 0)
5222         throw runtime_error("time_put_byname"
5223                             " failed to construct for " + nm);
5224 #endif  // _LIBCPP_NO_EXCEPTIONS
5225 }
5226 
5227 __time_put::~__time_put()
5228 {
5229     if (__loc_)
5230         freelocale(__loc_);
5231 }
5232 
5233 void
5234 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5235                      char __fmt, char __mod) const
5236 {
5237     char fmt[] = {'%', __fmt, __mod, 0};
5238     if (__mod != 0)
5239         swap(fmt[1], fmt[2]);
5240     size_t n = strftime_l(__nb, static_cast<size_t>(__ne-__nb), fmt, __tm, __loc_);
5241     __ne = __nb + n;
5242 }
5243 
5244 void
5245 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5246                      char __fmt, char __mod) const
5247 {
5248     char __nar[100];
5249     char* __ne = __nar + 100;
5250     __do_put(__nar, __ne, __tm, __fmt, __mod);
5251     mbstate_t mb = {0};
5252     const char* __nb = __nar;
5253 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5254     size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5255 #else
5256     size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_);
5257 #endif
5258     if (j == size_t(-1))
5259         __throw_runtime_error("locale not supported");
5260     __we = __wb + j;
5261 }
5262 
5263 // moneypunct_byname
5264 
5265 static
5266 void
5267 __init_pat(money_base::pattern& pat, char cs_precedes, char sep_by_space, char sign_posn)
5268 {
5269     const char sign = static_cast<char>(money_base::sign);
5270     const char space = static_cast<char>(money_base::space);
5271     const char none = static_cast<char>(money_base::none);
5272     const char symbol = static_cast<char>(money_base::symbol);
5273     const char value = static_cast<char>(money_base::value);
5274     switch (cs_precedes)
5275     {
5276     case 0:
5277         switch (sign_posn)
5278         {
5279         case 0:
5280             pat.field[0] = sign;
5281             pat.field[1] = value;
5282             pat.field[3] = symbol;
5283             switch (sep_by_space)
5284             {
5285             case 0:
5286                 pat.field[2] = none;
5287                 return;
5288             case 1:
5289             case 2:
5290                 pat.field[2] = space;
5291                 return;
5292             default:
5293                 break;
5294             }
5295             break;
5296         case 1:
5297             pat.field[0] = sign;
5298             pat.field[3] = symbol;
5299             switch (sep_by_space)
5300             {
5301             case 0:
5302                 pat.field[1] = value;
5303                 pat.field[2] = none;
5304                 return;
5305             case 1:
5306                 pat.field[1] = value;
5307                 pat.field[2] = space;
5308                 return;
5309             case 2:
5310                 pat.field[1] = space;
5311                 pat.field[2] = value;
5312                 return;
5313             default:
5314                 break;
5315             }
5316             break;
5317         case 2:
5318             pat.field[0] = value;
5319             pat.field[3] = sign;
5320             switch (sep_by_space)
5321             {
5322             case 0:
5323                 pat.field[1] = none;
5324                 pat.field[2] = symbol;
5325                 return;
5326             case 1:
5327                 pat.field[1] = space;
5328                 pat.field[2] = symbol;
5329                 return;
5330             case 2:
5331                 pat.field[1] = symbol;
5332                 pat.field[2] = space;
5333                 return;
5334             default:
5335                 break;
5336             }
5337             break;
5338         case 3:
5339             pat.field[0] = value;
5340             pat.field[3] = symbol;
5341             switch (sep_by_space)
5342             {
5343             case 0:
5344                 pat.field[1] = none;
5345                 pat.field[2] = sign;
5346                 return;
5347             case 1:
5348                 pat.field[1] = space;
5349                 pat.field[2] = sign;
5350                 return;
5351             case 2:
5352                 pat.field[1] = sign;
5353                 pat.field[2] = space;
5354                 return;
5355             default:
5356                 break;
5357             }
5358             break;
5359         case 4:
5360             pat.field[0] = value;
5361             pat.field[3] = sign;
5362             switch (sep_by_space)
5363             {
5364             case 0:
5365                 pat.field[1] = none;
5366                 pat.field[2] = symbol;
5367                 return;
5368             case 1:
5369                 pat.field[1] = space;
5370                 pat.field[2] = symbol;
5371                 return;
5372             case 2:
5373                 pat.field[1] = symbol;
5374                 pat.field[2] = space;
5375                 return;
5376             default:
5377                 break;
5378             }
5379             break;
5380         default:
5381             break;
5382         }
5383         break;
5384     case 1:
5385         switch (sign_posn)
5386         {
5387         case 0:
5388             pat.field[0] = sign;
5389             pat.field[1] = symbol;
5390             pat.field[3] = value;
5391             switch (sep_by_space)
5392             {
5393             case 0:
5394                 pat.field[2] = none;
5395                 return;
5396             case 1:
5397             case 2:
5398                 pat.field[2] = space;
5399                 return;
5400             default:
5401                 break;
5402             }
5403             break;
5404         case 1:
5405             pat.field[0] = sign;
5406             pat.field[3] = value;
5407             switch (sep_by_space)
5408             {
5409             case 0:
5410                 pat.field[1] = symbol;
5411                 pat.field[2] = none;
5412                 return;
5413             case 1:
5414                 pat.field[1] = symbol;
5415                 pat.field[2] = space;
5416                 return;
5417             case 2:
5418                 pat.field[1] = space;
5419                 pat.field[2] = symbol;
5420                 return;
5421             default:
5422                 break;
5423             }
5424             break;
5425         case 2:
5426             pat.field[0] = symbol;
5427             pat.field[3] = sign;
5428             switch (sep_by_space)
5429             {
5430             case 0:
5431                 pat.field[1] = none;
5432                 pat.field[2] = value;
5433                 return;
5434             case 1:
5435                 pat.field[1] = space;
5436                 pat.field[2] = value;
5437                 return;
5438             case 2:
5439                 pat.field[1] = value;
5440                 pat.field[2] = space;
5441                 return;
5442             default:
5443                 break;
5444             }
5445             break;
5446         case 3:
5447             pat.field[0] = sign;
5448             pat.field[3] = value;
5449             switch (sep_by_space)
5450             {
5451             case 0:
5452                 pat.field[1] = symbol;
5453                 pat.field[2] = none;
5454                 return;
5455             case 1:
5456                 pat.field[1] = symbol;
5457                 pat.field[2] = space;
5458                 return;
5459             case 2:
5460                 pat.field[1] = space;
5461                 pat.field[2] = symbol;
5462                 return;
5463             default:
5464                 break;
5465             }
5466             break;
5467         case 4:
5468             pat.field[0] = symbol;
5469             pat.field[3] = value;
5470             switch (sep_by_space)
5471             {
5472             case 0:
5473                 pat.field[1] = sign;
5474                 pat.field[2] = none;
5475                 return;
5476             case 1:
5477                 pat.field[1] = sign;
5478                 pat.field[2] = space;
5479                 return;
5480             case 2:
5481                 pat.field[1] = space;
5482                 pat.field[2] = sign;
5483                 return;
5484            default:
5485                 break;
5486             }
5487             break;
5488         default:
5489             break;
5490         }
5491         break;
5492     default:
5493         break;
5494     }
5495     pat.field[0] = symbol;
5496     pat.field[1] = sign;
5497     pat.field[2] = none;
5498     pat.field[3] = value;
5499 }
5500 
5501 template<>
5502 void
5503 moneypunct_byname<char, false>::init(const char* nm)
5504 {
5505     typedef moneypunct<char, false> base;
5506     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5507 #ifndef _LIBCPP_NO_EXCEPTIONS
5508     if (loc == 0)
5509         throw runtime_error("moneypunct_byname"
5510                             " failed to construct for " + string(nm));
5511 #endif  // _LIBCPP_NO_EXCEPTIONS
5512 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5513     lconv* lc = localeconv_l(loc.get());
5514 #else
5515     lconv* lc = __localeconv_l(loc.get());
5516 #endif
5517     if (*lc->mon_decimal_point)
5518         __decimal_point_ = *lc->mon_decimal_point;
5519     else
5520         __decimal_point_ = base::do_decimal_point();
5521     if (*lc->mon_thousands_sep)
5522         __thousands_sep_ = *lc->mon_thousands_sep;
5523     else
5524         __thousands_sep_ = base::do_thousands_sep();
5525     __grouping_ = lc->mon_grouping;
5526     __curr_symbol_ = lc->currency_symbol;
5527     if (lc->frac_digits != CHAR_MAX)
5528         __frac_digits_ = lc->frac_digits;
5529     else
5530         __frac_digits_ = base::do_frac_digits();
5531     if (lc->p_sign_posn == 0)
5532         __positive_sign_ = "()";
5533     else
5534         __positive_sign_ = lc->positive_sign;
5535     if (lc->n_sign_posn == 0)
5536         __negative_sign_ = "()";
5537     else
5538         __negative_sign_ = lc->negative_sign;
5539     __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5540     __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5541 }
5542 
5543 template<>
5544 void
5545 moneypunct_byname<char, true>::init(const char* nm)
5546 {
5547     typedef moneypunct<char, true> base;
5548     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5549 #ifndef _LIBCPP_NO_EXCEPTIONS
5550     if (loc == 0)
5551         throw runtime_error("moneypunct_byname"
5552                             " failed to construct for " + string(nm));
5553 #endif  // _LIBCPP_NO_EXCEPTIONS
5554 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5555     lconv* lc = localeconv_l(loc.get());
5556 #else
5557     lconv* lc = __localeconv_l(loc.get());
5558 #endif
5559     if (*lc->mon_decimal_point)
5560         __decimal_point_ = *lc->mon_decimal_point;
5561     else
5562         __decimal_point_ = base::do_decimal_point();
5563     if (*lc->mon_thousands_sep)
5564         __thousands_sep_ = *lc->mon_thousands_sep;
5565     else
5566         __thousands_sep_ = base::do_thousands_sep();
5567     __grouping_ = lc->mon_grouping;
5568     __curr_symbol_ = lc->int_curr_symbol;
5569     if (lc->int_frac_digits != CHAR_MAX)
5570         __frac_digits_ = lc->int_frac_digits;
5571     else
5572         __frac_digits_ = base::do_frac_digits();
5573 #if _WIN32
5574     if (lc->p_sign_posn == 0)
5575 #else // _WIN32
5576     if (lc->int_p_sign_posn == 0)
5577 #endif //_WIN32
5578         __positive_sign_ = "()";
5579     else
5580         __positive_sign_ = lc->positive_sign;
5581 #if _WIN32
5582     if(lc->n_sign_posn == 0)
5583 #else // _WIN32
5584     if (lc->int_n_sign_posn == 0)
5585 #endif // _WIN32
5586         __negative_sign_ = "()";
5587     else
5588         __negative_sign_ = lc->negative_sign;
5589 #if _WIN32
5590     __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5591     __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5592 #else
5593     __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5594     __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5595 #endif // _WIN32
5596 }
5597 
5598 template<>
5599 void
5600 moneypunct_byname<wchar_t, false>::init(const char* nm)
5601 {
5602     typedef moneypunct<wchar_t, false> base;
5603     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5604 #ifndef _LIBCPP_NO_EXCEPTIONS
5605     if (loc == 0)
5606         throw runtime_error("moneypunct_byname"
5607                             " failed to construct for " + string(nm));
5608 #endif  // _LIBCPP_NO_EXCEPTIONS
5609 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5610     lconv* lc = localeconv_l(loc.get());
5611 #else
5612     lconv* lc = __localeconv_l(loc.get());
5613 #endif
5614     if (*lc->mon_decimal_point)
5615         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5616     else
5617         __decimal_point_ = base::do_decimal_point();
5618     if (*lc->mon_thousands_sep)
5619         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5620     else
5621         __thousands_sep_ = base::do_thousands_sep();
5622     __grouping_ = lc->mon_grouping;
5623     wchar_t wbuf[100];
5624     mbstate_t mb = {0};
5625     const char* bb = lc->currency_symbol;
5626 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5627     size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5628 #else
5629     size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5630 #endif
5631     if (j == size_t(-1))
5632         __throw_runtime_error("locale not supported");
5633     wchar_t* wbe = wbuf + j;
5634     __curr_symbol_.assign(wbuf, wbe);
5635     if (lc->frac_digits != CHAR_MAX)
5636         __frac_digits_ = lc->frac_digits;
5637     else
5638         __frac_digits_ = base::do_frac_digits();
5639     if (lc->p_sign_posn == 0)
5640         __positive_sign_ = L"()";
5641     else
5642     {
5643         mb = mbstate_t();
5644         bb = lc->positive_sign;
5645 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5646         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5647 #else
5648         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5649 #endif
5650         if (j == size_t(-1))
5651             __throw_runtime_error("locale not supported");
5652         wbe = wbuf + j;
5653         __positive_sign_.assign(wbuf, wbe);
5654     }
5655     if (lc->n_sign_posn == 0)
5656         __negative_sign_ = L"()";
5657     else
5658     {
5659         mb = mbstate_t();
5660         bb = lc->negative_sign;
5661 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5662         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5663 #else
5664         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5665 #endif
5666         if (j == size_t(-1))
5667             __throw_runtime_error("locale not supported");
5668         wbe = wbuf + j;
5669         __negative_sign_.assign(wbuf, wbe);
5670     }
5671     __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5672     __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5673 }
5674 
5675 template<>
5676 void
5677 moneypunct_byname<wchar_t, true>::init(const char* nm)
5678 {
5679     typedef moneypunct<wchar_t, true> base;
5680     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5681 #ifndef _LIBCPP_NO_EXCEPTIONS
5682     if (loc == 0)
5683         throw runtime_error("moneypunct_byname"
5684                             " failed to construct for " + string(nm));
5685 #endif  // _LIBCPP_NO_EXCEPTIONS
5686 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5687     lconv* lc = localeconv_l(loc.get());
5688 #else
5689     lconv* lc = __localeconv_l(loc.get());
5690 #endif
5691     if (*lc->mon_decimal_point)
5692         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5693     else
5694         __decimal_point_ = base::do_decimal_point();
5695     if (*lc->mon_thousands_sep)
5696         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5697     else
5698         __thousands_sep_ = base::do_thousands_sep();
5699     __grouping_ = lc->mon_grouping;
5700     wchar_t wbuf[100];
5701     mbstate_t mb = {0};
5702     const char* bb = lc->int_curr_symbol;
5703 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5704     size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5705 #else
5706     size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5707 #endif
5708     if (j == size_t(-1))
5709         __throw_runtime_error("locale not supported");
5710     wchar_t* wbe = wbuf + j;
5711     __curr_symbol_.assign(wbuf, wbe);
5712     if (lc->int_frac_digits != CHAR_MAX)
5713         __frac_digits_ = lc->int_frac_digits;
5714     else
5715         __frac_digits_ = base::do_frac_digits();
5716 #if _WIN32
5717     if (lc->p_sign_posn == 0)
5718 #else // _WIN32
5719     if (lc->int_p_sign_posn == 0)
5720 #endif // _WIN32
5721         __positive_sign_ = L"()";
5722     else
5723     {
5724         mb = mbstate_t();
5725         bb = lc->positive_sign;
5726 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5727         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5728 #else
5729         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5730 #endif
5731         if (j == size_t(-1))
5732             __throw_runtime_error("locale not supported");
5733         wbe = wbuf + j;
5734         __positive_sign_.assign(wbuf, wbe);
5735     }
5736 #if _WIN32
5737     if (lc->n_sign_posn == 0)
5738 #else // _WIN32
5739     if (lc->int_n_sign_posn == 0)
5740 #endif // _WIN32
5741         __negative_sign_ = L"()";
5742     else
5743     {
5744         mb = mbstate_t();
5745         bb = lc->negative_sign;
5746 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5747         j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5748 #else
5749         j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get());
5750 #endif
5751         if (j == size_t(-1))
5752             __throw_runtime_error("locale not supported");
5753         wbe = wbuf + j;
5754         __negative_sign_.assign(wbuf, wbe);
5755     }
5756 #if _WIN32
5757     __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn);
5758     __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn);
5759 #else // _WIN32
5760     __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn);
5761     __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn);
5762 #endif // _WIN32
5763 }
5764 
5765 void __do_nothing(void*) {}
5766 
5767 void __throw_runtime_error(const char* msg)
5768 {
5769 #ifndef _LIBCPP_NO_EXCEPTIONS
5770     throw runtime_error(msg);
5771 #endif
5772 }
5773 
5774 template class collate<char>;
5775 template class collate<wchar_t>;
5776 
5777 template class num_get<char>;
5778 template class num_get<wchar_t>;
5779 
5780 template struct __num_get<char>;
5781 template struct __num_get<wchar_t>;
5782 
5783 template class num_put<char>;
5784 template class num_put<wchar_t>;
5785 
5786 template struct __num_put<char>;
5787 template struct __num_put<wchar_t>;
5788 
5789 template class time_get<char>;
5790 template class time_get<wchar_t>;
5791 
5792 template class time_get_byname<char>;
5793 template class time_get_byname<wchar_t>;
5794 
5795 template class time_put<char>;
5796 template class time_put<wchar_t>;
5797 
5798 template class time_put_byname<char>;
5799 template class time_put_byname<wchar_t>;
5800 
5801 template class moneypunct<char, false>;
5802 template class moneypunct<char, true>;
5803 template class moneypunct<wchar_t, false>;
5804 template class moneypunct<wchar_t, true>;
5805 
5806 template class moneypunct_byname<char, false>;
5807 template class moneypunct_byname<char, true>;
5808 template class moneypunct_byname<wchar_t, false>;
5809 template class moneypunct_byname<wchar_t, true>;
5810 
5811 template class money_get<char>;
5812 template class money_get<wchar_t>;
5813 
5814 template class __money_get<char>;
5815 template class __money_get<wchar_t>;
5816 
5817 template class money_put<char>;
5818 template class money_put<wchar_t>;
5819 
5820 template class __money_put<char>;
5821 template class __money_put<wchar_t>;
5822 
5823 template class messages<char>;
5824 template class messages<wchar_t>;
5825 
5826 template class messages_byname<char>;
5827 template class messages_byname<wchar_t>;
5828 
5829 template class codecvt_byname<char, char, mbstate_t>;
5830 template class codecvt_byname<wchar_t, char, mbstate_t>;
5831 template class codecvt_byname<char16_t, char, mbstate_t>;
5832 template class codecvt_byname<char32_t, char, mbstate_t>;
5833 
5834 template class __vector_base_common<true>;
5835 
5836 _LIBCPP_END_NAMESPACE_STD
5837