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