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