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