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