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