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