etc/services - sync with NetBSD-8
[minix.git] / external / bsd / libc++ / dist / libcxx / src / locale.cpp
bloba77fad8667e5b425a8003f39d0c7d06b747b4ce7
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 //===----------------------------------------------------------------------===//
10 // On Solaris, we need to define something to make the C99 parts of localeconv
11 // visible.
12 #ifdef __sun__
13 #define _LCONV_C99
14 #endif
16 #include "string"
17 #include "locale"
18 #include "codecvt"
19 #include "vector"
20 #include "algorithm"
21 #include "typeinfo"
22 #ifndef _LIBCPP_NO_EXCEPTIONS
23 # include "type_traits"
24 #endif
25 #include "clocale"
26 #include "cstring"
27 #include "cwctype"
28 #include "__sso_allocator"
29 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
30 #include "support/win32/locale_win32.h"
31 #elif !defined(__ANDROID__)
32 #include <langinfo.h>
33 #endif
34 #include <stdlib.h>
35 #include <stdio.h>
37 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
38 // lots of noise in the build log, but no bugs that I know of.
39 #if defined(__clang__)
40 #pragma clang diagnostic ignored "-Wsign-conversion"
41 #endif
43 _LIBCPP_BEGIN_NAMESPACE_STD
45 #ifdef __cloc_defined
46 locale_t __cloc() {
47 // In theory this could create a race condition. In practice
48 // the race condition is non-fatal since it will just create
49 // a little resource leak. Better approach would be appreciated.
50 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
51 return result;
53 #endif // __cloc_defined
55 namespace {
57 struct release
59 void operator()(locale::facet* p) {p->__release_shared();}
62 template <class T, class A0>
63 inline
65 make(A0 a0)
67 static typename aligned_storage<sizeof(T)>::type buf;
68 ::new (&buf) T(a0);
69 return *reinterpret_cast<T*>(&buf);
72 template <class T, class A0, class A1>
73 inline
75 make(A0 a0, A1 a1)
77 static typename aligned_storage<sizeof(T)>::type buf;
78 ::new (&buf) T(a0, a1);
79 return *reinterpret_cast<T*>(&buf);
82 template <class T, class A0, class A1, class A2>
83 inline
85 make(A0 a0, A1 a1, A2 a2)
87 static typename aligned_storage<sizeof(T)>::type buf;
88 ::new (&buf) T(a0, a1, a2);
89 return *reinterpret_cast<T*>(&buf);
92 template <typename T, size_t N>
93 inline
94 _LIBCPP_CONSTEXPR
95 size_t
96 countof(const T (&)[N])
98 return N;
101 template <typename T>
102 inline
103 _LIBCPP_CONSTEXPR
104 size_t
105 countof(const T * const begin, const T * const end)
107 return static_cast<size_t>(end - begin);
112 #if defined(_AIX)
113 // Set priority to INT_MIN + 256 + 150
114 # pragma priority ( -2147483242 )
115 #endif
117 const locale::category locale::none;
118 const locale::category locale::collate;
119 const locale::category locale::ctype;
120 const locale::category locale::monetary;
121 const locale::category locale::numeric;
122 const locale::category locale::time;
123 const locale::category locale::messages;
124 const locale::category locale::all;
126 #if defined(__clang__)
127 #pragma clang diagnostic push
128 #pragma clang diagnostic ignored "-Wpadded"
129 #endif
131 class _LIBCPP_HIDDEN locale::__imp
132 : public facet
134 enum {N = 28};
135 #if defined(_LIBCPP_MSVC)
136 // FIXME: MSVC doesn't support aligned parameters by value.
137 // I can't get the __sso_allocator to work here
138 // for MSVC I think for this reason.
139 vector<facet*> facets_;
140 #else
141 vector<facet*, __sso_allocator<facet*, N> > facets_;
142 #endif
143 string name_;
144 public:
145 explicit __imp(size_t refs = 0);
146 explicit __imp(const string& name, size_t refs = 0);
147 __imp(const __imp&);
148 __imp(const __imp&, const string&, locale::category c);
149 __imp(const __imp& other, const __imp& one, locale::category c);
150 __imp(const __imp&, facet* f, long id);
151 ~__imp();
153 const string& name() const {return name_;}
154 bool has_facet(long id) const
155 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
156 const locale::facet* use_facet(long id) const;
158 static const locale& make_classic();
159 static locale& make_global();
160 private:
161 void install(facet* f, long id);
162 template <class F> void install(F* f) {install(f, f->id.__get());}
163 template <class F> void install_from(const __imp& other);
166 #if defined(__clang__)
167 #pragma clang diagnostic pop
168 #endif
170 locale::__imp::__imp(size_t refs)
171 : facet(refs),
172 facets_(N),
173 name_("C")
175 facets_.clear();
176 install(&make<_VSTD::collate<char> >(1u));
177 install(&make<_VSTD::collate<wchar_t> >(1u));
178 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
179 install(&make<_VSTD::ctype<wchar_t> >(1u));
180 install(&make<codecvt<char, char, mbstate_t> >(1u));
181 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
182 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
183 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
184 install(&make<numpunct<char> >(1u));
185 install(&make<numpunct<wchar_t> >(1u));
186 install(&make<num_get<char> >(1u));
187 install(&make<num_get<wchar_t> >(1u));
188 install(&make<num_put<char> >(1u));
189 install(&make<num_put<wchar_t> >(1u));
190 install(&make<moneypunct<char, false> >(1u));
191 install(&make<moneypunct<char, true> >(1u));
192 install(&make<moneypunct<wchar_t, false> >(1u));
193 install(&make<moneypunct<wchar_t, true> >(1u));
194 install(&make<money_get<char> >(1u));
195 install(&make<money_get<wchar_t> >(1u));
196 install(&make<money_put<char> >(1u));
197 install(&make<money_put<wchar_t> >(1u));
198 install(&make<time_get<char> >(1u));
199 install(&make<time_get<wchar_t> >(1u));
200 install(&make<time_put<char> >(1u));
201 install(&make<time_put<wchar_t> >(1u));
202 install(&make<_VSTD::messages<char> >(1u));
203 install(&make<_VSTD::messages<wchar_t> >(1u));
206 locale::__imp::__imp(const string& name, size_t refs)
207 : facet(refs),
208 facets_(N),
209 name_(name)
211 #ifndef _LIBCPP_NO_EXCEPTIONS
214 #endif // _LIBCPP_NO_EXCEPTIONS
215 facets_ = locale::classic().__locale_->facets_;
216 for (unsigned i = 0; i < facets_.size(); ++i)
217 if (facets_[i])
218 facets_[i]->__add_shared();
219 install(new collate_byname<char>(name_));
220 install(new collate_byname<wchar_t>(name_));
221 install(new ctype_byname<char>(name_));
222 install(new ctype_byname<wchar_t>(name_));
223 install(new codecvt_byname<char, char, mbstate_t>(name_));
224 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
225 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
226 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
227 install(new numpunct_byname<char>(name_));
228 install(new numpunct_byname<wchar_t>(name_));
229 install(new moneypunct_byname<char, false>(name_));
230 install(new moneypunct_byname<char, true>(name_));
231 install(new moneypunct_byname<wchar_t, false>(name_));
232 install(new moneypunct_byname<wchar_t, true>(name_));
233 install(new time_get_byname<char>(name_));
234 install(new time_get_byname<wchar_t>(name_));
235 install(new time_put_byname<char>(name_));
236 install(new time_put_byname<wchar_t>(name_));
237 install(new messages_byname<char>(name_));
238 install(new messages_byname<wchar_t>(name_));
239 #ifndef _LIBCPP_NO_EXCEPTIONS
241 catch (...)
243 for (unsigned i = 0; i < facets_.size(); ++i)
244 if (facets_[i])
245 facets_[i]->__release_shared();
246 throw;
248 #endif // _LIBCPP_NO_EXCEPTIONS
251 // NOTE avoid the `base class should be explicitly initialized in the
252 // copy constructor` warning emitted by GCC
253 #if defined(__clang__) || _GNUC_VER >= 406
254 #pragma GCC diagnostic push
255 #pragma GCC diagnostic ignored "-Wextra"
256 #endif
258 locale::__imp::__imp(const __imp& other)
259 : facets_(max<size_t>(N, other.facets_.size())),
260 name_(other.name_)
262 facets_ = other.facets_;
263 for (unsigned i = 0; i < facets_.size(); ++i)
264 if (facets_[i])
265 facets_[i]->__add_shared();
268 #if defined(__clang__) || _GNUC_VER >= 406
269 #pragma GCC diagnostic pop
270 #endif
272 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
273 : facets_(N),
274 name_("*")
276 facets_ = other.facets_;
277 for (unsigned i = 0; i < facets_.size(); ++i)
278 if (facets_[i])
279 facets_[i]->__add_shared();
280 #ifndef _LIBCPP_NO_EXCEPTIONS
283 #endif // _LIBCPP_NO_EXCEPTIONS
284 if (c & locale::collate)
286 install(new collate_byname<char>(name));
287 install(new collate_byname<wchar_t>(name));
289 if (c & locale::ctype)
291 install(new ctype_byname<char>(name));
292 install(new ctype_byname<wchar_t>(name));
293 install(new codecvt_byname<char, char, mbstate_t>(name));
294 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
295 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
296 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
298 if (c & locale::monetary)
300 install(new moneypunct_byname<char, false>(name));
301 install(new moneypunct_byname<char, true>(name));
302 install(new moneypunct_byname<wchar_t, false>(name));
303 install(new moneypunct_byname<wchar_t, true>(name));
305 if (c & locale::numeric)
307 install(new numpunct_byname<char>(name));
308 install(new numpunct_byname<wchar_t>(name));
310 if (c & locale::time)
312 install(new time_get_byname<char>(name));
313 install(new time_get_byname<wchar_t>(name));
314 install(new time_put_byname<char>(name));
315 install(new time_put_byname<wchar_t>(name));
317 if (c & locale::messages)
319 install(new messages_byname<char>(name));
320 install(new messages_byname<wchar_t>(name));
322 #ifndef _LIBCPP_NO_EXCEPTIONS
324 catch (...)
326 for (unsigned i = 0; i < facets_.size(); ++i)
327 if (facets_[i])
328 facets_[i]->__release_shared();
329 throw;
331 #endif // _LIBCPP_NO_EXCEPTIONS
334 template<class F>
335 inline
336 void
337 locale::__imp::install_from(const locale::__imp& one)
339 long id = F::id.__get();
340 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
343 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
344 : facets_(N),
345 name_("*")
347 facets_ = other.facets_;
348 for (unsigned i = 0; i < facets_.size(); ++i)
349 if (facets_[i])
350 facets_[i]->__add_shared();
351 #ifndef _LIBCPP_NO_EXCEPTIONS
354 #endif // _LIBCPP_NO_EXCEPTIONS
355 if (c & locale::collate)
357 install_from<_VSTD::collate<char> >(one);
358 install_from<_VSTD::collate<wchar_t> >(one);
360 if (c & locale::ctype)
362 install_from<_VSTD::ctype<char> >(one);
363 install_from<_VSTD::ctype<wchar_t> >(one);
364 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
365 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
366 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
367 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
369 if (c & locale::monetary)
371 install_from<moneypunct<char, false> >(one);
372 install_from<moneypunct<char, true> >(one);
373 install_from<moneypunct<wchar_t, false> >(one);
374 install_from<moneypunct<wchar_t, true> >(one);
375 install_from<money_get<char> >(one);
376 install_from<money_get<wchar_t> >(one);
377 install_from<money_put<char> >(one);
378 install_from<money_put<wchar_t> >(one);
380 if (c & locale::numeric)
382 install_from<numpunct<char> >(one);
383 install_from<numpunct<wchar_t> >(one);
384 install_from<num_get<char> >(one);
385 install_from<num_get<wchar_t> >(one);
386 install_from<num_put<char> >(one);
387 install_from<num_put<wchar_t> >(one);
389 if (c & locale::time)
391 install_from<time_get<char> >(one);
392 install_from<time_get<wchar_t> >(one);
393 install_from<time_put<char> >(one);
394 install_from<time_put<wchar_t> >(one);
396 if (c & locale::messages)
398 install_from<_VSTD::messages<char> >(one);
399 install_from<_VSTD::messages<wchar_t> >(one);
401 #ifndef _LIBCPP_NO_EXCEPTIONS
403 catch (...)
405 for (unsigned i = 0; i < facets_.size(); ++i)
406 if (facets_[i])
407 facets_[i]->__release_shared();
408 throw;
410 #endif // _LIBCPP_NO_EXCEPTIONS
413 locale::__imp::__imp(const __imp& other, facet* f, long id)
414 : facets_(max<size_t>(N, other.facets_.size()+1)),
415 name_("*")
417 f->__add_shared();
418 unique_ptr<facet, release> hold(f);
419 facets_ = other.facets_;
420 for (unsigned i = 0; i < other.facets_.size(); ++i)
421 if (facets_[i])
422 facets_[i]->__add_shared();
423 install(hold.get(), id);
426 locale::__imp::~__imp()
428 for (unsigned i = 0; i < facets_.size(); ++i)
429 if (facets_[i])
430 facets_[i]->__release_shared();
433 void
434 locale::__imp::install(facet* f, long id)
436 f->__add_shared();
437 unique_ptr<facet, release> hold(f);
438 if (static_cast<size_t>(id) >= facets_.size())
439 facets_.resize(static_cast<size_t>(id+1));
440 if (facets_[static_cast<size_t>(id)])
441 facets_[static_cast<size_t>(id)]->__release_shared();
442 facets_[static_cast<size_t>(id)] = hold.release();
445 const locale::facet*
446 locale::__imp::use_facet(long id) const
448 #ifndef _LIBCPP_NO_EXCEPTIONS
449 if (!has_facet(id))
450 throw bad_cast();
451 #endif // _LIBCPP_NO_EXCEPTIONS
452 return facets_[static_cast<size_t>(id)];
455 // locale
457 const locale&
458 locale::__imp::make_classic()
460 // only one thread can get in here and it only gets in once
461 static aligned_storage<sizeof(locale)>::type buf;
462 locale* c = reinterpret_cast<locale*>(&buf);
463 c->__locale_ = &make<__imp>(1u);
464 return *c;
467 const locale&
468 locale::classic()
470 static const locale& c = __imp::make_classic();
471 return c;
474 locale&
475 locale::__imp::make_global()
477 // only one thread can get in here and it only gets in once
478 static aligned_storage<sizeof(locale)>::type buf;
479 ::new (&buf) locale(locale::classic());
480 return *reinterpret_cast<locale*>(&buf);
483 locale&
484 locale::__global()
486 static locale& g = __imp::make_global();
487 return g;
490 locale::locale() _NOEXCEPT
491 : __locale_(__global().__locale_)
493 __locale_->__add_shared();
496 locale::locale(const locale& l) _NOEXCEPT
497 : __locale_(l.__locale_)
499 __locale_->__add_shared();
502 locale::~locale()
504 __locale_->__release_shared();
507 const locale&
508 locale::operator=(const locale& other) _NOEXCEPT
510 other.__locale_->__add_shared();
511 __locale_->__release_shared();
512 __locale_ = other.__locale_;
513 return *this;
516 locale::locale(const char* name)
517 #ifndef _LIBCPP_NO_EXCEPTIONS
518 : __locale_(name ? new __imp(name)
519 : throw runtime_error("locale constructed with null"))
520 #else // _LIBCPP_NO_EXCEPTIONS
521 : __locale_(new __imp(name))
522 #endif
524 __locale_->__add_shared();
527 locale::locale(const string& name)
528 : __locale_(new __imp(name))
530 __locale_->__add_shared();
533 locale::locale(const locale& other, const char* name, category c)
534 #ifndef _LIBCPP_NO_EXCEPTIONS
535 : __locale_(name ? new __imp(*other.__locale_, name, c)
536 : throw runtime_error("locale constructed with null"))
537 #else // _LIBCPP_NO_EXCEPTIONS
538 : __locale_(new __imp(*other.__locale_, name, c))
539 #endif
541 __locale_->__add_shared();
544 locale::locale(const locale& other, const string& name, category c)
545 : __locale_(new __imp(*other.__locale_, name, c))
547 __locale_->__add_shared();
550 locale::locale(const locale& other, const locale& one, category c)
551 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
553 __locale_->__add_shared();
556 string
557 locale::name() const
559 return __locale_->name();
562 void
563 locale::__install_ctor(const locale& other, facet* f, long id)
565 if (f)
566 __locale_ = new __imp(*other.__locale_, f, id);
567 else
568 __locale_ = other.__locale_;
569 __locale_->__add_shared();
572 locale
573 locale::global(const locale& loc)
575 locale& g = __global();
576 locale r = g;
577 g = loc;
578 #ifndef __CloudABI__
579 if (g.name() != "*")
580 setlocale(LC_ALL, g.name().c_str());
581 #endif
582 return r;
585 bool
586 locale::has_facet(id& x) const
588 return __locale_->has_facet(x.__get());
591 const locale::facet*
592 locale::use_facet(id& x) const
594 return __locale_->use_facet(x.__get());
597 bool
598 locale::operator==(const locale& y) const
600 return (__locale_ == y.__locale_)
601 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
604 // locale::facet
606 locale::facet::~facet()
610 void
611 locale::facet::__on_zero_shared() _NOEXCEPT
613 delete this;
616 // locale::id
618 int32_t locale::id::__next_id = 0;
620 namespace
623 class __fake_bind
625 locale::id* id_;
626 void (locale::id::* pmf_)();
627 public:
628 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
629 : id_(id), pmf_(pmf) {}
631 void operator()() const
633 (id_->*pmf_)();
639 long
640 locale::id::__get()
642 call_once(__flag_, __fake_bind(&locale::id::__init, this));
643 return __id_ - 1;
646 void
647 locale::id::__init()
649 __id_ = __sync_add_and_fetch(&__next_id, 1);
652 // template <> class collate_byname<char>
654 collate_byname<char>::collate_byname(const char* n, size_t refs)
655 : collate<char>(refs),
656 __l(newlocale(LC_ALL_MASK, n, 0))
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
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))
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
676 collate_byname<char>::~collate_byname()
678 freelocale(__l);
682 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
683 const char_type* __lo2, const char_type* __hi2) const
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;
695 collate_byname<char>::string_type
696 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
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;
704 // template <> class collate_byname<wchar_t>
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))
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
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))
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
728 collate_byname<wchar_t>::~collate_byname()
730 freelocale(__l);
734 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
735 const char_type* __lo2, const char_type* __hi2) const
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;
747 collate_byname<wchar_t>::string_type
748 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
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;
756 // template <> class ctype<wchar_t>;
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;
771 locale::id ctype<wchar_t>::id;
773 ctype<wchar_t>::~ctype()
777 bool
778 ctype<wchar_t>::do_is(mask m, char_type c) const
780 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
783 const wchar_t*
784 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
786 for (; low != high; ++low, ++vec)
787 *vec = static_cast<mask>(isascii(*low) ?
788 ctype<char>::classic_table()[*low] : 0);
789 return low;
792 const wchar_t*
793 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
795 for (; low != high; ++low)
796 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
797 break;
798 return low;
801 const wchar_t*
802 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
804 for (; low != high; ++low)
805 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
806 break;
807 return low;
810 wchar_t
811 ctype<wchar_t>::do_toupper(char_type c) const
813 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
814 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
815 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
816 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
817 #else
818 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
819 #endif
822 const wchar_t*
823 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
825 for (; low != high; ++low)
826 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
827 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
828 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
829 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
830 : *low;
831 #else
832 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
833 #endif
834 return low;
837 wchar_t
838 ctype<wchar_t>::do_tolower(char_type c) const
840 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
841 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
842 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
843 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
844 #else
845 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
846 #endif
849 const wchar_t*
850 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
852 for (; low != high; ++low)
853 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
854 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
855 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
856 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
857 : *low;
858 #else
859 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
860 #endif
861 return low;
864 wchar_t
865 ctype<wchar_t>::do_widen(char c) const
867 return c;
870 const char*
871 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
873 for (; low != high; ++low, ++dest)
874 *dest = *low;
875 return low;
878 char
879 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
881 if (isascii(c))
882 return static_cast<char>(c);
883 return dfault;
886 const wchar_t*
887 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
889 for (; low != high; ++low, ++dest)
890 if (isascii(*low))
891 *dest = static_cast<char>(*low);
892 else
893 *dest = dfault;
894 return low;
897 // template <> class ctype<char>;
899 locale::id ctype<char>::id;
901 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
902 : locale::facet(refs),
903 __tab_(tab),
904 __del_(del)
906 if (__tab_ == 0)
907 __tab_ = classic_table();
910 ctype<char>::~ctype()
912 if (__tab_ && __del_)
913 delete [] __tab_;
916 char
917 ctype<char>::do_toupper(char_type c) const
919 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
920 return isascii(c) ?
921 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
922 #elif defined(__NetBSD__) || defined(__minix)
923 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
924 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
925 return isascii(c) ?
926 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
927 #else
928 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
929 #endif
932 const char*
933 ctype<char>::do_toupper(char_type* low, const char_type* high) const
935 for (; low != high; ++low)
936 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
937 *low = isascii(*low) ?
938 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
939 #elif defined(__NetBSD__)
940 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
941 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
942 *low = isascii(*low) ?
943 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
944 #else
945 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
946 #endif
947 return low;
950 char
951 ctype<char>::do_tolower(char_type c) const
953 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
954 return isascii(c) ?
955 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
956 #elif defined(__NetBSD__) || defined(__minix)
957 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
958 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__minix)
959 return isascii(c) ?
960 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
961 #else
962 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
963 #endif
966 const char*
967 ctype<char>::do_tolower(char_type* low, const char_type* high) const
969 for (; low != high; ++low)
970 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
971 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
972 #elif defined(__NetBSD__) || defined(__minix)
973 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
974 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
975 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
976 #else
977 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
978 #endif
979 return low;
982 char
983 ctype<char>::do_widen(char c) const
985 return c;
988 const char*
989 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
991 for (; low != high; ++low, ++dest)
992 *dest = *low;
993 return low;
996 char
997 ctype<char>::do_narrow(char_type c, char dfault) const
999 if (isascii(c))
1000 return static_cast<char>(c);
1001 return dfault;
1004 const char*
1005 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1007 for (; low != high; ++low, ++dest)
1008 if (isascii(*low))
1009 *dest = *low;
1010 else
1011 *dest = dfault;
1012 return low;
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
1021 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1022 const ctype<char>::mask*
1023 ctype<char>::classic_table() _NOEXCEPT
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
1099 return builtin_table;
1101 #else
1102 const ctype<char>::mask*
1103 ctype<char>::classic_table() _NOEXCEPT
1105 #if defined(__APPLE__) || defined(__FreeBSD__)
1106 return _DefaultRuneLocale.__runetype;
1107 #elif defined(__NetBSD__) || defined(__minix)
1108 return _C_ctype_tab_ + 1;
1109 #elif defined(__GLIBC__)
1110 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1111 #elif __sun__
1112 return __ctype_mask;
1113 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1114 return _ctype+1; // internal ctype mask table defined in msvcrt.dll
1115 // This is assumed to be safe, which is a nonsense assumption because we're
1116 // going to end up dereferencing it later...
1117 #elif defined(__EMSCRIPTEN__)
1118 return *__ctype_b_loc();
1119 #elif defined(_NEWLIB_VERSION)
1120 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1121 return _ctype_ + 1;
1122 #elif defined(_AIX)
1123 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1124 #else
1125 // Platform not supported: abort so the person doing the port knows what to
1126 // fix
1127 # warning ctype<char>::classic_table() is not implemented
1128 printf("ctype<char>::classic_table() is not implemented\n");
1129 abort();
1130 return NULL;
1131 #endif
1133 #endif
1135 #if defined(__GLIBC__)
1136 const int*
1137 ctype<char>::__classic_lower_table() _NOEXCEPT
1139 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1142 const int*
1143 ctype<char>::__classic_upper_table() _NOEXCEPT
1145 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1147 #elif __NetBSD__ || defined(__minix)
1148 const short*
1149 ctype<char>::__classic_lower_table() _NOEXCEPT
1151 return _C_tolower_tab_ + 1;
1154 const short*
1155 ctype<char>::__classic_upper_table() _NOEXCEPT
1157 return _C_toupper_tab_ + 1;
1160 #elif defined(__EMSCRIPTEN__)
1161 const int*
1162 ctype<char>::__classic_lower_table() _NOEXCEPT
1164 return *__ctype_tolower_loc();
1167 const int*
1168 ctype<char>::__classic_upper_table() _NOEXCEPT
1170 return *__ctype_toupper_loc();
1172 #endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__
1174 // template <> class ctype_byname<char>
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))
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
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))
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
1198 ctype_byname<char>::~ctype_byname()
1200 freelocale(__l);
1203 char
1204 ctype_byname<char>::do_toupper(char_type c) const
1206 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1209 const char*
1210 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1212 for (; low != high; ++low)
1213 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1214 return low;
1217 char
1218 ctype_byname<char>::do_tolower(char_type c) const
1220 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1223 const char*
1224 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1226 for (; low != high; ++low)
1227 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1228 return low;
1231 // template <> class ctype_byname<wchar_t>
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))
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
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))
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
1255 ctype_byname<wchar_t>::~ctype_byname()
1257 freelocale(__l);
1260 bool
1261 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1263 #ifdef _LIBCPP_WCTYPE_IS_MASK
1264 return static_cast<bool>(iswctype_l(c, m, __l));
1265 #else
1266 bool result = false;
1267 wint_t ch = static_cast<wint_t>(c);
1268 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1269 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1270 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1271 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1272 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1273 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1274 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1275 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1276 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1277 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1278 return result;
1279 #endif
1282 const wchar_t*
1283 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1285 for (; low != high; ++low, ++vec)
1287 if (isascii(*low))
1288 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1289 else
1291 *vec = 0;
1292 wint_t ch = static_cast<wint_t>(*low);
1293 if (iswspace_l(ch, __l))
1294 *vec |= space;
1295 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1296 if (iswprint_l(ch, __l))
1297 *vec |= print;
1298 #endif
1299 if (iswcntrl_l(ch, __l))
1300 *vec |= cntrl;
1301 if (iswupper_l(ch, __l))
1302 *vec |= upper;
1303 if (iswlower_l(ch, __l))
1304 *vec |= lower;
1305 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1306 if (iswalpha_l(ch, __l))
1307 *vec |= alpha;
1308 #endif
1309 if (iswdigit_l(ch, __l))
1310 *vec |= digit;
1311 if (iswpunct_l(ch, __l))
1312 *vec |= punct;
1313 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1314 if (iswxdigit_l(ch, __l))
1315 *vec |= xdigit;
1316 #endif
1317 #if !defined(__sun__)
1318 if (iswblank_l(ch, __l))
1319 *vec |= blank;
1320 #endif
1323 return low;
1326 const wchar_t*
1327 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1329 for (; low != high; ++low)
1331 #ifdef _LIBCPP_WCTYPE_IS_MASK
1332 if (iswctype_l(*low, m, __l))
1333 break;
1334 #else
1335 wint_t ch = static_cast<wint_t>(*low);
1336 if ((m & space) == space && iswspace_l(ch, __l)) break;
1337 if ((m & print) == print && iswprint_l(ch, __l)) break;
1338 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1339 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1340 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1341 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1342 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1343 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1344 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1345 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1346 #endif
1348 return low;
1351 const wchar_t*
1352 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1354 for (; low != high; ++low)
1356 #ifdef _LIBCPP_WCTYPE_IS_MASK
1357 if (!iswctype_l(*low, m, __l))
1358 break;
1359 #else
1360 wint_t ch = static_cast<wint_t>(*low);
1361 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1362 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1363 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1364 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1365 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1366 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1367 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1368 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1369 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1370 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1371 break;
1372 #endif
1374 return low;
1377 wchar_t
1378 ctype_byname<wchar_t>::do_toupper(char_type c) const
1380 return towupper_l(c, __l);
1383 const wchar_t*
1384 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1386 for (; low != high; ++low)
1387 *low = towupper_l(*low, __l);
1388 return low;
1391 wchar_t
1392 ctype_byname<wchar_t>::do_tolower(char_type c) const
1394 return towlower_l(c, __l);
1397 const wchar_t*
1398 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1400 for (; low != high; ++low)
1401 *low = towlower_l(*low, __l);
1402 return low;
1405 wchar_t
1406 ctype_byname<wchar_t>::do_widen(char c) const
1408 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1409 return btowc_l(c, __l);
1410 #else
1411 return __btowc_l(c, __l);
1412 #endif
1415 const char*
1416 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1418 for (; low != high; ++low, ++dest)
1419 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1420 *dest = btowc_l(*low, __l);
1421 #else
1422 *dest = __btowc_l(*low, __l);
1423 #endif
1424 return low;
1427 char
1428 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1430 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1431 int r = wctob_l(c, __l);
1432 #else
1433 int r = __wctob_l(c, __l);
1434 #endif
1435 return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1438 const wchar_t*
1439 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1441 for (; low != high; ++low, ++dest)
1443 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1444 int r = wctob_l(*low, __l);
1445 #else
1446 int r = __wctob_l(*low, __l);
1447 #endif
1448 *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1450 return low;
1453 // template <> class codecvt<char, char, mbstate_t>
1455 locale::id codecvt<char, char, mbstate_t>::id;
1457 codecvt<char, char, mbstate_t>::~codecvt()
1461 codecvt<char, char, mbstate_t>::result
1462 codecvt<char, char, mbstate_t>::do_out(state_type&,
1463 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1464 extern_type* to, extern_type*, extern_type*& to_nxt) const
1466 frm_nxt = frm;
1467 to_nxt = to;
1468 return noconv;
1471 codecvt<char, char, mbstate_t>::result
1472 codecvt<char, char, mbstate_t>::do_in(state_type&,
1473 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1474 intern_type* to, intern_type*, intern_type*& to_nxt) const
1476 frm_nxt = frm;
1477 to_nxt = to;
1478 return noconv;
1481 codecvt<char, char, mbstate_t>::result
1482 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1483 extern_type* to, extern_type*, extern_type*& to_nxt) const
1485 to_nxt = to;
1486 return noconv;
1490 codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1492 return 1;
1495 bool
1496 codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1498 return true;
1502 codecvt<char, char, mbstate_t>::do_length(state_type&,
1503 const extern_type* frm, const extern_type* end, size_t mx) const
1505 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1509 codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1511 return 1;
1514 // template <> class codecvt<wchar_t, char, mbstate_t>
1516 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1518 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1519 : locale::facet(refs),
1520 __l(_LIBCPP_GET_C_LOCALE)
1524 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1525 : locale::facet(refs),
1526 __l(newlocale(LC_ALL_MASK, nm, 0))
1528 #ifndef _LIBCPP_NO_EXCEPTIONS
1529 if (__l == 0)
1530 throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1531 " failed to construct for " + string(nm));
1532 #endif // _LIBCPP_NO_EXCEPTIONS
1535 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1537 if (__l != _LIBCPP_GET_C_LOCALE)
1538 freelocale(__l);
1541 codecvt<wchar_t, char, mbstate_t>::result
1542 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1543 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1544 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1546 // look for first internal null in frm
1547 const intern_type* fend = frm;
1548 for (; fend != frm_end; ++fend)
1549 if (*fend == 0)
1550 break;
1551 // loop over all null-terminated sequences in frm
1552 to_nxt = to;
1553 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1555 // save state in case it is needed to recover to_nxt on error
1556 mbstate_t save_state = st;
1557 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1558 size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1559 static_cast<size_t>(to_end-to), &st, __l);
1560 #else
1561 size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1562 #endif
1563 if (n == size_t(-1))
1565 // need to recover to_nxt
1566 for (to_nxt = to; frm != frm_nxt; ++frm)
1568 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1569 n = wcrtomb_l(to_nxt, *frm, &save_state, __l);
1570 #else
1571 n = __wcrtomb_l(to_nxt, *frm, &save_state, __l);
1572 #endif
1573 if (n == size_t(-1))
1574 break;
1575 to_nxt += n;
1577 frm_nxt = frm;
1578 return error;
1580 if (n == 0)
1581 return partial;
1582 to_nxt += n;
1583 if (to_nxt == to_end)
1584 break;
1585 if (fend != frm_end) // set up next null terminated sequence
1587 // Try to write the terminating null
1588 extern_type tmp[MB_LEN_MAX];
1589 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1590 n = wcrtomb_l(tmp, intern_type(), &st, __l);
1591 #else
1592 n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1593 #endif
1594 if (n == size_t(-1)) // on error
1595 return error;
1596 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1597 return partial;
1598 for (extern_type* p = tmp; n; --n) // write it
1599 *to_nxt++ = *p++;
1600 ++frm_nxt;
1601 // look for next null in frm
1602 for (fend = frm_nxt; fend != frm_end; ++fend)
1603 if (*fend == 0)
1604 break;
1607 return frm_nxt == frm_end ? ok : partial;
1610 codecvt<wchar_t, char, mbstate_t>::result
1611 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1612 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1613 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1615 // look for first internal null in frm
1616 const extern_type* fend = frm;
1617 for (; fend != frm_end; ++fend)
1618 if (*fend == 0)
1619 break;
1620 // loop over all null-terminated sequences in frm
1621 to_nxt = to;
1622 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1624 // save state in case it is needed to recover to_nxt on error
1625 mbstate_t save_state = st;
1626 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1627 size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1628 static_cast<size_t>(to_end-to), &st, __l);
1629 #else
1630 size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l);
1631 #endif
1632 if (n == size_t(-1))
1634 // need to recover to_nxt
1635 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1637 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1638 n = mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1639 &save_state, __l);
1640 #else
1641 n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l);
1642 #endif
1643 switch (n)
1645 case 0:
1646 ++frm;
1647 break;
1648 case size_t(-1):
1649 frm_nxt = frm;
1650 return error;
1651 case size_t(-2):
1652 frm_nxt = frm;
1653 return partial;
1654 default:
1655 frm += n;
1656 break;
1659 frm_nxt = frm;
1660 return frm_nxt == frm_end ? ok : partial;
1662 if (n == size_t(-1))
1663 return error;
1664 to_nxt += n;
1665 if (to_nxt == to_end)
1666 break;
1667 if (fend != frm_end) // set up next null terminated sequence
1669 // Try to write the terminating null
1670 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1671 n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1672 #else
1673 n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1674 #endif
1675 if (n != 0) // on error
1676 return error;
1677 ++to_nxt;
1678 ++frm_nxt;
1679 // look for next null in frm
1680 for (fend = frm_nxt; fend != frm_end; ++fend)
1681 if (*fend == 0)
1682 break;
1685 return frm_nxt == frm_end ? ok : partial;
1688 codecvt<wchar_t, char, mbstate_t>::result
1689 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1690 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1692 to_nxt = to;
1693 extern_type tmp[MB_LEN_MAX];
1694 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1695 size_t n = wcrtomb_l(tmp, intern_type(), &st, __l);
1696 #else
1697 size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l);
1698 #endif
1699 if (n == size_t(-1) || n == 0) // on error
1700 return error;
1701 --n;
1702 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1703 return partial;
1704 for (extern_type* p = tmp; n; --n) // write it
1705 *to_nxt++ = *p++;
1706 return ok;
1710 codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1712 #ifndef __CloudABI__
1713 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1714 if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1715 #else
1716 if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1717 #endif
1718 return -1;
1719 #endif
1721 // stateless encoding
1722 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1723 if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
1724 #else
1725 if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1726 #endif
1727 return 1; // which take more than 1 char to form a wchar_t
1728 return 0;
1731 bool
1732 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1734 return false;
1738 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1739 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1741 int nbytes = 0;
1742 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1744 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1745 size_t n = mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1746 #else
1747 size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l);
1748 #endif
1749 switch (n)
1751 case 0:
1752 ++nbytes;
1753 ++frm;
1754 break;
1755 case size_t(-1):
1756 case size_t(-2):
1757 return nbytes;
1758 default:
1759 nbytes += n;
1760 frm += n;
1761 break;
1764 return nbytes;
1768 codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1770 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
1771 return __l == 0 ? 1 : static_cast<int>( MB_CUR_MAX_L(__l));
1772 #else
1773 return __l == 0 ? 1 : static_cast<int>(__mb_cur_max_l(__l));
1774 #endif
1777 // Valid UTF ranges
1778 // UTF-32 UTF-16 UTF-8 # of code points
1779 // first second first second third fourth
1780 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1781 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1782 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1783 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1784 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1785 // 00D800 - 00DFFF invalid
1786 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1787 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1788 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1789 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1791 static
1792 codecvt_base::result
1793 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1794 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1795 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1797 frm_nxt = frm;
1798 to_nxt = to;
1799 if (mode & generate_header)
1801 if (to_end-to_nxt < 3)
1802 return codecvt_base::partial;
1803 *to_nxt++ = static_cast<uint8_t>(0xEF);
1804 *to_nxt++ = static_cast<uint8_t>(0xBB);
1805 *to_nxt++ = static_cast<uint8_t>(0xBF);
1807 for (; frm_nxt < frm_end; ++frm_nxt)
1809 uint16_t wc1 = *frm_nxt;
1810 if (wc1 > Maxcode)
1811 return codecvt_base::error;
1812 if (wc1 < 0x0080)
1814 if (to_end-to_nxt < 1)
1815 return codecvt_base::partial;
1816 *to_nxt++ = static_cast<uint8_t>(wc1);
1818 else if (wc1 < 0x0800)
1820 if (to_end-to_nxt < 2)
1821 return codecvt_base::partial;
1822 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1823 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1825 else if (wc1 < 0xD800)
1827 if (to_end-to_nxt < 3)
1828 return codecvt_base::partial;
1829 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1830 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1831 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1833 else if (wc1 < 0xDC00)
1835 if (frm_end-frm_nxt < 2)
1836 return codecvt_base::partial;
1837 uint16_t wc2 = frm_nxt[1];
1838 if ((wc2 & 0xFC00) != 0xDC00)
1839 return codecvt_base::error;
1840 if (to_end-to_nxt < 4)
1841 return codecvt_base::partial;
1842 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1843 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1844 return codecvt_base::error;
1845 ++frm_nxt;
1846 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1847 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1848 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1849 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1850 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1852 else if (wc1 < 0xE000)
1854 return codecvt_base::error;
1856 else
1858 if (to_end-to_nxt < 3)
1859 return codecvt_base::partial;
1860 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1861 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1862 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1865 return codecvt_base::ok;
1868 static
1869 codecvt_base::result
1870 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1871 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1872 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1874 frm_nxt = frm;
1875 to_nxt = to;
1876 if (mode & generate_header)
1878 if (to_end-to_nxt < 3)
1879 return codecvt_base::partial;
1880 *to_nxt++ = static_cast<uint8_t>(0xEF);
1881 *to_nxt++ = static_cast<uint8_t>(0xBB);
1882 *to_nxt++ = static_cast<uint8_t>(0xBF);
1884 for (; frm_nxt < frm_end; ++frm_nxt)
1886 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1887 if (wc1 > Maxcode)
1888 return codecvt_base::error;
1889 if (wc1 < 0x0080)
1891 if (to_end-to_nxt < 1)
1892 return codecvt_base::partial;
1893 *to_nxt++ = static_cast<uint8_t>(wc1);
1895 else if (wc1 < 0x0800)
1897 if (to_end-to_nxt < 2)
1898 return codecvt_base::partial;
1899 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1900 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1902 else if (wc1 < 0xD800)
1904 if (to_end-to_nxt < 3)
1905 return codecvt_base::partial;
1906 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1907 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1908 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1910 else if (wc1 < 0xDC00)
1912 if (frm_end-frm_nxt < 2)
1913 return codecvt_base::partial;
1914 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1915 if ((wc2 & 0xFC00) != 0xDC00)
1916 return codecvt_base::error;
1917 if (to_end-to_nxt < 4)
1918 return codecvt_base::partial;
1919 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1920 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1921 return codecvt_base::error;
1922 ++frm_nxt;
1923 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1924 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1925 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1926 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1927 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1929 else if (wc1 < 0xE000)
1931 return codecvt_base::error;
1933 else
1935 if (to_end-to_nxt < 3)
1936 return codecvt_base::partial;
1937 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1938 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1939 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1942 return codecvt_base::ok;
1945 static
1946 codecvt_base::result
1947 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1948 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1949 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1951 frm_nxt = frm;
1952 to_nxt = to;
1953 if (mode & consume_header)
1955 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1956 frm_nxt[2] == 0xBF)
1957 frm_nxt += 3;
1959 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1961 uint8_t c1 = *frm_nxt;
1962 if (c1 > Maxcode)
1963 return codecvt_base::error;
1964 if (c1 < 0x80)
1966 *to_nxt = static_cast<uint16_t>(c1);
1967 ++frm_nxt;
1969 else if (c1 < 0xC2)
1971 return codecvt_base::error;
1973 else if (c1 < 0xE0)
1975 if (frm_end-frm_nxt < 2)
1976 return codecvt_base::partial;
1977 uint8_t c2 = frm_nxt[1];
1978 if ((c2 & 0xC0) != 0x80)
1979 return codecvt_base::error;
1980 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1981 if (t > Maxcode)
1982 return codecvt_base::error;
1983 *to_nxt = t;
1984 frm_nxt += 2;
1986 else if (c1 < 0xF0)
1988 if (frm_end-frm_nxt < 3)
1989 return codecvt_base::partial;
1990 uint8_t c2 = frm_nxt[1];
1991 uint8_t c3 = frm_nxt[2];
1992 switch (c1)
1994 case 0xE0:
1995 if ((c2 & 0xE0) != 0xA0)
1996 return codecvt_base::error;
1997 break;
1998 case 0xED:
1999 if ((c2 & 0xE0) != 0x80)
2000 return codecvt_base::error;
2001 break;
2002 default:
2003 if ((c2 & 0xC0) != 0x80)
2004 return codecvt_base::error;
2005 break;
2007 if ((c3 & 0xC0) != 0x80)
2008 return codecvt_base::error;
2009 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2010 | ((c2 & 0x3F) << 6)
2011 | (c3 & 0x3F));
2012 if (t > Maxcode)
2013 return codecvt_base::error;
2014 *to_nxt = t;
2015 frm_nxt += 3;
2017 else if (c1 < 0xF5)
2019 if (frm_end-frm_nxt < 4)
2020 return codecvt_base::partial;
2021 uint8_t c2 = frm_nxt[1];
2022 uint8_t c3 = frm_nxt[2];
2023 uint8_t c4 = frm_nxt[3];
2024 switch (c1)
2026 case 0xF0:
2027 if (!(0x90 <= c2 && c2 <= 0xBF))
2028 return codecvt_base::error;
2029 break;
2030 case 0xF4:
2031 if ((c2 & 0xF0) != 0x80)
2032 return codecvt_base::error;
2033 break;
2034 default:
2035 if ((c2 & 0xC0) != 0x80)
2036 return codecvt_base::error;
2037 break;
2039 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2040 return codecvt_base::error;
2041 if (to_end-to_nxt < 2)
2042 return codecvt_base::partial;
2043 if ((((c1 & 7UL) << 18) +
2044 ((c2 & 0x3FUL) << 12) +
2045 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2046 return codecvt_base::error;
2047 *to_nxt = static_cast<uint16_t>(
2048 0xD800
2049 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2050 | ((c2 & 0x0F) << 2)
2051 | ((c3 & 0x30) >> 4));
2052 *++to_nxt = static_cast<uint16_t>(
2053 0xDC00
2054 | ((c3 & 0x0F) << 6)
2055 | (c4 & 0x3F));
2056 frm_nxt += 4;
2058 else
2060 return codecvt_base::error;
2063 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2066 static
2067 codecvt_base::result
2068 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2069 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2070 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2072 frm_nxt = frm;
2073 to_nxt = to;
2074 if (mode & consume_header)
2076 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2077 frm_nxt[2] == 0xBF)
2078 frm_nxt += 3;
2080 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2082 uint8_t c1 = *frm_nxt;
2083 if (c1 > Maxcode)
2084 return codecvt_base::error;
2085 if (c1 < 0x80)
2087 *to_nxt = static_cast<uint32_t>(c1);
2088 ++frm_nxt;
2090 else if (c1 < 0xC2)
2092 return codecvt_base::error;
2094 else if (c1 < 0xE0)
2096 if (frm_end-frm_nxt < 2)
2097 return codecvt_base::partial;
2098 uint8_t c2 = frm_nxt[1];
2099 if ((c2 & 0xC0) != 0x80)
2100 return codecvt_base::error;
2101 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2102 if (t > Maxcode)
2103 return codecvt_base::error;
2104 *to_nxt = static_cast<uint32_t>(t);
2105 frm_nxt += 2;
2107 else if (c1 < 0xF0)
2109 if (frm_end-frm_nxt < 3)
2110 return codecvt_base::partial;
2111 uint8_t c2 = frm_nxt[1];
2112 uint8_t c3 = frm_nxt[2];
2113 switch (c1)
2115 case 0xE0:
2116 if ((c2 & 0xE0) != 0xA0)
2117 return codecvt_base::error;
2118 break;
2119 case 0xED:
2120 if ((c2 & 0xE0) != 0x80)
2121 return codecvt_base::error;
2122 break;
2123 default:
2124 if ((c2 & 0xC0) != 0x80)
2125 return codecvt_base::error;
2126 break;
2128 if ((c3 & 0xC0) != 0x80)
2129 return codecvt_base::error;
2130 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2131 | ((c2 & 0x3F) << 6)
2132 | (c3 & 0x3F));
2133 if (t > Maxcode)
2134 return codecvt_base::error;
2135 *to_nxt = static_cast<uint32_t>(t);
2136 frm_nxt += 3;
2138 else if (c1 < 0xF5)
2140 if (frm_end-frm_nxt < 4)
2141 return codecvt_base::partial;
2142 uint8_t c2 = frm_nxt[1];
2143 uint8_t c3 = frm_nxt[2];
2144 uint8_t c4 = frm_nxt[3];
2145 switch (c1)
2147 case 0xF0:
2148 if (!(0x90 <= c2 && c2 <= 0xBF))
2149 return codecvt_base::error;
2150 break;
2151 case 0xF4:
2152 if ((c2 & 0xF0) != 0x80)
2153 return codecvt_base::error;
2154 break;
2155 default:
2156 if ((c2 & 0xC0) != 0x80)
2157 return codecvt_base::error;
2158 break;
2160 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2161 return codecvt_base::error;
2162 if (to_end-to_nxt < 2)
2163 return codecvt_base::partial;
2164 if ((((c1 & 7UL) << 18) +
2165 ((c2 & 0x3FUL) << 12) +
2166 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2167 return codecvt_base::error;
2168 *to_nxt = static_cast<uint32_t>(
2169 0xD800
2170 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2171 | ((c2 & 0x0F) << 2)
2172 | ((c3 & 0x30) >> 4));
2173 *++to_nxt = static_cast<uint32_t>(
2174 0xDC00
2175 | ((c3 & 0x0F) << 6)
2176 | (c4 & 0x3F));
2177 frm_nxt += 4;
2179 else
2181 return codecvt_base::error;
2184 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2187 static
2189 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2190 size_t mx, unsigned long Maxcode = 0x10FFFF,
2191 codecvt_mode mode = codecvt_mode(0))
2193 const uint8_t* frm_nxt = frm;
2194 if (mode & consume_header)
2196 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2197 frm_nxt[2] == 0xBF)
2198 frm_nxt += 3;
2200 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2202 uint8_t c1 = *frm_nxt;
2203 if (c1 > Maxcode)
2204 break;
2205 if (c1 < 0x80)
2207 ++frm_nxt;
2209 else if (c1 < 0xC2)
2211 break;
2213 else if (c1 < 0xE0)
2215 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2216 break;
2217 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2218 if (t > Maxcode)
2219 break;
2220 frm_nxt += 2;
2222 else if (c1 < 0xF0)
2224 if (frm_end-frm_nxt < 3)
2225 break;
2226 uint8_t c2 = frm_nxt[1];
2227 uint8_t c3 = frm_nxt[2];
2228 switch (c1)
2230 case 0xE0:
2231 if ((c2 & 0xE0) != 0xA0)
2232 return static_cast<int>(frm_nxt - frm);
2233 break;
2234 case 0xED:
2235 if ((c2 & 0xE0) != 0x80)
2236 return static_cast<int>(frm_nxt - frm);
2237 break;
2238 default:
2239 if ((c2 & 0xC0) != 0x80)
2240 return static_cast<int>(frm_nxt - frm);
2241 break;
2243 if ((c3 & 0xC0) != 0x80)
2244 break;
2245 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2246 break;
2247 frm_nxt += 3;
2249 else if (c1 < 0xF5)
2251 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2252 break;
2253 uint8_t c2 = frm_nxt[1];
2254 uint8_t c3 = frm_nxt[2];
2255 uint8_t c4 = frm_nxt[3];
2256 switch (c1)
2258 case 0xF0:
2259 if (!(0x90 <= c2 && c2 <= 0xBF))
2260 return static_cast<int>(frm_nxt - frm);
2261 break;
2262 case 0xF4:
2263 if ((c2 & 0xF0) != 0x80)
2264 return static_cast<int>(frm_nxt - frm);
2265 break;
2266 default:
2267 if ((c2 & 0xC0) != 0x80)
2268 return static_cast<int>(frm_nxt - frm);
2269 break;
2271 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2272 break;
2273 if ((((c1 & 7UL) << 18) +
2274 ((c2 & 0x3FUL) << 12) +
2275 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2276 break;
2277 ++nchar16_t;
2278 frm_nxt += 4;
2280 else
2282 break;
2285 return static_cast<int>(frm_nxt - frm);
2288 static
2289 codecvt_base::result
2290 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2291 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2292 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2294 frm_nxt = frm;
2295 to_nxt = to;
2296 if (mode & generate_header)
2298 if (to_end-to_nxt < 3)
2299 return codecvt_base::partial;
2300 *to_nxt++ = static_cast<uint8_t>(0xEF);
2301 *to_nxt++ = static_cast<uint8_t>(0xBB);
2302 *to_nxt++ = static_cast<uint8_t>(0xBF);
2304 for (; frm_nxt < frm_end; ++frm_nxt)
2306 uint32_t wc = *frm_nxt;
2307 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2308 return codecvt_base::error;
2309 if (wc < 0x000080)
2311 if (to_end-to_nxt < 1)
2312 return codecvt_base::partial;
2313 *to_nxt++ = static_cast<uint8_t>(wc);
2315 else if (wc < 0x000800)
2317 if (to_end-to_nxt < 2)
2318 return codecvt_base::partial;
2319 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2320 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2322 else if (wc < 0x010000)
2324 if (to_end-to_nxt < 3)
2325 return codecvt_base::partial;
2326 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2327 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2328 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2330 else // if (wc < 0x110000)
2332 if (to_end-to_nxt < 4)
2333 return codecvt_base::partial;
2334 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2335 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2336 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2337 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2340 return codecvt_base::ok;
2343 static
2344 codecvt_base::result
2345 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2346 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2347 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2349 frm_nxt = frm;
2350 to_nxt = to;
2351 if (mode & consume_header)
2353 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2354 frm_nxt[2] == 0xBF)
2355 frm_nxt += 3;
2357 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2359 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2360 if (c1 < 0x80)
2362 if (c1 > Maxcode)
2363 return codecvt_base::error;
2364 *to_nxt = static_cast<uint32_t>(c1);
2365 ++frm_nxt;
2367 else if (c1 < 0xC2)
2369 return codecvt_base::error;
2371 else if (c1 < 0xE0)
2373 if (frm_end-frm_nxt < 2)
2374 return codecvt_base::partial;
2375 uint8_t c2 = frm_nxt[1];
2376 if ((c2 & 0xC0) != 0x80)
2377 return codecvt_base::error;
2378 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2379 | (c2 & 0x3F));
2380 if (t > Maxcode)
2381 return codecvt_base::error;
2382 *to_nxt = t;
2383 frm_nxt += 2;
2385 else if (c1 < 0xF0)
2387 if (frm_end-frm_nxt < 3)
2388 return codecvt_base::partial;
2389 uint8_t c2 = frm_nxt[1];
2390 uint8_t c3 = frm_nxt[2];
2391 switch (c1)
2393 case 0xE0:
2394 if ((c2 & 0xE0) != 0xA0)
2395 return codecvt_base::error;
2396 break;
2397 case 0xED:
2398 if ((c2 & 0xE0) != 0x80)
2399 return codecvt_base::error;
2400 break;
2401 default:
2402 if ((c2 & 0xC0) != 0x80)
2403 return codecvt_base::error;
2404 break;
2406 if ((c3 & 0xC0) != 0x80)
2407 return codecvt_base::error;
2408 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2409 | ((c2 & 0x3F) << 6)
2410 | (c3 & 0x3F));
2411 if (t > Maxcode)
2412 return codecvt_base::error;
2413 *to_nxt = t;
2414 frm_nxt += 3;
2416 else if (c1 < 0xF5)
2418 if (frm_end-frm_nxt < 4)
2419 return codecvt_base::partial;
2420 uint8_t c2 = frm_nxt[1];
2421 uint8_t c3 = frm_nxt[2];
2422 uint8_t c4 = frm_nxt[3];
2423 switch (c1)
2425 case 0xF0:
2426 if (!(0x90 <= c2 && c2 <= 0xBF))
2427 return codecvt_base::error;
2428 break;
2429 case 0xF4:
2430 if ((c2 & 0xF0) != 0x80)
2431 return codecvt_base::error;
2432 break;
2433 default:
2434 if ((c2 & 0xC0) != 0x80)
2435 return codecvt_base::error;
2436 break;
2438 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2439 return codecvt_base::error;
2440 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2441 | ((c2 & 0x3F) << 12)
2442 | ((c3 & 0x3F) << 6)
2443 | (c4 & 0x3F));
2444 if (t > Maxcode)
2445 return codecvt_base::error;
2446 *to_nxt = t;
2447 frm_nxt += 4;
2449 else
2451 return codecvt_base::error;
2454 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2457 static
2459 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2460 size_t mx, unsigned long Maxcode = 0x10FFFF,
2461 codecvt_mode mode = codecvt_mode(0))
2463 const uint8_t* frm_nxt = frm;
2464 if (mode & consume_header)
2466 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2467 frm_nxt[2] == 0xBF)
2468 frm_nxt += 3;
2470 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2472 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2473 if (c1 < 0x80)
2475 if (c1 > Maxcode)
2476 break;
2477 ++frm_nxt;
2479 else if (c1 < 0xC2)
2481 break;
2483 else if (c1 < 0xE0)
2485 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2486 break;
2487 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2488 break;
2489 frm_nxt += 2;
2491 else if (c1 < 0xF0)
2493 if (frm_end-frm_nxt < 3)
2494 break;
2495 uint8_t c2 = frm_nxt[1];
2496 uint8_t c3 = frm_nxt[2];
2497 switch (c1)
2499 case 0xE0:
2500 if ((c2 & 0xE0) != 0xA0)
2501 return static_cast<int>(frm_nxt - frm);
2502 break;
2503 case 0xED:
2504 if ((c2 & 0xE0) != 0x80)
2505 return static_cast<int>(frm_nxt - frm);
2506 break;
2507 default:
2508 if ((c2 & 0xC0) != 0x80)
2509 return static_cast<int>(frm_nxt - frm);
2510 break;
2512 if ((c3 & 0xC0) != 0x80)
2513 break;
2514 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2515 break;
2516 frm_nxt += 3;
2518 else if (c1 < 0xF5)
2520 if (frm_end-frm_nxt < 4)
2521 break;
2522 uint8_t c2 = frm_nxt[1];
2523 uint8_t c3 = frm_nxt[2];
2524 uint8_t c4 = frm_nxt[3];
2525 switch (c1)
2527 case 0xF0:
2528 if (!(0x90 <= c2 && c2 <= 0xBF))
2529 return static_cast<int>(frm_nxt - frm);
2530 break;
2531 case 0xF4:
2532 if ((c2 & 0xF0) != 0x80)
2533 return static_cast<int>(frm_nxt - frm);
2534 break;
2535 default:
2536 if ((c2 & 0xC0) != 0x80)
2537 return static_cast<int>(frm_nxt - frm);
2538 break;
2540 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2541 break;
2542 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2543 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2544 break;
2545 frm_nxt += 4;
2547 else
2549 break;
2552 return static_cast<int>(frm_nxt - frm);
2555 static
2556 codecvt_base::result
2557 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2558 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2559 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2561 frm_nxt = frm;
2562 to_nxt = to;
2563 if (mode & generate_header)
2565 if (to_end-to_nxt < 3)
2566 return codecvt_base::partial;
2567 *to_nxt++ = static_cast<uint8_t>(0xEF);
2568 *to_nxt++ = static_cast<uint8_t>(0xBB);
2569 *to_nxt++ = static_cast<uint8_t>(0xBF);
2571 for (; frm_nxt < frm_end; ++frm_nxt)
2573 uint16_t wc = *frm_nxt;
2574 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2575 return codecvt_base::error;
2576 if (wc < 0x0080)
2578 if (to_end-to_nxt < 1)
2579 return codecvt_base::partial;
2580 *to_nxt++ = static_cast<uint8_t>(wc);
2582 else if (wc < 0x0800)
2584 if (to_end-to_nxt < 2)
2585 return codecvt_base::partial;
2586 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2587 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2589 else // if (wc <= 0xFFFF)
2591 if (to_end-to_nxt < 3)
2592 return codecvt_base::partial;
2593 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2594 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2595 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2598 return codecvt_base::ok;
2601 static
2602 codecvt_base::result
2603 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2604 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2605 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2607 frm_nxt = frm;
2608 to_nxt = to;
2609 if (mode & consume_header)
2611 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2612 frm_nxt[2] == 0xBF)
2613 frm_nxt += 3;
2615 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2617 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2618 if (c1 < 0x80)
2620 if (c1 > Maxcode)
2621 return codecvt_base::error;
2622 *to_nxt = static_cast<uint16_t>(c1);
2623 ++frm_nxt;
2625 else if (c1 < 0xC2)
2627 return codecvt_base::error;
2629 else if (c1 < 0xE0)
2631 if (frm_end-frm_nxt < 2)
2632 return codecvt_base::partial;
2633 uint8_t c2 = frm_nxt[1];
2634 if ((c2 & 0xC0) != 0x80)
2635 return codecvt_base::error;
2636 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2637 | (c2 & 0x3F));
2638 if (t > Maxcode)
2639 return codecvt_base::error;
2640 *to_nxt = t;
2641 frm_nxt += 2;
2643 else if (c1 < 0xF0)
2645 if (frm_end-frm_nxt < 3)
2646 return codecvt_base::partial;
2647 uint8_t c2 = frm_nxt[1];
2648 uint8_t c3 = frm_nxt[2];
2649 switch (c1)
2651 case 0xE0:
2652 if ((c2 & 0xE0) != 0xA0)
2653 return codecvt_base::error;
2654 break;
2655 case 0xED:
2656 if ((c2 & 0xE0) != 0x80)
2657 return codecvt_base::error;
2658 break;
2659 default:
2660 if ((c2 & 0xC0) != 0x80)
2661 return codecvt_base::error;
2662 break;
2664 if ((c3 & 0xC0) != 0x80)
2665 return codecvt_base::error;
2666 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2667 | ((c2 & 0x3F) << 6)
2668 | (c3 & 0x3F));
2669 if (t > Maxcode)
2670 return codecvt_base::error;
2671 *to_nxt = t;
2672 frm_nxt += 3;
2674 else
2676 return codecvt_base::error;
2679 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2682 static
2684 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2685 size_t mx, unsigned long Maxcode = 0x10FFFF,
2686 codecvt_mode mode = codecvt_mode(0))
2688 const uint8_t* frm_nxt = frm;
2689 if (mode & consume_header)
2691 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2692 frm_nxt[2] == 0xBF)
2693 frm_nxt += 3;
2695 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2697 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2698 if (c1 < 0x80)
2700 if (c1 > Maxcode)
2701 break;
2702 ++frm_nxt;
2704 else if (c1 < 0xC2)
2706 break;
2708 else if (c1 < 0xE0)
2710 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2711 break;
2712 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2713 break;
2714 frm_nxt += 2;
2716 else if (c1 < 0xF0)
2718 if (frm_end-frm_nxt < 3)
2719 break;
2720 uint8_t c2 = frm_nxt[1];
2721 uint8_t c3 = frm_nxt[2];
2722 switch (c1)
2724 case 0xE0:
2725 if ((c2 & 0xE0) != 0xA0)
2726 return static_cast<int>(frm_nxt - frm);
2727 break;
2728 case 0xED:
2729 if ((c2 & 0xE0) != 0x80)
2730 return static_cast<int>(frm_nxt - frm);
2731 break;
2732 default:
2733 if ((c2 & 0xC0) != 0x80)
2734 return static_cast<int>(frm_nxt - frm);
2735 break;
2737 if ((c3 & 0xC0) != 0x80)
2738 break;
2739 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2740 break;
2741 frm_nxt += 3;
2743 else
2745 break;
2748 return static_cast<int>(frm_nxt - frm);
2751 static
2752 codecvt_base::result
2753 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2754 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2755 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2757 frm_nxt = frm;
2758 to_nxt = to;
2759 if (mode & generate_header)
2761 if (to_end-to_nxt < 2)
2762 return codecvt_base::partial;
2763 *to_nxt++ = static_cast<uint8_t>(0xFE);
2764 *to_nxt++ = static_cast<uint8_t>(0xFF);
2766 for (; frm_nxt < frm_end; ++frm_nxt)
2768 uint32_t wc = *frm_nxt;
2769 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2770 return codecvt_base::error;
2771 if (wc < 0x010000)
2773 if (to_end-to_nxt < 2)
2774 return codecvt_base::partial;
2775 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2776 *to_nxt++ = static_cast<uint8_t>(wc);
2778 else
2780 if (to_end-to_nxt < 4)
2781 return codecvt_base::partial;
2782 uint16_t t = static_cast<uint16_t>(
2783 0xD800
2784 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2785 | ((wc & 0x00FC00) >> 10));
2786 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2787 *to_nxt++ = static_cast<uint8_t>(t);
2788 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2789 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2790 *to_nxt++ = static_cast<uint8_t>(t);
2793 return codecvt_base::ok;
2796 static
2797 codecvt_base::result
2798 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2799 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2800 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2802 frm_nxt = frm;
2803 to_nxt = to;
2804 if (mode & consume_header)
2806 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2807 frm_nxt += 2;
2809 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2811 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2812 if ((c1 & 0xFC00) == 0xDC00)
2813 return codecvt_base::error;
2814 if ((c1 & 0xFC00) != 0xD800)
2816 if (c1 > Maxcode)
2817 return codecvt_base::error;
2818 *to_nxt = static_cast<uint32_t>(c1);
2819 frm_nxt += 2;
2821 else
2823 if (frm_end-frm_nxt < 4)
2824 return codecvt_base::partial;
2825 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2826 if ((c2 & 0xFC00) != 0xDC00)
2827 return codecvt_base::error;
2828 uint32_t t = static_cast<uint32_t>(
2829 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2830 | ((c1 & 0x003F) << 10)
2831 | (c2 & 0x03FF));
2832 if (t > Maxcode)
2833 return codecvt_base::error;
2834 *to_nxt = t;
2835 frm_nxt += 4;
2838 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2841 static
2843 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2844 size_t mx, unsigned long Maxcode = 0x10FFFF,
2845 codecvt_mode mode = codecvt_mode(0))
2847 const uint8_t* frm_nxt = frm;
2848 if (mode & consume_header)
2850 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2851 frm_nxt += 2;
2853 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2855 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2856 if ((c1 & 0xFC00) == 0xDC00)
2857 break;
2858 if ((c1 & 0xFC00) != 0xD800)
2860 if (c1 > Maxcode)
2861 break;
2862 frm_nxt += 2;
2864 else
2866 if (frm_end-frm_nxt < 4)
2867 break;
2868 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2869 if ((c2 & 0xFC00) != 0xDC00)
2870 break;
2871 uint32_t t = static_cast<uint32_t>(
2872 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2873 | ((c1 & 0x003F) << 10)
2874 | (c2 & 0x03FF));
2875 if (t > Maxcode)
2876 break;
2877 frm_nxt += 4;
2880 return static_cast<int>(frm_nxt - frm);
2883 static
2884 codecvt_base::result
2885 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2886 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2887 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2889 frm_nxt = frm;
2890 to_nxt = to;
2891 if (mode & generate_header)
2893 if (to_end-to_nxt < 2)
2894 return codecvt_base::partial;
2895 *to_nxt++ = static_cast<uint8_t>(0xFF);
2896 *to_nxt++ = static_cast<uint8_t>(0xFE);
2898 for (; frm_nxt < frm_end; ++frm_nxt)
2900 uint32_t wc = *frm_nxt;
2901 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2902 return codecvt_base::error;
2903 if (wc < 0x010000)
2905 if (to_end-to_nxt < 2)
2906 return codecvt_base::partial;
2907 *to_nxt++ = static_cast<uint8_t>(wc);
2908 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2910 else
2912 if (to_end-to_nxt < 4)
2913 return codecvt_base::partial;
2914 uint16_t t = static_cast<uint16_t>(
2915 0xD800
2916 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2917 | ((wc & 0x00FC00) >> 10));
2918 *to_nxt++ = static_cast<uint8_t>(t);
2919 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2920 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2921 *to_nxt++ = static_cast<uint8_t>(t);
2922 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2925 return codecvt_base::ok;
2928 static
2929 codecvt_base::result
2930 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2931 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2932 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2934 frm_nxt = frm;
2935 to_nxt = to;
2936 if (mode & consume_header)
2938 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2939 frm_nxt += 2;
2941 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2943 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2944 if ((c1 & 0xFC00) == 0xDC00)
2945 return codecvt_base::error;
2946 if ((c1 & 0xFC00) != 0xD800)
2948 if (c1 > Maxcode)
2949 return codecvt_base::error;
2950 *to_nxt = static_cast<uint32_t>(c1);
2951 frm_nxt += 2;
2953 else
2955 if (frm_end-frm_nxt < 4)
2956 return codecvt_base::partial;
2957 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2958 if ((c2 & 0xFC00) != 0xDC00)
2959 return codecvt_base::error;
2960 uint32_t t = static_cast<uint32_t>(
2961 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2962 | ((c1 & 0x003F) << 10)
2963 | (c2 & 0x03FF));
2964 if (t > Maxcode)
2965 return codecvt_base::error;
2966 *to_nxt = t;
2967 frm_nxt += 4;
2970 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2973 static
2975 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2976 size_t mx, unsigned long Maxcode = 0x10FFFF,
2977 codecvt_mode mode = codecvt_mode(0))
2979 const uint8_t* frm_nxt = frm;
2980 if (mode & consume_header)
2982 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2983 frm_nxt += 2;
2985 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2987 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2988 if ((c1 & 0xFC00) == 0xDC00)
2989 break;
2990 if ((c1 & 0xFC00) != 0xD800)
2992 if (c1 > Maxcode)
2993 break;
2994 frm_nxt += 2;
2996 else
2998 if (frm_end-frm_nxt < 4)
2999 break;
3000 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3001 if ((c2 & 0xFC00) != 0xDC00)
3002 break;
3003 uint32_t t = static_cast<uint32_t>(
3004 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3005 | ((c1 & 0x003F) << 10)
3006 | (c2 & 0x03FF));
3007 if (t > Maxcode)
3008 break;
3009 frm_nxt += 4;
3012 return static_cast<int>(frm_nxt - frm);
3015 static
3016 codecvt_base::result
3017 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3018 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3019 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3021 frm_nxt = frm;
3022 to_nxt = to;
3023 if (mode & generate_header)
3025 if (to_end-to_nxt < 2)
3026 return codecvt_base::partial;
3027 *to_nxt++ = static_cast<uint8_t>(0xFE);
3028 *to_nxt++ = static_cast<uint8_t>(0xFF);
3030 for (; frm_nxt < frm_end; ++frm_nxt)
3032 uint16_t wc = *frm_nxt;
3033 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3034 return codecvt_base::error;
3035 if (to_end-to_nxt < 2)
3036 return codecvt_base::partial;
3037 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3038 *to_nxt++ = static_cast<uint8_t>(wc);
3040 return codecvt_base::ok;
3043 static
3044 codecvt_base::result
3045 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3046 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3047 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3049 frm_nxt = frm;
3050 to_nxt = to;
3051 if (mode & consume_header)
3053 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3054 frm_nxt += 2;
3056 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3058 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3059 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3060 return codecvt_base::error;
3061 *to_nxt = c1;
3062 frm_nxt += 2;
3064 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3067 static
3069 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3070 size_t mx, unsigned long Maxcode = 0x10FFFF,
3071 codecvt_mode mode = codecvt_mode(0))
3073 const uint8_t* frm_nxt = frm;
3074 if (mode & consume_header)
3076 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3077 frm_nxt += 2;
3079 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3081 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3082 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3083 break;
3084 frm_nxt += 2;
3086 return static_cast<int>(frm_nxt - frm);
3089 static
3090 codecvt_base::result
3091 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3092 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3093 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3095 frm_nxt = frm;
3096 to_nxt = to;
3097 if (mode & generate_header)
3099 if (to_end-to_nxt < 2)
3100 return codecvt_base::partial;
3101 *to_nxt++ = static_cast<uint8_t>(0xFF);
3102 *to_nxt++ = static_cast<uint8_t>(0xFE);
3104 for (; frm_nxt < frm_end; ++frm_nxt)
3106 uint16_t wc = *frm_nxt;
3107 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3108 return codecvt_base::error;
3109 if (to_end-to_nxt < 2)
3110 return codecvt_base::partial;
3111 *to_nxt++ = static_cast<uint8_t>(wc);
3112 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3114 return codecvt_base::ok;
3117 static
3118 codecvt_base::result
3119 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3120 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3121 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3123 frm_nxt = frm;
3124 to_nxt = to;
3125 if (mode & consume_header)
3127 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3128 frm_nxt += 2;
3130 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3132 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3133 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3134 return codecvt_base::error;
3135 *to_nxt = c1;
3136 frm_nxt += 2;
3138 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3141 static
3143 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3144 size_t mx, unsigned long Maxcode = 0x10FFFF,
3145 codecvt_mode mode = codecvt_mode(0))
3147 const uint8_t* frm_nxt = frm;
3148 frm_nxt = frm;
3149 if (mode & consume_header)
3151 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3152 frm_nxt += 2;
3154 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3156 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3157 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3158 break;
3159 frm_nxt += 2;
3161 return static_cast<int>(frm_nxt - frm);
3164 // template <> class codecvt<char16_t, char, mbstate_t>
3166 locale::id codecvt<char16_t, char, mbstate_t>::id;
3168 codecvt<char16_t, char, mbstate_t>::~codecvt()
3172 codecvt<char16_t, char, mbstate_t>::result
3173 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3174 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3175 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3177 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3178 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3179 const uint16_t* _frm_nxt = _frm;
3180 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3181 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3182 uint8_t* _to_nxt = _to;
3183 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3184 frm_nxt = frm + (_frm_nxt - _frm);
3185 to_nxt = to + (_to_nxt - _to);
3186 return r;
3189 codecvt<char16_t, char, mbstate_t>::result
3190 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3191 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3192 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3194 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3195 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3196 const uint8_t* _frm_nxt = _frm;
3197 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3198 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3199 uint16_t* _to_nxt = _to;
3200 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3201 frm_nxt = frm + (_frm_nxt - _frm);
3202 to_nxt = to + (_to_nxt - _to);
3203 return r;
3206 codecvt<char16_t, char, mbstate_t>::result
3207 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3208 extern_type* to, extern_type*, extern_type*& to_nxt) const
3210 to_nxt = to;
3211 return noconv;
3215 codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3217 return 0;
3220 bool
3221 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3223 return false;
3227 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3228 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3230 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3231 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3232 return utf8_to_utf16_length(_frm, _frm_end, mx);
3236 codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3238 return 4;
3241 // template <> class codecvt<char32_t, char, mbstate_t>
3243 locale::id codecvt<char32_t, char, mbstate_t>::id;
3245 codecvt<char32_t, char, mbstate_t>::~codecvt()
3249 codecvt<char32_t, char, mbstate_t>::result
3250 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3251 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3252 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3254 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3255 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3256 const uint32_t* _frm_nxt = _frm;
3257 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3258 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3259 uint8_t* _to_nxt = _to;
3260 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3261 frm_nxt = frm + (_frm_nxt - _frm);
3262 to_nxt = to + (_to_nxt - _to);
3263 return r;
3266 codecvt<char32_t, char, mbstate_t>::result
3267 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3268 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3269 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3271 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3272 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3273 const uint8_t* _frm_nxt = _frm;
3274 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3275 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3276 uint32_t* _to_nxt = _to;
3277 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3278 frm_nxt = frm + (_frm_nxt - _frm);
3279 to_nxt = to + (_to_nxt - _to);
3280 return r;
3283 codecvt<char32_t, char, mbstate_t>::result
3284 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3285 extern_type* to, extern_type*, extern_type*& to_nxt) const
3287 to_nxt = to;
3288 return noconv;
3292 codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3294 return 0;
3297 bool
3298 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3300 return false;
3304 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3305 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3307 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3308 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3309 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3313 codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3315 return 4;
3318 // __codecvt_utf8<wchar_t>
3320 __codecvt_utf8<wchar_t>::result
3321 __codecvt_utf8<wchar_t>::do_out(state_type&,
3322 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3323 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3325 #if _WIN32
3326 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3327 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3328 const uint16_t* _frm_nxt = _frm;
3329 #else
3330 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3331 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3332 const uint32_t* _frm_nxt = _frm;
3333 #endif
3334 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3335 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3336 uint8_t* _to_nxt = _to;
3337 #if _WIN32
3338 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3339 _Maxcode_, _Mode_);
3340 #else
3341 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3342 _Maxcode_, _Mode_);
3343 #endif
3344 frm_nxt = frm + (_frm_nxt - _frm);
3345 to_nxt = to + (_to_nxt - _to);
3346 return r;
3349 __codecvt_utf8<wchar_t>::result
3350 __codecvt_utf8<wchar_t>::do_in(state_type&,
3351 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3352 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3354 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3355 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3356 const uint8_t* _frm_nxt = _frm;
3357 #if _WIN32
3358 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3359 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3360 uint16_t* _to_nxt = _to;
3361 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3362 _Maxcode_, _Mode_);
3363 #else
3364 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3365 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3366 uint32_t* _to_nxt = _to;
3367 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3368 _Maxcode_, _Mode_);
3369 #endif
3370 frm_nxt = frm + (_frm_nxt - _frm);
3371 to_nxt = to + (_to_nxt - _to);
3372 return r;
3375 __codecvt_utf8<wchar_t>::result
3376 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3377 extern_type* to, extern_type*, extern_type*& to_nxt) const
3379 to_nxt = to;
3380 return noconv;
3384 __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3386 return 0;
3389 bool
3390 __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3392 return false;
3396 __codecvt_utf8<wchar_t>::do_length(state_type&,
3397 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3399 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3400 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3401 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3405 __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3407 if (_Mode_ & consume_header)
3408 return 7;
3409 return 4;
3412 // __codecvt_utf8<char16_t>
3414 __codecvt_utf8<char16_t>::result
3415 __codecvt_utf8<char16_t>::do_out(state_type&,
3416 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3417 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3419 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3420 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3421 const uint16_t* _frm_nxt = _frm;
3422 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3423 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3424 uint8_t* _to_nxt = _to;
3425 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3426 _Maxcode_, _Mode_);
3427 frm_nxt = frm + (_frm_nxt - _frm);
3428 to_nxt = to + (_to_nxt - _to);
3429 return r;
3432 __codecvt_utf8<char16_t>::result
3433 __codecvt_utf8<char16_t>::do_in(state_type&,
3434 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3435 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3437 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3438 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3439 const uint8_t* _frm_nxt = _frm;
3440 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3441 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3442 uint16_t* _to_nxt = _to;
3443 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3444 _Maxcode_, _Mode_);
3445 frm_nxt = frm + (_frm_nxt - _frm);
3446 to_nxt = to + (_to_nxt - _to);
3447 return r;
3450 __codecvt_utf8<char16_t>::result
3451 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3452 extern_type* to, extern_type*, extern_type*& to_nxt) const
3454 to_nxt = to;
3455 return noconv;
3459 __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3461 return 0;
3464 bool
3465 __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3467 return false;
3471 __codecvt_utf8<char16_t>::do_length(state_type&,
3472 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3474 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3475 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3476 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3480 __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3482 if (_Mode_ & consume_header)
3483 return 6;
3484 return 3;
3487 // __codecvt_utf8<char32_t>
3489 __codecvt_utf8<char32_t>::result
3490 __codecvt_utf8<char32_t>::do_out(state_type&,
3491 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3492 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3494 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3495 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3496 const uint32_t* _frm_nxt = _frm;
3497 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3498 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3499 uint8_t* _to_nxt = _to;
3500 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3501 _Maxcode_, _Mode_);
3502 frm_nxt = frm + (_frm_nxt - _frm);
3503 to_nxt = to + (_to_nxt - _to);
3504 return r;
3507 __codecvt_utf8<char32_t>::result
3508 __codecvt_utf8<char32_t>::do_in(state_type&,
3509 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3510 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3512 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3513 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3514 const uint8_t* _frm_nxt = _frm;
3515 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3516 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3517 uint32_t* _to_nxt = _to;
3518 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3519 _Maxcode_, _Mode_);
3520 frm_nxt = frm + (_frm_nxt - _frm);
3521 to_nxt = to + (_to_nxt - _to);
3522 return r;
3525 __codecvt_utf8<char32_t>::result
3526 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3527 extern_type* to, extern_type*, extern_type*& to_nxt) const
3529 to_nxt = to;
3530 return noconv;
3534 __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3536 return 0;
3539 bool
3540 __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3542 return false;
3546 __codecvt_utf8<char32_t>::do_length(state_type&,
3547 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3549 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3550 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3551 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3555 __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3557 if (_Mode_ & consume_header)
3558 return 7;
3559 return 4;
3562 // __codecvt_utf16<wchar_t, false>
3564 __codecvt_utf16<wchar_t, false>::result
3565 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3566 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3567 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3569 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3570 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3571 const uint32_t* _frm_nxt = _frm;
3572 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3573 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3574 uint8_t* _to_nxt = _to;
3575 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3576 _Maxcode_, _Mode_);
3577 frm_nxt = frm + (_frm_nxt - _frm);
3578 to_nxt = to + (_to_nxt - _to);
3579 return r;
3582 __codecvt_utf16<wchar_t, false>::result
3583 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3584 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3585 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3587 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3588 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3589 const uint8_t* _frm_nxt = _frm;
3590 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3591 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3592 uint32_t* _to_nxt = _to;
3593 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3594 _Maxcode_, _Mode_);
3595 frm_nxt = frm + (_frm_nxt - _frm);
3596 to_nxt = to + (_to_nxt - _to);
3597 return r;
3600 __codecvt_utf16<wchar_t, false>::result
3601 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3602 extern_type* to, extern_type*, extern_type*& to_nxt) const
3604 to_nxt = to;
3605 return noconv;
3609 __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3611 return 0;
3614 bool
3615 __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3617 return false;
3621 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3622 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3624 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3625 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3626 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3630 __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3632 if (_Mode_ & consume_header)
3633 return 6;
3634 return 4;
3637 // __codecvt_utf16<wchar_t, true>
3639 __codecvt_utf16<wchar_t, true>::result
3640 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3641 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3642 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3644 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3645 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3646 const uint32_t* _frm_nxt = _frm;
3647 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3648 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3649 uint8_t* _to_nxt = _to;
3650 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3651 _Maxcode_, _Mode_);
3652 frm_nxt = frm + (_frm_nxt - _frm);
3653 to_nxt = to + (_to_nxt - _to);
3654 return r;
3657 __codecvt_utf16<wchar_t, true>::result
3658 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3659 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3660 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3662 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3663 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3664 const uint8_t* _frm_nxt = _frm;
3665 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3666 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3667 uint32_t* _to_nxt = _to;
3668 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3669 _Maxcode_, _Mode_);
3670 frm_nxt = frm + (_frm_nxt - _frm);
3671 to_nxt = to + (_to_nxt - _to);
3672 return r;
3675 __codecvt_utf16<wchar_t, true>::result
3676 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3677 extern_type* to, extern_type*, extern_type*& to_nxt) const
3679 to_nxt = to;
3680 return noconv;
3684 __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3686 return 0;
3689 bool
3690 __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3692 return false;
3696 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3697 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3699 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3700 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3701 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3705 __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3707 if (_Mode_ & consume_header)
3708 return 6;
3709 return 4;
3712 // __codecvt_utf16<char16_t, false>
3714 __codecvt_utf16<char16_t, false>::result
3715 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3716 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3717 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3719 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3720 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3721 const uint16_t* _frm_nxt = _frm;
3722 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3723 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3724 uint8_t* _to_nxt = _to;
3725 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3726 _Maxcode_, _Mode_);
3727 frm_nxt = frm + (_frm_nxt - _frm);
3728 to_nxt = to + (_to_nxt - _to);
3729 return r;
3732 __codecvt_utf16<char16_t, false>::result
3733 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3734 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3735 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3737 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3738 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3739 const uint8_t* _frm_nxt = _frm;
3740 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3741 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3742 uint16_t* _to_nxt = _to;
3743 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3744 _Maxcode_, _Mode_);
3745 frm_nxt = frm + (_frm_nxt - _frm);
3746 to_nxt = to + (_to_nxt - _to);
3747 return r;
3750 __codecvt_utf16<char16_t, false>::result
3751 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3752 extern_type* to, extern_type*, extern_type*& to_nxt) const
3754 to_nxt = to;
3755 return noconv;
3759 __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3761 return 0;
3764 bool
3765 __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3767 return false;
3771 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3772 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3774 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3775 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3776 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3780 __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3782 if (_Mode_ & consume_header)
3783 return 4;
3784 return 2;
3787 // __codecvt_utf16<char16_t, true>
3789 __codecvt_utf16<char16_t, true>::result
3790 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3791 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3792 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3794 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3795 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3796 const uint16_t* _frm_nxt = _frm;
3797 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3798 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3799 uint8_t* _to_nxt = _to;
3800 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3801 _Maxcode_, _Mode_);
3802 frm_nxt = frm + (_frm_nxt - _frm);
3803 to_nxt = to + (_to_nxt - _to);
3804 return r;
3807 __codecvt_utf16<char16_t, true>::result
3808 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3809 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3810 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3812 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3813 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3814 const uint8_t* _frm_nxt = _frm;
3815 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3816 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3817 uint16_t* _to_nxt = _to;
3818 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3819 _Maxcode_, _Mode_);
3820 frm_nxt = frm + (_frm_nxt - _frm);
3821 to_nxt = to + (_to_nxt - _to);
3822 return r;
3825 __codecvt_utf16<char16_t, true>::result
3826 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3827 extern_type* to, extern_type*, extern_type*& to_nxt) const
3829 to_nxt = to;
3830 return noconv;
3834 __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3836 return 0;
3839 bool
3840 __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3842 return false;
3846 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3847 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3849 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3850 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3851 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3855 __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3857 if (_Mode_ & consume_header)
3858 return 4;
3859 return 2;
3862 // __codecvt_utf16<char32_t, false>
3864 __codecvt_utf16<char32_t, false>::result
3865 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3866 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3867 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3869 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3870 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3871 const uint32_t* _frm_nxt = _frm;
3872 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3873 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3874 uint8_t* _to_nxt = _to;
3875 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3876 _Maxcode_, _Mode_);
3877 frm_nxt = frm + (_frm_nxt - _frm);
3878 to_nxt = to + (_to_nxt - _to);
3879 return r;
3882 __codecvt_utf16<char32_t, false>::result
3883 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3884 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3885 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3887 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3888 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3889 const uint8_t* _frm_nxt = _frm;
3890 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3891 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3892 uint32_t* _to_nxt = _to;
3893 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3894 _Maxcode_, _Mode_);
3895 frm_nxt = frm + (_frm_nxt - _frm);
3896 to_nxt = to + (_to_nxt - _to);
3897 return r;
3900 __codecvt_utf16<char32_t, false>::result
3901 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3902 extern_type* to, extern_type*, extern_type*& to_nxt) const
3904 to_nxt = to;
3905 return noconv;
3909 __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
3911 return 0;
3914 bool
3915 __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
3917 return false;
3921 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3922 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3924 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3925 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3926 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3930 __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
3932 if (_Mode_ & consume_header)
3933 return 6;
3934 return 4;
3937 // __codecvt_utf16<char32_t, true>
3939 __codecvt_utf16<char32_t, true>::result
3940 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3941 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3942 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3944 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3945 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3946 const uint32_t* _frm_nxt = _frm;
3947 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3948 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3949 uint8_t* _to_nxt = _to;
3950 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3951 _Maxcode_, _Mode_);
3952 frm_nxt = frm + (_frm_nxt - _frm);
3953 to_nxt = to + (_to_nxt - _to);
3954 return r;
3957 __codecvt_utf16<char32_t, true>::result
3958 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3959 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3960 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3962 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3963 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3964 const uint8_t* _frm_nxt = _frm;
3965 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3966 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3967 uint32_t* _to_nxt = _to;
3968 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3969 _Maxcode_, _Mode_);
3970 frm_nxt = frm + (_frm_nxt - _frm);
3971 to_nxt = to + (_to_nxt - _to);
3972 return r;
3975 __codecvt_utf16<char32_t, true>::result
3976 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3977 extern_type* to, extern_type*, extern_type*& to_nxt) const
3979 to_nxt = to;
3980 return noconv;
3984 __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
3986 return 0;
3989 bool
3990 __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
3992 return false;
3996 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3997 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3999 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4000 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4001 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4005 __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
4007 if (_Mode_ & consume_header)
4008 return 6;
4009 return 4;
4012 // __codecvt_utf8_utf16<wchar_t>
4014 __codecvt_utf8_utf16<wchar_t>::result
4015 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4016 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4017 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4019 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4020 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4021 const uint32_t* _frm_nxt = _frm;
4022 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4023 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4024 uint8_t* _to_nxt = _to;
4025 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4026 _Maxcode_, _Mode_);
4027 frm_nxt = frm + (_frm_nxt - _frm);
4028 to_nxt = to + (_to_nxt - _to);
4029 return r;
4032 __codecvt_utf8_utf16<wchar_t>::result
4033 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4034 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4035 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4037 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4038 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4039 const uint8_t* _frm_nxt = _frm;
4040 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4041 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4042 uint32_t* _to_nxt = _to;
4043 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4044 _Maxcode_, _Mode_);
4045 frm_nxt = frm + (_frm_nxt - _frm);
4046 to_nxt = to + (_to_nxt - _to);
4047 return r;
4050 __codecvt_utf8_utf16<wchar_t>::result
4051 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4052 extern_type* to, extern_type*, extern_type*& to_nxt) const
4054 to_nxt = to;
4055 return noconv;
4059 __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
4061 return 0;
4064 bool
4065 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
4067 return false;
4071 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4072 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4074 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4075 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4076 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4080 __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
4082 if (_Mode_ & consume_header)
4083 return 7;
4084 return 4;
4087 // __codecvt_utf8_utf16<char16_t>
4089 __codecvt_utf8_utf16<char16_t>::result
4090 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4091 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4092 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4094 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4095 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4096 const uint16_t* _frm_nxt = _frm;
4097 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4098 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4099 uint8_t* _to_nxt = _to;
4100 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4101 _Maxcode_, _Mode_);
4102 frm_nxt = frm + (_frm_nxt - _frm);
4103 to_nxt = to + (_to_nxt - _to);
4104 return r;
4107 __codecvt_utf8_utf16<char16_t>::result
4108 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4109 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4110 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4112 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4113 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4114 const uint8_t* _frm_nxt = _frm;
4115 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4116 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4117 uint16_t* _to_nxt = _to;
4118 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4119 _Maxcode_, _Mode_);
4120 frm_nxt = frm + (_frm_nxt - _frm);
4121 to_nxt = to + (_to_nxt - _to);
4122 return r;
4125 __codecvt_utf8_utf16<char16_t>::result
4126 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4127 extern_type* to, extern_type*, extern_type*& to_nxt) const
4129 to_nxt = to;
4130 return noconv;
4134 __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4136 return 0;
4139 bool
4140 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4142 return false;
4146 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4147 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4149 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4150 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4151 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4155 __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4157 if (_Mode_ & consume_header)
4158 return 7;
4159 return 4;
4162 // __codecvt_utf8_utf16<char32_t>
4164 __codecvt_utf8_utf16<char32_t>::result
4165 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4166 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4167 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4169 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4170 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4171 const uint32_t* _frm_nxt = _frm;
4172 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4173 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4174 uint8_t* _to_nxt = _to;
4175 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4176 _Maxcode_, _Mode_);
4177 frm_nxt = frm + (_frm_nxt - _frm);
4178 to_nxt = to + (_to_nxt - _to);
4179 return r;
4182 __codecvt_utf8_utf16<char32_t>::result
4183 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4184 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4185 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4187 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4188 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4189 const uint8_t* _frm_nxt = _frm;
4190 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4191 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4192 uint32_t* _to_nxt = _to;
4193 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4194 _Maxcode_, _Mode_);
4195 frm_nxt = frm + (_frm_nxt - _frm);
4196 to_nxt = to + (_to_nxt - _to);
4197 return r;
4200 __codecvt_utf8_utf16<char32_t>::result
4201 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4202 extern_type* to, extern_type*, extern_type*& to_nxt) const
4204 to_nxt = to;
4205 return noconv;
4209 __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4211 return 0;
4214 bool
4215 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4217 return false;
4221 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4222 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4224 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4225 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4226 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4230 __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4232 if (_Mode_ & consume_header)
4233 return 7;
4234 return 4;
4237 // __narrow_to_utf8<16>
4239 __narrow_to_utf8<16>::~__narrow_to_utf8()
4243 // __narrow_to_utf8<32>
4245 __narrow_to_utf8<32>::~__narrow_to_utf8()
4249 // __widen_from_utf8<16>
4251 __widen_from_utf8<16>::~__widen_from_utf8()
4255 // __widen_from_utf8<32>
4257 __widen_from_utf8<32>::~__widen_from_utf8()
4261 // numpunct<char> && numpunct<wchar_t>
4263 locale::id numpunct< char >::id;
4264 locale::id numpunct<wchar_t>::id;
4266 numpunct<char>::numpunct(size_t refs)
4267 : locale::facet(refs),
4268 __decimal_point_('.'),
4269 __thousands_sep_(',')
4273 numpunct<wchar_t>::numpunct(size_t refs)
4274 : locale::facet(refs),
4275 __decimal_point_(L'.'),
4276 __thousands_sep_(L',')
4280 numpunct<char>::~numpunct()
4284 numpunct<wchar_t>::~numpunct()
4288 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4289 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4291 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4292 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4294 string numpunct< char >::do_grouping() const {return __grouping_;}
4295 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4297 string numpunct< char >::do_truename() const {return "true";}
4298 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4300 string numpunct< char >::do_falsename() const {return "false";}
4301 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4303 // numpunct_byname<char>
4305 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4306 : numpunct<char>(refs)
4308 __init(nm);
4311 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4312 : numpunct<char>(refs)
4314 __init(nm.c_str());
4317 numpunct_byname<char>::~numpunct_byname()
4321 void
4322 numpunct_byname<char>::__init(const char* nm)
4324 if (strcmp(nm, "C") != 0)
4326 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4327 #ifndef _LIBCPP_NO_EXCEPTIONS
4328 if (loc == nullptr)
4329 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4330 " failed to construct for " + string(nm));
4331 #endif // _LIBCPP_NO_EXCEPTIONS
4332 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4333 lconv* lc = localeconv_l(loc.get());
4334 #else
4335 lconv* lc = __localeconv_l(loc.get());
4336 #endif
4337 if (*lc->decimal_point)
4338 __decimal_point_ = *lc->decimal_point;
4339 if (*lc->thousands_sep)
4340 __thousands_sep_ = *lc->thousands_sep;
4341 __grouping_ = lc->grouping;
4342 // localization for truename and falsename is not available
4346 // numpunct_byname<wchar_t>
4348 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4349 : numpunct<wchar_t>(refs)
4351 __init(nm);
4354 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4355 : numpunct<wchar_t>(refs)
4357 __init(nm.c_str());
4360 numpunct_byname<wchar_t>::~numpunct_byname()
4364 void
4365 numpunct_byname<wchar_t>::__init(const char* nm)
4367 if (strcmp(nm, "C") != 0)
4369 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4370 #ifndef _LIBCPP_NO_EXCEPTIONS
4371 if (loc == nullptr)
4372 throw runtime_error("numpunct_byname<char>::numpunct_byname"
4373 " failed to construct for " + string(nm));
4374 #endif // _LIBCPP_NO_EXCEPTIONS
4375 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4376 lconv* lc = localeconv_l(loc.get());
4377 #else
4378 lconv* lc = __localeconv_l(loc.get());
4379 #endif
4380 if (*lc->decimal_point)
4381 __decimal_point_ = *lc->decimal_point;
4382 if (*lc->thousands_sep)
4383 __thousands_sep_ = *lc->thousands_sep;
4384 __grouping_ = lc->grouping;
4385 // locallization for truename and falsename is not available
4389 // num_get helpers
4392 __num_get_base::__get_base(ios_base& iob)
4394 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4395 if (__basefield == ios_base::oct)
4396 return 8;
4397 else if (__basefield == ios_base::hex)
4398 return 16;
4399 else if (__basefield == 0)
4400 return 0;
4401 return 10;
4404 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4406 void
4407 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4408 ios_base::iostate& __err)
4410 if (__grouping.size() != 0)
4412 reverse(__g, __g_end);
4413 const char* __ig = __grouping.data();
4414 const char* __eg = __ig + __grouping.size();
4415 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4417 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4419 if (static_cast<unsigned>(*__ig) != *__r)
4421 __err = ios_base::failbit;
4422 return;
4425 if (__eg - __ig > 1)
4426 ++__ig;
4428 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4430 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4431 __err = ios_base::failbit;
4436 void
4437 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4438 ios_base::fmtflags __flags)
4440 if (__flags & ios_base::showpos)
4441 *__fmtp++ = '+';
4442 if (__flags & ios_base::showbase)
4443 *__fmtp++ = '#';
4444 while(*__len)
4445 *__fmtp++ = *__len++;
4446 if ((__flags & ios_base::basefield) == ios_base::oct)
4447 *__fmtp = 'o';
4448 else if ((__flags & ios_base::basefield) == ios_base::hex)
4450 if (__flags & ios_base::uppercase)
4451 *__fmtp = 'X';
4452 else
4453 *__fmtp = 'x';
4455 else if (__signd)
4456 *__fmtp = 'd';
4457 else
4458 *__fmtp = 'u';
4461 bool
4462 __num_put_base::__format_float(char* __fmtp, const char* __len,
4463 ios_base::fmtflags __flags)
4465 bool specify_precision = true;
4466 if (__flags & ios_base::showpos)
4467 *__fmtp++ = '+';
4468 if (__flags & ios_base::showpoint)
4469 *__fmtp++ = '#';
4470 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4471 bool uppercase = (__flags & ios_base::uppercase) != 0;
4472 if (floatfield == (ios_base::fixed | ios_base::scientific))
4473 specify_precision = false;
4474 else
4476 *__fmtp++ = '.';
4477 *__fmtp++ = '*';
4479 while(*__len)
4480 *__fmtp++ = *__len++;
4481 if (floatfield == ios_base::fixed)
4483 if (uppercase)
4484 *__fmtp = 'F';
4485 else
4486 *__fmtp = 'f';
4488 else if (floatfield == ios_base::scientific)
4490 if (uppercase)
4491 *__fmtp = 'E';
4492 else
4493 *__fmtp = 'e';
4495 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4497 if (uppercase)
4498 *__fmtp = 'A';
4499 else
4500 *__fmtp = 'a';
4502 else
4504 if (uppercase)
4505 *__fmtp = 'G';
4506 else
4507 *__fmtp = 'g';
4509 return specify_precision;
4512 char*
4513 __num_put_base::__identify_padding(char* __nb, char* __ne,
4514 const ios_base& __iob)
4516 switch (__iob.flags() & ios_base::adjustfield)
4518 case ios_base::internal:
4519 if (__nb[0] == '-' || __nb[0] == '+')
4520 return __nb+1;
4521 if (__ne - __nb >= 2 && __nb[0] == '0'
4522 && (__nb[1] == 'x' || __nb[1] == 'X'))
4523 return __nb+2;
4524 break;
4525 case ios_base::left:
4526 return __ne;
4527 case ios_base::right:
4528 default:
4529 break;
4531 return __nb;
4534 // time_get
4536 static
4537 string*
4538 init_weeks()
4540 static string weeks[14];
4541 weeks[0] = "Sunday";
4542 weeks[1] = "Monday";
4543 weeks[2] = "Tuesday";
4544 weeks[3] = "Wednesday";
4545 weeks[4] = "Thursday";
4546 weeks[5] = "Friday";
4547 weeks[6] = "Saturday";
4548 weeks[7] = "Sun";
4549 weeks[8] = "Mon";
4550 weeks[9] = "Tue";
4551 weeks[10] = "Wed";
4552 weeks[11] = "Thu";
4553 weeks[12] = "Fri";
4554 weeks[13] = "Sat";
4555 return weeks;
4558 static
4559 wstring*
4560 init_wweeks()
4562 static wstring weeks[14];
4563 weeks[0] = L"Sunday";
4564 weeks[1] = L"Monday";
4565 weeks[2] = L"Tuesday";
4566 weeks[3] = L"Wednesday";
4567 weeks[4] = L"Thursday";
4568 weeks[5] = L"Friday";
4569 weeks[6] = L"Saturday";
4570 weeks[7] = L"Sun";
4571 weeks[8] = L"Mon";
4572 weeks[9] = L"Tue";
4573 weeks[10] = L"Wed";
4574 weeks[11] = L"Thu";
4575 weeks[12] = L"Fri";
4576 weeks[13] = L"Sat";
4577 return weeks;
4580 template <>
4581 const string*
4582 __time_get_c_storage<char>::__weeks() const
4584 static const string* weeks = init_weeks();
4585 return weeks;
4588 template <>
4589 const wstring*
4590 __time_get_c_storage<wchar_t>::__weeks() const
4592 static const wstring* weeks = init_wweeks();
4593 return weeks;
4596 static
4597 string*
4598 init_months()
4600 static string months[24];
4601 months[0] = "January";
4602 months[1] = "February";
4603 months[2] = "March";
4604 months[3] = "April";
4605 months[4] = "May";
4606 months[5] = "June";
4607 months[6] = "July";
4608 months[7] = "August";
4609 months[8] = "September";
4610 months[9] = "October";
4611 months[10] = "November";
4612 months[11] = "December";
4613 months[12] = "Jan";
4614 months[13] = "Feb";
4615 months[14] = "Mar";
4616 months[15] = "Apr";
4617 months[16] = "May";
4618 months[17] = "Jun";
4619 months[18] = "Jul";
4620 months[19] = "Aug";
4621 months[20] = "Sep";
4622 months[21] = "Oct";
4623 months[22] = "Nov";
4624 months[23] = "Dec";
4625 return months;
4628 static
4629 wstring*
4630 init_wmonths()
4632 static wstring months[24];
4633 months[0] = L"January";
4634 months[1] = L"February";
4635 months[2] = L"March";
4636 months[3] = L"April";
4637 months[4] = L"May";
4638 months[5] = L"June";
4639 months[6] = L"July";
4640 months[7] = L"August";
4641 months[8] = L"September";
4642 months[9] = L"October";
4643 months[10] = L"November";
4644 months[11] = L"December";
4645 months[12] = L"Jan";
4646 months[13] = L"Feb";
4647 months[14] = L"Mar";
4648 months[15] = L"Apr";
4649 months[16] = L"May";
4650 months[17] = L"Jun";
4651 months[18] = L"Jul";
4652 months[19] = L"Aug";
4653 months[20] = L"Sep";
4654 months[21] = L"Oct";
4655 months[22] = L"Nov";
4656 months[23] = L"Dec";
4657 return months;
4660 template <>
4661 const string*
4662 __time_get_c_storage<char>::__months() const
4664 static const string* months = init_months();
4665 return months;
4668 template <>
4669 const wstring*
4670 __time_get_c_storage<wchar_t>::__months() const
4672 static const wstring* months = init_wmonths();
4673 return months;
4676 static
4677 string*
4678 init_am_pm()
4680 static string am_pm[24];
4681 am_pm[0] = "AM";
4682 am_pm[1] = "PM";
4683 return am_pm;
4686 static
4687 wstring*
4688 init_wam_pm()
4690 static wstring am_pm[24];
4691 am_pm[0] = L"AM";
4692 am_pm[1] = L"PM";
4693 return am_pm;
4696 template <>
4697 const string*
4698 __time_get_c_storage<char>::__am_pm() const
4700 static const string* am_pm = init_am_pm();
4701 return am_pm;
4704 template <>
4705 const wstring*
4706 __time_get_c_storage<wchar_t>::__am_pm() const
4708 static const wstring* am_pm = init_wam_pm();
4709 return am_pm;
4712 template <>
4713 const string&
4714 __time_get_c_storage<char>::__x() const
4716 static string s("%m/%d/%y");
4717 return s;
4720 template <>
4721 const wstring&
4722 __time_get_c_storage<wchar_t>::__x() const
4724 static wstring s(L"%m/%d/%y");
4725 return s;
4728 template <>
4729 const string&
4730 __time_get_c_storage<char>::__X() const
4732 static string s("%H:%M:%S");
4733 return s;
4736 template <>
4737 const wstring&
4738 __time_get_c_storage<wchar_t>::__X() const
4740 static wstring s(L"%H:%M:%S");
4741 return s;
4744 template <>
4745 const string&
4746 __time_get_c_storage<char>::__c() const
4748 static string s("%a %b %d %H:%M:%S %Y");
4749 return s;
4752 template <>
4753 const wstring&
4754 __time_get_c_storage<wchar_t>::__c() const
4756 static wstring s(L"%a %b %d %H:%M:%S %Y");
4757 return s;
4760 template <>
4761 const string&
4762 __time_get_c_storage<char>::__r() const
4764 static string s("%I:%M:%S %p");
4765 return s;
4768 template <>
4769 const wstring&
4770 __time_get_c_storage<wchar_t>::__r() const
4772 static wstring s(L"%I:%M:%S %p");
4773 return s;
4776 // time_get_byname
4778 __time_get::__time_get(const char* nm)
4779 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4781 #ifndef _LIBCPP_NO_EXCEPTIONS
4782 if (__loc_ == 0)
4783 throw runtime_error("time_get_byname"
4784 " failed to construct for " + string(nm));
4785 #endif // _LIBCPP_NO_EXCEPTIONS
4788 __time_get::__time_get(const string& nm)
4789 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4791 #ifndef _LIBCPP_NO_EXCEPTIONS
4792 if (__loc_ == 0)
4793 throw runtime_error("time_get_byname"
4794 " failed to construct for " + nm);
4795 #endif // _LIBCPP_NO_EXCEPTIONS
4798 __time_get::~__time_get()
4800 freelocale(__loc_);
4802 #if defined(__clang__)
4803 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4804 #endif
4805 #if defined(__GNUG__)
4806 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4807 #endif
4809 template <>
4810 string
4811 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4813 tm t = {0};
4814 t.tm_sec = 59;
4815 t.tm_min = 55;
4816 t.tm_hour = 23;
4817 t.tm_mday = 31;
4818 t.tm_mon = 11;
4819 t.tm_year = 161;
4820 t.tm_wday = 6;
4821 t.tm_yday = 364;
4822 t.tm_isdst = -1;
4823 char buf[100];
4824 char f[3] = {0};
4825 f[0] = '%';
4826 f[1] = fmt;
4827 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4828 char* bb = buf;
4829 char* be = buf + n;
4830 string result;
4831 while (bb != be)
4833 if (ct.is(ctype_base::space, *bb))
4835 result.push_back(' ');
4836 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4838 continue;
4840 char* w = bb;
4841 ios_base::iostate err = ios_base::goodbit;
4842 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4843 ct, err, false)
4844 - this->__weeks_;
4845 if (i < 14)
4847 result.push_back('%');
4848 if (i < 7)
4849 result.push_back('A');
4850 else
4851 result.push_back('a');
4852 bb = w;
4853 continue;
4855 w = bb;
4856 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4857 ct, err, false)
4858 - this->__months_;
4859 if (i < 24)
4861 result.push_back('%');
4862 if (i < 12)
4863 result.push_back('B');
4864 else
4865 result.push_back('b');
4866 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4867 result.back() = 'm';
4868 bb = w;
4869 continue;
4871 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4873 w = bb;
4874 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4875 ct, err, false) - this->__am_pm_;
4876 if (i < 2)
4878 result.push_back('%');
4879 result.push_back('p');
4880 bb = w;
4881 continue;
4884 w = bb;
4885 if (ct.is(ctype_base::digit, *bb))
4887 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4889 case 6:
4890 result.push_back('%');
4891 result.push_back('w');
4892 break;
4893 case 7:
4894 result.push_back('%');
4895 result.push_back('u');
4896 break;
4897 case 11:
4898 result.push_back('%');
4899 result.push_back('I');
4900 break;
4901 case 12:
4902 result.push_back('%');
4903 result.push_back('m');
4904 break;
4905 case 23:
4906 result.push_back('%');
4907 result.push_back('H');
4908 break;
4909 case 31:
4910 result.push_back('%');
4911 result.push_back('d');
4912 break;
4913 case 55:
4914 result.push_back('%');
4915 result.push_back('M');
4916 break;
4917 case 59:
4918 result.push_back('%');
4919 result.push_back('S');
4920 break;
4921 case 61:
4922 result.push_back('%');
4923 result.push_back('y');
4924 break;
4925 case 364:
4926 result.push_back('%');
4927 result.push_back('j');
4928 break;
4929 case 2061:
4930 result.push_back('%');
4931 result.push_back('Y');
4932 break;
4933 default:
4934 for (; w != bb; ++w)
4935 result.push_back(*w);
4936 break;
4938 continue;
4940 if (*bb == '%')
4942 result.push_back('%');
4943 result.push_back('%');
4944 ++bb;
4945 continue;
4947 result.push_back(*bb);
4948 ++bb;
4950 return result;
4953 #if defined(__clang__)
4954 #pragma clang diagnostic ignored "-Wmissing-braces"
4955 #endif
4957 template <>
4958 wstring
4959 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4961 tm t = {0};
4962 t.tm_sec = 59;
4963 t.tm_min = 55;
4964 t.tm_hour = 23;
4965 t.tm_mday = 31;
4966 t.tm_mon = 11;
4967 t.tm_year = 161;
4968 t.tm_wday = 6;
4969 t.tm_yday = 364;
4970 t.tm_isdst = -1;
4971 char buf[100];
4972 char f[3] = {0};
4973 f[0] = '%';
4974 f[1] = fmt;
4975 strftime_l(buf, countof(buf), f, &t, __loc_);
4976 wchar_t wbuf[100];
4977 wchar_t* wbb = wbuf;
4978 mbstate_t mb = {0};
4979 const char* bb = buf;
4980 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
4981 size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4982 #else
4983 size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4984 #endif
4985 if (j == size_t(-1))
4986 __throw_runtime_error("locale not supported");
4987 wchar_t* wbe = wbb + j;
4988 wstring result;
4989 while (wbb != wbe)
4991 if (ct.is(ctype_base::space, *wbb))
4993 result.push_back(L' ');
4994 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4996 continue;
4998 wchar_t* w = wbb;
4999 ios_base::iostate err = ios_base::goodbit;
5000 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
5001 ct, err, false)
5002 - this->__weeks_;
5003 if (i < 14)
5005 result.push_back(L'%');
5006 if (i < 7)
5007 result.push_back(L'A');
5008 else
5009 result.push_back(L'a');
5010 wbb = w;
5011 continue;
5013 w = wbb;
5014 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5015 ct, err, false)
5016 - this->__months_;
5017 if (i < 24)
5019 result.push_back(L'%');
5020 if (i < 12)
5021 result.push_back(L'B');
5022 else
5023 result.push_back(L'b');
5024 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5025 result.back() = L'm';
5026 wbb = w;
5027 continue;
5029 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5031 w = wbb;
5032 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5033 ct, err, false) - this->__am_pm_;
5034 if (i < 2)
5036 result.push_back(L'%');
5037 result.push_back(L'p');
5038 wbb = w;
5039 continue;
5042 w = wbb;
5043 if (ct.is(ctype_base::digit, *wbb))
5045 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5047 case 6:
5048 result.push_back(L'%');
5049 result.push_back(L'w');
5050 break;
5051 case 7:
5052 result.push_back(L'%');
5053 result.push_back(L'u');
5054 break;
5055 case 11:
5056 result.push_back(L'%');
5057 result.push_back(L'I');
5058 break;
5059 case 12:
5060 result.push_back(L'%');
5061 result.push_back(L'm');
5062 break;
5063 case 23:
5064 result.push_back(L'%');
5065 result.push_back(L'H');
5066 break;
5067 case 31:
5068 result.push_back(L'%');
5069 result.push_back(L'd');
5070 break;
5071 case 55:
5072 result.push_back(L'%');
5073 result.push_back(L'M');
5074 break;
5075 case 59:
5076 result.push_back(L'%');
5077 result.push_back(L'S');
5078 break;
5079 case 61:
5080 result.push_back(L'%');
5081 result.push_back(L'y');
5082 break;
5083 case 364:
5084 result.push_back(L'%');
5085 result.push_back(L'j');
5086 break;
5087 case 2061:
5088 result.push_back(L'%');
5089 result.push_back(L'Y');
5090 break;
5091 default:
5092 for (; w != wbb; ++w)
5093 result.push_back(*w);
5094 break;
5096 continue;
5098 if (ct.narrow(*wbb, 0) == '%')
5100 result.push_back(L'%');
5101 result.push_back(L'%');
5102 ++wbb;
5103 continue;
5105 result.push_back(*wbb);
5106 ++wbb;
5108 return result;
5111 template <>
5112 void
5113 __time_get_storage<char>::init(const ctype<char>& ct)
5115 tm t = {0};
5116 char buf[100];
5117 // __weeks_
5118 for (int i = 0; i < 7; ++i)
5120 t.tm_wday = i;
5121 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5122 __weeks_[i] = buf;
5123 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5124 __weeks_[i+7] = buf;
5126 // __months_
5127 for (int i = 0; i < 12; ++i)
5129 t.tm_mon = i;
5130 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5131 __months_[i] = buf;
5132 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5133 __months_[i+12] = buf;
5135 // __am_pm_
5136 t.tm_hour = 1;
5137 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5138 __am_pm_[0] = buf;
5139 t.tm_hour = 13;
5140 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5141 __am_pm_[1] = buf;
5142 __c_ = __analyze('c', ct);
5143 __r_ = __analyze('r', ct);
5144 __x_ = __analyze('x', ct);
5145 __X_ = __analyze('X', ct);
5148 template <>
5149 void
5150 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5152 tm t = {0};
5153 char buf[100];
5154 wchar_t wbuf[100];
5155 wchar_t* wbe;
5156 mbstate_t mb = {0};
5157 // __weeks_
5158 for (int i = 0; i < 7; ++i)
5160 t.tm_wday = i;
5161 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5162 mb = mbstate_t();
5163 const char* bb = buf;
5164 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5165 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5166 #else
5167 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5168 #endif
5169 if (j == size_t(-1))
5170 __throw_runtime_error("locale not supported");
5171 wbe = wbuf + j;
5172 __weeks_[i].assign(wbuf, wbe);
5173 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5174 mb = mbstate_t();
5175 bb = buf;
5176 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5177 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5178 #else
5179 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5180 #endif
5181 if (j == size_t(-1))
5182 __throw_runtime_error("locale not supported");
5183 wbe = wbuf + j;
5184 __weeks_[i+7].assign(wbuf, wbe);
5186 // __months_
5187 for (int i = 0; i < 12; ++i)
5189 t.tm_mon = i;
5190 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5191 mb = mbstate_t();
5192 const char* bb = buf;
5193 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5194 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5195 #else
5196 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5197 #endif
5198 if (j == size_t(-1))
5199 __throw_runtime_error("locale not supported");
5200 wbe = wbuf + j;
5201 __months_[i].assign(wbuf, wbe);
5202 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5203 mb = mbstate_t();
5204 bb = buf;
5205 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5206 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5207 #else
5208 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5209 #endif
5210 if (j == size_t(-1))
5211 __throw_runtime_error("locale not supported");
5212 wbe = wbuf + j;
5213 __months_[i+12].assign(wbuf, wbe);
5215 // __am_pm_
5216 t.tm_hour = 1;
5217 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5218 mb = mbstate_t();
5219 const char* bb = buf;
5220 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5221 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5222 #else
5223 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5224 #endif
5225 if (j == size_t(-1))
5226 __throw_runtime_error("locale not supported");
5227 wbe = wbuf + j;
5228 __am_pm_[0].assign(wbuf, wbe);
5229 t.tm_hour = 13;
5230 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5231 mb = mbstate_t();
5232 bb = buf;
5233 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5234 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5235 #else
5236 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5237 #endif
5238 if (j == size_t(-1))
5239 __throw_runtime_error("locale not supported");
5240 wbe = wbuf + j;
5241 __am_pm_[1].assign(wbuf, wbe);
5242 __c_ = __analyze('c', ct);
5243 __r_ = __analyze('r', ct);
5244 __x_ = __analyze('x', ct);
5245 __X_ = __analyze('X', ct);
5248 template <class CharT>
5249 struct _LIBCPP_HIDDEN __time_get_temp
5250 : public ctype_byname<CharT>
5252 explicit __time_get_temp(const char* nm)
5253 : ctype_byname<CharT>(nm, 1) {}
5254 explicit __time_get_temp(const string& nm)
5255 : ctype_byname<CharT>(nm, 1) {}
5258 template <>
5259 __time_get_storage<char>::__time_get_storage(const char* __nm)
5260 : __time_get(__nm)
5262 const __time_get_temp<char> ct(__nm);
5263 init(ct);
5266 template <>
5267 __time_get_storage<char>::__time_get_storage(const string& __nm)
5268 : __time_get(__nm)
5270 const __time_get_temp<char> ct(__nm);
5271 init(ct);
5274 template <>
5275 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5276 : __time_get(__nm)
5278 const __time_get_temp<wchar_t> ct(__nm);
5279 init(ct);
5282 template <>
5283 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5284 : __time_get(__nm)
5286 const __time_get_temp<wchar_t> ct(__nm);
5287 init(ct);
5290 template <>
5291 time_base::dateorder
5292 __time_get_storage<char>::__do_date_order() const
5294 unsigned i;
5295 for (i = 0; i < __x_.size(); ++i)
5296 if (__x_[i] == '%')
5297 break;
5298 ++i;
5299 switch (__x_[i])
5301 case 'y':
5302 case 'Y':
5303 for (++i; i < __x_.size(); ++i)
5304 if (__x_[i] == '%')
5305 break;
5306 if (i == __x_.size())
5307 break;
5308 ++i;
5309 switch (__x_[i])
5311 case 'm':
5312 for (++i; i < __x_.size(); ++i)
5313 if (__x_[i] == '%')
5314 break;
5315 if (i == __x_.size())
5316 break;
5317 ++i;
5318 if (__x_[i] == 'd')
5319 return time_base::ymd;
5320 break;
5321 case 'd':
5322 for (++i; i < __x_.size(); ++i)
5323 if (__x_[i] == '%')
5324 break;
5325 if (i == __x_.size())
5326 break;
5327 ++i;
5328 if (__x_[i] == 'm')
5329 return time_base::ydm;
5330 break;
5332 break;
5333 case 'm':
5334 for (++i; i < __x_.size(); ++i)
5335 if (__x_[i] == '%')
5336 break;
5337 if (i == __x_.size())
5338 break;
5339 ++i;
5340 if (__x_[i] == 'd')
5342 for (++i; i < __x_.size(); ++i)
5343 if (__x_[i] == '%')
5344 break;
5345 if (i == __x_.size())
5346 break;
5347 ++i;
5348 if (__x_[i] == 'y' || __x_[i] == 'Y')
5349 return time_base::mdy;
5350 break;
5352 break;
5353 case 'd':
5354 for (++i; i < __x_.size(); ++i)
5355 if (__x_[i] == '%')
5356 break;
5357 if (i == __x_.size())
5358 break;
5359 ++i;
5360 if (__x_[i] == 'm')
5362 for (++i; i < __x_.size(); ++i)
5363 if (__x_[i] == '%')
5364 break;
5365 if (i == __x_.size())
5366 break;
5367 ++i;
5368 if (__x_[i] == 'y' || __x_[i] == 'Y')
5369 return time_base::dmy;
5370 break;
5372 break;
5374 return time_base::no_order;
5377 template <>
5378 time_base::dateorder
5379 __time_get_storage<wchar_t>::__do_date_order() const
5381 unsigned i;
5382 for (i = 0; i < __x_.size(); ++i)
5383 if (__x_[i] == L'%')
5384 break;
5385 ++i;
5386 switch (__x_[i])
5388 case L'y':
5389 case L'Y':
5390 for (++i; i < __x_.size(); ++i)
5391 if (__x_[i] == L'%')
5392 break;
5393 if (i == __x_.size())
5394 break;
5395 ++i;
5396 switch (__x_[i])
5398 case L'm':
5399 for (++i; i < __x_.size(); ++i)
5400 if (__x_[i] == L'%')
5401 break;
5402 if (i == __x_.size())
5403 break;
5404 ++i;
5405 if (__x_[i] == L'd')
5406 return time_base::ymd;
5407 break;
5408 case L'd':
5409 for (++i; i < __x_.size(); ++i)
5410 if (__x_[i] == L'%')
5411 break;
5412 if (i == __x_.size())
5413 break;
5414 ++i;
5415 if (__x_[i] == L'm')
5416 return time_base::ydm;
5417 break;
5419 break;
5420 case L'm':
5421 for (++i; i < __x_.size(); ++i)
5422 if (__x_[i] == L'%')
5423 break;
5424 if (i == __x_.size())
5425 break;
5426 ++i;
5427 if (__x_[i] == L'd')
5429 for (++i; i < __x_.size(); ++i)
5430 if (__x_[i] == L'%')
5431 break;
5432 if (i == __x_.size())
5433 break;
5434 ++i;
5435 if (__x_[i] == L'y' || __x_[i] == L'Y')
5436 return time_base::mdy;
5437 break;
5439 break;
5440 case L'd':
5441 for (++i; i < __x_.size(); ++i)
5442 if (__x_[i] == L'%')
5443 break;
5444 if (i == __x_.size())
5445 break;
5446 ++i;
5447 if (__x_[i] == L'm')
5449 for (++i; i < __x_.size(); ++i)
5450 if (__x_[i] == L'%')
5451 break;
5452 if (i == __x_.size())
5453 break;
5454 ++i;
5455 if (__x_[i] == L'y' || __x_[i] == L'Y')
5456 return time_base::dmy;
5457 break;
5459 break;
5461 return time_base::no_order;
5464 // time_put
5466 __time_put::__time_put(const char* nm)
5467 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5469 #ifndef _LIBCPP_NO_EXCEPTIONS
5470 if (__loc_ == 0)
5471 throw runtime_error("time_put_byname"
5472 " failed to construct for " + string(nm));
5473 #endif // _LIBCPP_NO_EXCEPTIONS
5476 __time_put::__time_put(const string& nm)
5477 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5479 #ifndef _LIBCPP_NO_EXCEPTIONS
5480 if (__loc_ == 0)
5481 throw runtime_error("time_put_byname"
5482 " failed to construct for " + nm);
5483 #endif // _LIBCPP_NO_EXCEPTIONS
5486 __time_put::~__time_put()
5488 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5489 freelocale(__loc_);
5492 void
5493 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5494 char __fmt, char __mod) const
5496 char fmt[] = {'%', __fmt, __mod, 0};
5497 if (__mod != 0)
5498 swap(fmt[1], fmt[2]);
5499 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5500 __ne = __nb + n;
5503 void
5504 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5505 char __fmt, char __mod) const
5507 char __nar[100];
5508 char* __ne = __nar + 100;
5509 __do_put(__nar, __ne, __tm, __fmt, __mod);
5510 mbstate_t mb = {0};
5511 const char* __nb = __nar;
5512 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5513 size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5514 #else
5515 size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5516 #endif
5517 if (j == size_t(-1))
5518 __throw_runtime_error("locale not supported");
5519 __we = __wb + j;
5522 // moneypunct_byname
5524 template <class charT>
5525 static
5526 void
5527 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5528 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5529 charT space_char)
5531 const char sign = static_cast<char>(money_base::sign);
5532 const char space = static_cast<char>(money_base::space);
5533 const char none = static_cast<char>(money_base::none);
5534 const char symbol = static_cast<char>(money_base::symbol);
5535 const char value = static_cast<char>(money_base::value);
5536 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5538 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5539 // function'. "Space between sign and symbol or value" means that
5540 // if the sign is adjacent to the symbol, there's a space between
5541 // them, and otherwise there's a space between the sign and value.
5543 // C11's localeconv specifies that the fourth character of an
5544 // international curr_symbol is used to separate the sign and
5545 // value when sep_by_space says to do so. C++ can't represent
5546 // that, so we just use a space. When sep_by_space says to
5547 // separate the symbol and value-or-sign with a space, we rearrange the
5548 // curr_symbol to put its spacing character on the correct side of
5549 // the symbol.
5551 // We also need to avoid adding an extra space between the sign
5552 // and value when the currency symbol is suppressed (by not
5553 // setting showbase). We match glibc's strfmon by interpreting
5554 // sep_by_space==1 as "omit the space when the currency symbol is
5555 // absent".
5557 // Users who want to get this right should use ICU instead.
5559 switch (cs_precedes)
5561 case 0: // value before curr_symbol
5562 if (symbol_contains_sep) {
5563 // Move the separator to before the symbol, to place it
5564 // between the value and symbol.
5565 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5566 __curr_symbol_.end());
5568 switch (sign_posn)
5570 case 0: // Parentheses surround the quantity and currency symbol.
5571 pat.field[0] = sign;
5572 pat.field[1] = value;
5573 pat.field[2] = none; // Any space appears in the symbol.
5574 pat.field[3] = symbol;
5575 switch (sep_by_space)
5577 case 0: // No space separates the currency symbol and value.
5578 // This case may have changed between C99 and C11;
5579 // assume the currency symbol matches the intention.
5580 case 2: // Space between sign and currency or value.
5581 // The "sign" is two parentheses, so no space here either.
5582 return;
5583 case 1: // Space between currency-and-sign or currency and value.
5584 if (!symbol_contains_sep) {
5585 // We insert the space into the symbol instead of
5586 // setting pat.field[2]=space so that when
5587 // showbase is not set, the space goes away too.
5588 __curr_symbol_.insert(0, 1, space_char);
5590 return;
5591 default:
5592 break;
5594 break;
5595 case 1: // The sign string precedes the quantity and currency symbol.
5596 pat.field[0] = sign;
5597 pat.field[3] = symbol;
5598 switch (sep_by_space)
5600 case 0: // No space separates the currency symbol and value.
5601 pat.field[1] = value;
5602 pat.field[2] = none;
5603 return;
5604 case 1: // Space between currency-and-sign or currency and value.
5605 pat.field[1] = value;
5606 pat.field[2] = none;
5607 if (!symbol_contains_sep) {
5608 // We insert the space into the symbol instead of
5609 // setting pat.field[2]=space so that when
5610 // showbase is not set, the space goes away too.
5611 __curr_symbol_.insert(0, 1, space_char);
5613 return;
5614 case 2: // Space between sign and currency or value.
5615 pat.field[1] = space;
5616 pat.field[2] = value;
5617 if (symbol_contains_sep) {
5618 // Remove the separator from the symbol, since it
5619 // has already appeared after the sign.
5620 __curr_symbol_.erase(__curr_symbol_.begin());
5622 return;
5623 default:
5624 break;
5626 break;
5627 case 2: // The sign string succeeds the quantity and currency symbol.
5628 pat.field[0] = value;
5629 pat.field[3] = sign;
5630 switch (sep_by_space)
5632 case 0: // No space separates the currency symbol and value.
5633 pat.field[1] = none;
5634 pat.field[2] = symbol;
5635 return;
5636 case 1: // Space between currency-and-sign or currency and value.
5637 if (!symbol_contains_sep) {
5638 // We insert the space into the symbol instead of
5639 // setting pat.field[1]=space so that when
5640 // showbase is not set, the space goes away too.
5641 __curr_symbol_.insert(0, 1, space_char);
5643 pat.field[1] = none;
5644 pat.field[2] = symbol;
5645 return;
5646 case 2: // Space between sign and currency or value.
5647 pat.field[1] = symbol;
5648 pat.field[2] = space;
5649 if (symbol_contains_sep) {
5650 // Remove the separator from the symbol, since it
5651 // should not be removed if showbase is absent.
5652 __curr_symbol_.erase(__curr_symbol_.begin());
5654 return;
5655 default:
5656 break;
5658 break;
5659 case 3: // The sign string immediately precedes the currency symbol.
5660 pat.field[0] = value;
5661 pat.field[3] = symbol;
5662 switch (sep_by_space)
5664 case 0: // No space separates the currency symbol and value.
5665 pat.field[1] = none;
5666 pat.field[2] = sign;
5667 return;
5668 case 1: // Space between currency-and-sign or currency and value.
5669 pat.field[1] = space;
5670 pat.field[2] = sign;
5671 if (symbol_contains_sep) {
5672 // Remove the separator from the symbol, since it
5673 // has already appeared before the sign.
5674 __curr_symbol_.erase(__curr_symbol_.begin());
5676 return;
5677 case 2: // Space between sign and currency or value.
5678 pat.field[1] = sign;
5679 pat.field[2] = none;
5680 if (!symbol_contains_sep) {
5681 // We insert the space into the symbol instead of
5682 // setting pat.field[2]=space so that when
5683 // showbase is not set, the space goes away too.
5684 __curr_symbol_.insert(0, 1, space_char);
5686 return;
5687 default:
5688 break;
5690 break;
5691 case 4: // The sign string immediately succeeds the currency symbol.
5692 pat.field[0] = value;
5693 pat.field[3] = sign;
5694 switch (sep_by_space)
5696 case 0: // No space separates the currency symbol and value.
5697 pat.field[1] = none;
5698 pat.field[2] = symbol;
5699 return;
5700 case 1: // Space between currency-and-sign or currency and value.
5701 pat.field[1] = none;
5702 pat.field[2] = symbol;
5703 if (!symbol_contains_sep) {
5704 // We insert the space into the symbol instead of
5705 // setting pat.field[1]=space so that when
5706 // showbase is not set, the space goes away too.
5707 __curr_symbol_.insert(0, 1, space_char);
5709 return;
5710 case 2: // Space between sign and currency or value.
5711 pat.field[1] = symbol;
5712 pat.field[2] = space;
5713 if (symbol_contains_sep) {
5714 // Remove the separator from the symbol, since it
5715 // should not disappear when showbase is absent.
5716 __curr_symbol_.erase(__curr_symbol_.begin());
5718 return;
5719 default:
5720 break;
5722 break;
5723 default:
5724 break;
5726 break;
5727 case 1: // curr_symbol before value
5728 switch (sign_posn)
5730 case 0: // Parentheses surround the quantity and currency symbol.
5731 pat.field[0] = sign;
5732 pat.field[1] = symbol;
5733 pat.field[2] = none; // Any space appears in the symbol.
5734 pat.field[3] = value;
5735 switch (sep_by_space)
5737 case 0: // No space separates the currency symbol and value.
5738 // This case may have changed between C99 and C11;
5739 // assume the currency symbol matches the intention.
5740 case 2: // Space between sign and currency or value.
5741 // The "sign" is two parentheses, so no space here either.
5742 return;
5743 case 1: // Space between currency-and-sign or currency and value.
5744 if (!symbol_contains_sep) {
5745 // We insert the space into the symbol instead of
5746 // setting pat.field[2]=space so that when
5747 // showbase is not set, the space goes away too.
5748 __curr_symbol_.insert(0, 1, space_char);
5750 return;
5751 default:
5752 break;
5754 break;
5755 case 1: // The sign string precedes the quantity and currency symbol.
5756 pat.field[0] = sign;
5757 pat.field[3] = value;
5758 switch (sep_by_space)
5760 case 0: // No space separates the currency symbol and value.
5761 pat.field[1] = symbol;
5762 pat.field[2] = none;
5763 return;
5764 case 1: // Space between currency-and-sign or currency and value.
5765 pat.field[1] = symbol;
5766 pat.field[2] = none;
5767 if (!symbol_contains_sep) {
5768 // We insert the space into the symbol instead of
5769 // setting pat.field[2]=space so that when
5770 // showbase is not set, the space goes away too.
5771 __curr_symbol_.push_back(space_char);
5773 return;
5774 case 2: // Space between sign and currency or value.
5775 pat.field[1] = space;
5776 pat.field[2] = symbol;
5777 if (symbol_contains_sep) {
5778 // Remove the separator from the symbol, since it
5779 // has already appeared after the sign.
5780 __curr_symbol_.pop_back();
5782 return;
5783 default:
5784 break;
5786 break;
5787 case 2: // The sign string succeeds the quantity and currency symbol.
5788 pat.field[0] = symbol;
5789 pat.field[3] = sign;
5790 switch (sep_by_space)
5792 case 0: // No space separates the currency symbol and value.
5793 pat.field[1] = none;
5794 pat.field[2] = value;
5795 return;
5796 case 1: // Space between currency-and-sign or currency and value.
5797 pat.field[1] = none;
5798 pat.field[2] = value;
5799 if (!symbol_contains_sep) {
5800 // We insert the space into the symbol instead of
5801 // setting pat.field[1]=space so that when
5802 // showbase is not set, the space goes away too.
5803 __curr_symbol_.push_back(space_char);
5805 return;
5806 case 2: // Space between sign and currency or value.
5807 pat.field[1] = value;
5808 pat.field[2] = space;
5809 if (symbol_contains_sep) {
5810 // Remove the separator from the symbol, since it
5811 // will appear before the sign.
5812 __curr_symbol_.pop_back();
5814 return;
5815 default:
5816 break;
5818 break;
5819 case 3: // The sign string immediately precedes the currency symbol.
5820 pat.field[0] = sign;
5821 pat.field[3] = value;
5822 switch (sep_by_space)
5824 case 0: // No space separates the currency symbol and value.
5825 pat.field[1] = symbol;
5826 pat.field[2] = none;
5827 return;
5828 case 1: // Space between currency-and-sign or currency and value.
5829 pat.field[1] = symbol;
5830 pat.field[2] = none;
5831 if (!symbol_contains_sep) {
5832 // We insert the space into the symbol instead of
5833 // setting pat.field[2]=space so that when
5834 // showbase is not set, the space goes away too.
5835 __curr_symbol_.push_back(space_char);
5837 return;
5838 case 2: // Space between sign and currency or value.
5839 pat.field[1] = space;
5840 pat.field[2] = symbol;
5841 if (symbol_contains_sep) {
5842 // Remove the separator from the symbol, since it
5843 // has already appeared after the sign.
5844 __curr_symbol_.pop_back();
5846 return;
5847 default:
5848 break;
5850 break;
5851 case 4: // The sign string immediately succeeds the currency symbol.
5852 pat.field[0] = symbol;
5853 pat.field[3] = value;
5854 switch (sep_by_space)
5856 case 0: // No space separates the currency symbol and value.
5857 pat.field[1] = sign;
5858 pat.field[2] = none;
5859 return;
5860 case 1: // Space between currency-and-sign or currency and value.
5861 pat.field[1] = sign;
5862 pat.field[2] = space;
5863 if (symbol_contains_sep) {
5864 // Remove the separator from the symbol, since it
5865 // should not disappear when showbase is absent.
5866 __curr_symbol_.pop_back();
5868 return;
5869 case 2: // Space between sign and currency or value.
5870 pat.field[1] = none;
5871 pat.field[2] = sign;
5872 if (!symbol_contains_sep) {
5873 // We insert the space into the symbol instead of
5874 // setting pat.field[1]=space so that when
5875 // showbase is not set, the space goes away too.
5876 __curr_symbol_.push_back(space_char);
5878 return;
5879 default:
5880 break;
5882 break;
5883 default:
5884 break;
5886 break;
5887 default:
5888 break;
5890 pat.field[0] = symbol;
5891 pat.field[1] = sign;
5892 pat.field[2] = none;
5893 pat.field[3] = value;
5896 template<>
5897 void
5898 moneypunct_byname<char, false>::init(const char* nm)
5900 typedef moneypunct<char, false> base;
5901 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5902 #ifndef _LIBCPP_NO_EXCEPTIONS
5903 if (loc == nullptr)
5904 throw runtime_error("moneypunct_byname"
5905 " failed to construct for " + string(nm));
5906 #endif // _LIBCPP_NO_EXCEPTIONS
5907 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5908 lconv* lc = localeconv_l(loc.get());
5909 #else
5910 lconv* lc = __localeconv_l(loc.get());
5911 #endif
5912 if (*lc->mon_decimal_point)
5913 __decimal_point_ = *lc->mon_decimal_point;
5914 else
5915 __decimal_point_ = base::do_decimal_point();
5916 if (*lc->mon_thousands_sep)
5917 __thousands_sep_ = *lc->mon_thousands_sep;
5918 else
5919 __thousands_sep_ = base::do_thousands_sep();
5920 __grouping_ = lc->mon_grouping;
5921 __curr_symbol_ = lc->currency_symbol;
5922 if (lc->frac_digits != CHAR_MAX)
5923 __frac_digits_ = lc->frac_digits;
5924 else
5925 __frac_digits_ = base::do_frac_digits();
5926 if (lc->p_sign_posn == 0)
5927 __positive_sign_ = "()";
5928 else
5929 __positive_sign_ = lc->positive_sign;
5930 if (lc->n_sign_posn == 0)
5931 __negative_sign_ = "()";
5932 else
5933 __negative_sign_ = lc->negative_sign;
5934 // Assume the positive and negative formats will want spaces in
5935 // the same places in curr_symbol since there's no way to
5936 // represent anything else.
5937 string_type __dummy_curr_symbol = __curr_symbol_;
5938 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5939 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5940 __init_pat(__neg_format_, __curr_symbol_, false,
5941 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5944 template<>
5945 void
5946 moneypunct_byname<char, true>::init(const char* nm)
5948 typedef moneypunct<char, true> base;
5949 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5950 #ifndef _LIBCPP_NO_EXCEPTIONS
5951 if (loc == nullptr)
5952 throw runtime_error("moneypunct_byname"
5953 " failed to construct for " + string(nm));
5954 #endif // _LIBCPP_NO_EXCEPTIONS
5955 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
5956 lconv* lc = localeconv_l(loc.get());
5957 #else
5958 lconv* lc = __localeconv_l(loc.get());
5959 #endif
5960 if (*lc->mon_decimal_point)
5961 __decimal_point_ = *lc->mon_decimal_point;
5962 else
5963 __decimal_point_ = base::do_decimal_point();
5964 if (*lc->mon_thousands_sep)
5965 __thousands_sep_ = *lc->mon_thousands_sep;
5966 else
5967 __thousands_sep_ = base::do_thousands_sep();
5968 __grouping_ = lc->mon_grouping;
5969 __curr_symbol_ = lc->int_curr_symbol;
5970 if (lc->int_frac_digits != CHAR_MAX)
5971 __frac_digits_ = lc->int_frac_digits;
5972 else
5973 __frac_digits_ = base::do_frac_digits();
5974 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5975 if (lc->p_sign_posn == 0)
5976 #else // _LIBCPP_MSVCRT
5977 if (lc->int_p_sign_posn == 0)
5978 #endif // !_LIBCPP_MSVCRT
5979 __positive_sign_ = "()";
5980 else
5981 __positive_sign_ = lc->positive_sign;
5982 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5983 if(lc->n_sign_posn == 0)
5984 #else // _LIBCPP_MSVCRT
5985 if (lc->int_n_sign_posn == 0)
5986 #endif // !_LIBCPP_MSVCRT
5987 __negative_sign_ = "()";
5988 else
5989 __negative_sign_ = lc->negative_sign;
5990 // Assume the positive and negative formats will want spaces in
5991 // the same places in curr_symbol since there's no way to
5992 // represent anything else.
5993 string_type __dummy_curr_symbol = __curr_symbol_;
5994 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5995 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5996 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5997 __init_pat(__neg_format_, __curr_symbol_, true,
5998 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5999 #else // _LIBCPP_MSVCRT
6000 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6001 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6002 lc->int_p_sign_posn, ' ');
6003 __init_pat(__neg_format_, __curr_symbol_, true,
6004 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6005 lc->int_n_sign_posn, ' ');
6006 #endif // !_LIBCPP_MSVCRT
6009 template<>
6010 void
6011 moneypunct_byname<wchar_t, false>::init(const char* nm)
6013 typedef moneypunct<wchar_t, false> base;
6014 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
6015 #ifndef _LIBCPP_NO_EXCEPTIONS
6016 if (loc == nullptr)
6017 throw runtime_error("moneypunct_byname"
6018 " failed to construct for " + string(nm));
6019 #endif // _LIBCPP_NO_EXCEPTIONS
6020 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6021 lconv* lc = localeconv_l(loc.get());
6022 #else
6023 lconv* lc = __localeconv_l(loc.get());
6024 #endif
6025 if (*lc->mon_decimal_point)
6026 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
6027 else
6028 __decimal_point_ = base::do_decimal_point();
6029 if (*lc->mon_thousands_sep)
6030 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
6031 else
6032 __thousands_sep_ = base::do_thousands_sep();
6033 __grouping_ = lc->mon_grouping;
6034 wchar_t wbuf[100];
6035 mbstate_t mb = {0};
6036 const char* bb = lc->currency_symbol;
6037 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6038 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6039 #else
6040 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6041 #endif
6042 if (j == size_t(-1))
6043 __throw_runtime_error("locale not supported");
6044 wchar_t* wbe = wbuf + j;
6045 __curr_symbol_.assign(wbuf, wbe);
6046 if (lc->frac_digits != CHAR_MAX)
6047 __frac_digits_ = lc->frac_digits;
6048 else
6049 __frac_digits_ = base::do_frac_digits();
6050 if (lc->p_sign_posn == 0)
6051 __positive_sign_ = L"()";
6052 else
6054 mb = mbstate_t();
6055 bb = lc->positive_sign;
6056 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6057 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6058 #else
6059 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6060 #endif
6061 if (j == size_t(-1))
6062 __throw_runtime_error("locale not supported");
6063 wbe = wbuf + j;
6064 __positive_sign_.assign(wbuf, wbe);
6066 if (lc->n_sign_posn == 0)
6067 __negative_sign_ = L"()";
6068 else
6070 mb = mbstate_t();
6071 bb = lc->negative_sign;
6072 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6073 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6074 #else
6075 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6076 #endif
6077 if (j == size_t(-1))
6078 __throw_runtime_error("locale not supported");
6079 wbe = wbuf + j;
6080 __negative_sign_.assign(wbuf, wbe);
6082 // Assume the positive and negative formats will want spaces in
6083 // the same places in curr_symbol since there's no way to
6084 // represent anything else.
6085 string_type __dummy_curr_symbol = __curr_symbol_;
6086 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6087 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6088 __init_pat(__neg_format_, __curr_symbol_, false,
6089 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6092 template<>
6093 void
6094 moneypunct_byname<wchar_t, true>::init(const char* nm)
6096 typedef moneypunct<wchar_t, true> base;
6097 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
6098 #ifndef _LIBCPP_NO_EXCEPTIONS
6099 if (loc == nullptr)
6100 throw runtime_error("moneypunct_byname"
6101 " failed to construct for " + string(nm));
6102 #endif // _LIBCPP_NO_EXCEPTIONS
6103 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6104 lconv* lc = localeconv_l(loc.get());
6105 #else
6106 lconv* lc = __localeconv_l(loc.get());
6107 #endif
6108 if (*lc->mon_decimal_point)
6109 __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
6110 else
6111 __decimal_point_ = base::do_decimal_point();
6112 if (*lc->mon_thousands_sep)
6113 __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
6114 else
6115 __thousands_sep_ = base::do_thousands_sep();
6116 __grouping_ = lc->mon_grouping;
6117 wchar_t wbuf[100];
6118 mbstate_t mb = {0};
6119 const char* bb = lc->int_curr_symbol;
6120 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6121 size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6122 #else
6123 size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6124 #endif
6125 if (j == size_t(-1))
6126 __throw_runtime_error("locale not supported");
6127 wchar_t* wbe = wbuf + j;
6128 __curr_symbol_.assign(wbuf, wbe);
6129 if (lc->int_frac_digits != CHAR_MAX)
6130 __frac_digits_ = lc->int_frac_digits;
6131 else
6132 __frac_digits_ = base::do_frac_digits();
6133 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6134 if (lc->p_sign_posn == 0)
6135 #else // _LIBCPP_MSVCRT
6136 if (lc->int_p_sign_posn == 0)
6137 #endif // !_LIBCPP_MSVCRT
6138 __positive_sign_ = L"()";
6139 else
6141 mb = mbstate_t();
6142 bb = lc->positive_sign;
6143 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6144 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6145 #else
6146 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6147 #endif
6148 if (j == size_t(-1))
6149 __throw_runtime_error("locale not supported");
6150 wbe = wbuf + j;
6151 __positive_sign_.assign(wbuf, wbe);
6153 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6154 if (lc->n_sign_posn == 0)
6155 #else // _LIBCPP_MSVCRT
6156 if (lc->int_n_sign_posn == 0)
6157 #endif // !_LIBCPP_MSVCRT
6158 __negative_sign_ = L"()";
6159 else
6161 mb = mbstate_t();
6162 bb = lc->negative_sign;
6163 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
6164 j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6165 #else
6166 j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6167 #endif
6168 if (j == size_t(-1))
6169 __throw_runtime_error("locale not supported");
6170 wbe = wbuf + j;
6171 __negative_sign_.assign(wbuf, wbe);
6173 // Assume the positive and negative formats will want spaces in
6174 // the same places in curr_symbol since there's no way to
6175 // represent anything else.
6176 string_type __dummy_curr_symbol = __curr_symbol_;
6177 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6178 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6179 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6180 __init_pat(__neg_format_, __curr_symbol_, true,
6181 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6182 #else // _LIBCPP_MSVCRT
6183 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6184 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6185 lc->int_p_sign_posn, L' ');
6186 __init_pat(__neg_format_, __curr_symbol_, true,
6187 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6188 lc->int_n_sign_posn, L' ');
6189 #endif // !_LIBCPP_MSVCRT
6192 void __do_nothing(void*) {}
6194 void __throw_runtime_error(const char* msg)
6196 #ifndef _LIBCPP_NO_EXCEPTIONS
6197 throw runtime_error(msg);
6198 #else
6199 (void)msg;
6200 #endif
6203 template class collate<char>;
6204 template class collate<wchar_t>;
6206 template class num_get<char>;
6207 template class num_get<wchar_t>;
6209 template struct __num_get<char>;
6210 template struct __num_get<wchar_t>;
6212 template class num_put<char>;
6213 template class num_put<wchar_t>;
6215 template struct __num_put<char>;
6216 template struct __num_put<wchar_t>;
6218 template class time_get<char>;
6219 template class time_get<wchar_t>;
6221 template class time_get_byname<char>;
6222 template class time_get_byname<wchar_t>;
6224 template class time_put<char>;
6225 template class time_put<wchar_t>;
6227 template class time_put_byname<char>;
6228 template class time_put_byname<wchar_t>;
6230 template class moneypunct<char, false>;
6231 template class moneypunct<char, true>;
6232 template class moneypunct<wchar_t, false>;
6233 template class moneypunct<wchar_t, true>;
6235 template class moneypunct_byname<char, false>;
6236 template class moneypunct_byname<char, true>;
6237 template class moneypunct_byname<wchar_t, false>;
6238 template class moneypunct_byname<wchar_t, true>;
6240 template class money_get<char>;
6241 template class money_get<wchar_t>;
6243 template class __money_get<char>;
6244 template class __money_get<wchar_t>;
6246 template class money_put<char>;
6247 template class money_put<wchar_t>;
6249 template class __money_put<char>;
6250 template class __money_put<wchar_t>;
6252 template class messages<char>;
6253 template class messages<wchar_t>;
6255 template class messages_byname<char>;
6256 template class messages_byname<wchar_t>;
6258 template class codecvt_byname<char, char, mbstate_t>;
6259 template class codecvt_byname<wchar_t, char, mbstate_t>;
6260 template class codecvt_byname<char16_t, char, mbstate_t>;
6261 template class codecvt_byname<char32_t, char, mbstate_t>;
6263 template class __vector_base_common<true>;
6265 _LIBCPP_END_NAMESPACE_STD