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