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