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