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